PageSourceSearch

https://msdm.ru/bitrix/cache/js/s1/msdm/template_bafcbf236af6c0437…c0437bbd990244012f95_v1.js?1790751995984423

js msdm.ru collected 2026-10-02 05:19:25 UTC 984,423 bytes, 24,596 lines download raw bytes

1
2; /* Start:"a:4:{s:4:"full";s:62:"/local/templates/msdm/assets/main-DLCqwHNN.js?1790751964964957";s:6:"source";s:45:"/local/templates/msdm/assets/main-DLCqwHNN.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
3true && (function polyfill() {
4    const relList = document.createElement("link").relList;
5    if (relList && relList.supports && relList.supports("modulepreload")) return;
6    for (const link of document.querySelectorAll("link[rel=\"modulepreload\"]")) processPreload(link);
7    new MutationObserver((mutations) => {
8        for (const mutation of mutations) {
9            if (mutation.type !== "childList") continue;
10            for (const node of mutation.addedNodes) if (node.tagName === "LINK" && node.rel === "modulepreload") processPreload(node);
11        }
12    }).observe(document, {
13        childList: true,
14        subtree: true
15    });
16
17    function getFetchOpts(link) {
18        const fetchOpts = {};
19        if (link.integrity) fetchOpts.integrity = link.integrity;
20        if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy;
21        if (link.crossOrigin === "use-credentials") fetchOpts.credentials = "include";
22        else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit";
23        else fetchOpts.credentials = "same-origin";
24        return fetchOpts;
25    }
26
27    function processPreload(link) {
28        if (link.ep) return;
29        link.ep = true;
30        const fetchOpts = getFetchOpts(link);
31        fetch(link.href, fetchOpts);
32    }
33}());
34
35function getDefaultExportFromCjs(x) {
36    return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
37}
38
39var jquery$1 = {exports: {}};
40
41/*!
42 * jQuery JavaScript Library v3.7.1
43 * https://jquery.com/
44 *
45 * Copyright OpenJS Foundation and other contributors
46 * Released under the MIT license
47 * https://jquery.org/license
48 *
49 * Date: 2023-08-28T13:37Z
50 */
51var jquery = jquery$1.exports;
52
53var hasRequiredJquery;
54
55function requireJquery() {
56    if (hasRequiredJquery) return jquery$1.exports;
57    hasRequiredJquery = 1;
58    (function (module) {
59        (function (global, factory) {
60
61            {
62
63                // For CommonJS and CommonJS-like environments where a proper `window`
64                // is present, execute the factory and get jQuery.
65                // For environments that do not have a `window` with a `document`
66                // (such as Node.js), expose a factory as module.exports.
67                // This accentuates the need for the creation of a real `window`.
68                // e.g. var jQuery = require("jquery")(window);
69                // See ticket trac-14549 for more info.
70                module.exports = global.document ?
71                    factory(global, true) :
72                    function (w) {
73                        if (!w.document) {
74                            throw new Error("jQuery requires a window with a document");
75                        }
76                        return factory(w);
77                    };
78            }
79
80            // Pass this if window is not defined yet
81        })(typeof window !== "undefined" ? window : jquery, function (window, noGlobal) {
82
83            var arr = [];
84
85            var getProto = Object.getPrototypeOf;
86
87            var slice = arr.slice;
88
89            var flat = arr.flat ? function (array) {
90                return arr.flat.call(array);
91            } : function (array) {
92                return arr.concat.apply([], array);
93            };
94
95
96            var push = arr.push;
97
98            var indexOf = arr.indexOf;
99
100            var class2type = {};
101
102            var toString = class2type.toString;
103
104            var hasOwn = class2type.hasOwnProperty;
105
106            var fnToString = hasOwn.toString;
107
108            var ObjectFunctionString = fnToString.call(Object);
109
110            var support = {};
111
112            var isFunction = function isFunction(obj) {
113
114                // Support: Chrome <=57, Firefox <=52
115                // In some browsers, typeof returns "function" for HTML <object> elements
116                // (i.e., `typeof document.createElement( "object" ) === "function"`).
117                // We don't want to classify *any* DOM node as a function.
vendor: 8,750 bytes, lines 118-347
118                // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5
119                // Plus for old WebKit, typeof returns "function" for HTML collections
120                // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)
121                return typeof obj === "function" && typeof obj.nodeType !== "number" &&
122                    typeof obj.item !== "function";
123            };
124
125
126            var isWindow = function isWindow(obj) {
127                return obj != null && obj === obj.window;
128            };
129
130
131            var document = window.document;
132
133
134            var preservedScriptAttributes = {
135                type: true,
136                src: true,
137                nonce: true,
138                noModule: true
139            };
140
141            function DOMEval(code, node, doc) {
142                doc = doc || document;
143
144                var i, val,
145                    script = doc.createElement("script");
146
147                script.text = code;
148                if (node) {
149                    for (i in preservedScriptAttributes) {
150
151                        // Support: Firefox 64+, Edge 18+
152                        // Some browsers don't support the "nonce" property on scripts.
153                        // On the other hand, just using `getAttribute` is not enough as
154                        // the `nonce` attribute is reset to an empty string whenever it
155                        // becomes browsing-context connected.
156                        // See https://github.com/whatwg/html/issues/2369
157                        // See https://html.spec.whatwg.org/#nonce-attributes
158                        // The `node.getAttribute` check was added for the sake of
159                        // `jQuery.globalEval` so that it can fake a nonce-containing node
160                        // via an object.
161                        val = node[i] || node.getAttribute && node.getAttribute(i);
162                        if (val) {
163                            script.setAttribute(i, val);
164                        }
165                    }
166                }
167                doc.head.appendChild(script).parentNode.removeChild(script);
168            }
169
170
171            function toType(obj) {
172                if (obj == null) {
173                    return obj + "";
174                }
175
176                // Support: Android <=2.3 only (functionish RegExp)
177                return typeof obj === "object" || typeof obj === "function" ?
178                    class2type[toString.call(obj)] || "object" :
179                    typeof obj;
180            }
181
182            /* global Symbol */
183            // Defining this global in .eslintrc.json would create a danger of using the global
184            // unguarded in another place, it seems safer to define global only for this module
185
186
187            var version = "3.7.1",
188
189                rhtmlSuffix = /HTML$/i,
190
191                // Define a local copy of jQuery
192                jQuery = function (selector, context) {
193
194                    // The jQuery object is actually just the init constructor 'enhanced'
195                    // Need init if jQuery is called (just allow error to be thrown if not included)
196                    return new jQuery.fn.init(selector, context);
197                };
198
199            jQuery.fn = jQuery.prototype = {
200
201                // The current version of jQuery being used
202                jquery: version,
203
204                constructor: jQuery,
205
206                // The default length of a jQuery object is 0
207                length: 0,
208
209                toArray: function () {
210                    return slice.call(this);
211                },
212
213                // Get the Nth element in the matched element set OR
214                // Get the whole matched element set as a clean array
215                get: function (num) {
216
217                    // Return all the elements in a clean array
218                    if (num == null) {
219                        return slice.call(this);
220                    }
221
222                    // Return just the one element from the set
223                    return num < 0 ? this[num + this.length] : this[num];
224                },
225
226                // Take an array of elements and push it onto the stack
227                // (returning the new matched element set)
228                pushStack: function (elems) {
229
230                    // Build a new jQuery matched element set
231                    var ret = jQuery.merge(this.constructor(), elems);
232
233                    // Add the old object onto the stack (as a reference)
234                    ret.prevObject = this;
235
236                    // Return the newly-formed element set
237                    return ret;
238                },
239
240                // Execute a callback for every element in the matched set.
241                each: function (callback) {
242                    return jQuery.each(this, callback);
243                },
244
245                map: function (callback) {
246                    return this.pushStack(jQuery.map(this, function (elem, i) {
247                        return callback.call(elem, i, elem);
248                    }));
249                },
250
251                slice: function () {
252                    return this.pushStack(slice.apply(this, arguments));
253                },
254
255                first: function () {
256                    return this.eq(0);
257                },
258
259                last: function () {
260                    return this.eq(-1);
261                },
262
263                even: function () {
264                    return this.pushStack(jQuery.grep(this, function (_elem, i) {
265                        return (i + 1) % 2;
266                    }));
267                },
268
269                odd: function () {
270                    return this.pushStack(jQuery.grep(this, function (_elem, i) {
271                        return i % 2;
272                    }));
273                },
274
275                eq: function (i) {
276                    var len = this.length,
277                        j = +i + (i < 0 ? len : 0);
278                    return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
279                },
280
281                end: function () {
282                    return this.prevObject || this.constructor();
283                },
284
285                // For internal use only.
286                // Behaves like an Array's method, not like a jQuery method.
287                push: push,
288                sort: arr.sort,
289                splice: arr.splice
290            };
291
292            jQuery.extend = jQuery.fn.extend = function () {
293                var options, name, src, copy, copyIsArray, clone,
294                    target = arguments[0] || {},
295                    i = 1,
296                    length = arguments.length,
297                    deep = false;
298
299                // Handle a deep copy situation
300                if (typeof target === "boolean") {
301                    deep = target;
302
303                    // Skip the boolean and the target
304                    target = arguments[i] || {};
305                    i++;
306                }
307
308                // Handle case when target is a string or something (possible in deep copy)
309                if (typeof target !== "object" && !isFunction(target)) {
310                    target = {};
311                }
312
313                // Extend jQuery itself if only one argument is passed
314                if (i === length) {
315                    target = this;
316                    i--;
317                }
318
319                for (; i < length; i++) {
320
321                    // Only deal with non-null/undefined values
322                    if ((options = arguments[i]) != null) {
323
324                        // Extend the base object
325                        for (name in options) {
326                            copy = options[name];
327
328                            // Prevent Object.prototype pollution
329                            // Prevent never-ending loop
330                            if (name === "__proto__" || target === copy) {
331                                continue;
332                            }
333
334                            // Recurse if we're merging plain objects or arrays
335                            if (deep && copy && (jQuery.isPlainObject(copy) ||
336                                (copyIsArray = Array.isArray(copy)))) {
337                                src = target[name];
338
339                                // Ensure proper type for the source value
340                                if (copyIsArray && !Array.isArray(src)) {
341                                    clone = [];
342                                } else if (!copyIsArray && !jQuery.isPlainObject(src)) {
343                                    clone = {};
344                                } else {
345                                    clone = src;
346                                }
347                                copyIsArray = false;
vendor: 5,405 bytes, lines 348-498
348
349                                // Never move original objects, clone them
350                                target[name] = jQuery.extend(deep, clone, copy);
351
352                                // Don't bring in undefined values
353                            } else if (copy !== undefined) {
354                                target[name] = copy;
355                            }
356                        }
357                    }
358                }
359
360                // Return the modified object
361                return target;
362            };
363
364            jQuery.extend({
365
366                // Unique for each copy of jQuery on the page
367                expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
368
369                // Assume jQuery is ready without the ready module
370                isReady: true,
371
372                error: function (msg) {
373                    throw new Error(msg);
374                },
375
376                noop: function () {
377                },
378
379                isPlainObject: function (obj) {
380                    var proto, Ctor;
381
382                    // Detect obvious negatives
383                    // Use toString instead of jQuery.type to catch host objects
384                    if (!obj || toString.call(obj) !== "[object Object]") {
385                        return false;
386                    }
387
388                    proto = getProto(obj);
389
390                    // Objects with no prototype (e.g., `Object.create( null )`) are plain
391                    if (!proto) {
392                        return true;
393                    }
394
395                    // Objects with prototype are plain iff they were constructed by a global Object function
396                    Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
397                    return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
398                },
399
400                isEmptyObject: function (obj) {
401                    var name;
402
403                    for (name in obj) {
404                        return false;
405                    }
406                    return true;
407                },
408
409                // Evaluates a script in a provided context; falls back to the global one
410                // if not specified.
411                globalEval: function (code, options, doc) {
412                    DOMEval(code, {nonce: options && options.nonce}, doc);
413                },
414
415                each: function (obj, callback) {
416                    var length, i = 0;
417
418                    if (isArrayLike(obj)) {
419                        length = obj.length;
420                        for (; i < length; i++) {
421                            if (callback.call(obj[i], i, obj[i]) === false) {
422                                break;
423                            }
424                        }
425                    } else {
426                        for (i in obj) {
427                            if (callback.call(obj[i], i, obj[i]) === false) {
428                                break;
429                            }
430                        }
431                    }
432
433                    return obj;
434                },
435
436
437                // Retrieve the text value of an array of DOM nodes
438                text: function (elem) {
439                    var node,
440                        ret = "",
441                        i = 0,
442                        nodeType = elem.nodeType;
443
444                    if (!nodeType) {
445
446                        // If no nodeType, this is expected to be an array
447                        while ((node = elem[i++])) {
448
449                            // Do not traverse comment nodes
450                            ret += jQuery.text(node);
451                        }
452                    }
453                    if (nodeType === 1 || nodeType === 11) {
454                        return elem.textContent;
455                    }
456                    if (nodeType === 9) {
457                        return elem.documentElement.textContent;
458                    }
459                    if (nodeType === 3 || nodeType === 4) {
460                        return elem.nodeValue;
461                    }
462
463                    // Do not include comment or processing instruction nodes
464
465                    return ret;
466                },
467
468                // results is for internal usage only
469                makeArray: function (arr, results) {
470                    var ret = results || [];
471
472                    if (arr != null) {
473                        if (isArrayLike(Object(arr))) {
474                            jQuery.merge(ret,
475                                typeof arr === "string" ?
476                                    [arr] : arr
477                            );
478                        } else {
479                            push.call(ret, arr);
480                        }
481                    }
482
483                    return ret;
484                },
485
486                inArray: function (elem, arr, i) {
487                    return arr == null ? -1 : indexOf.call(arr, elem, i);
488                },
489
490                isXMLDoc: function (elem) {
491                    var namespace = elem && elem.namespaceURI,
492                        docElem = elem && (elem.ownerDocument || elem).documentElement;
493
494                    // Assume HTML when documentElement doesn't yet exist, such as inside
495                    // document fragments.
496                    return !rhtmlSuffix.test(namespace || docElem && docElem.nodeName || "HTML");
497                },
498
vendor: 56,575 bytes, lines 499-1734
499                // Support: Android <=4.0 only, PhantomJS 1 only
500                // push.apply(_, arraylike) throws on ancient WebKit
501                merge: function (first, second) {
502                    var len = +second.length,
503                        j = 0,
504                        i = first.length;
505
506                    for (; j < len; j++) {
507                        first[i++] = second[j];
508                    }
509
510                    first.length = i;
511
512                    return first;
513                },
514
515                grep: function (elems, callback, invert) {
516                    var callbackInverse,
517                        matches = [],
518                        i = 0,
519                        length = elems.length,
520                        callbackExpect = !invert;
521
522                    // Go through the array, only saving the items
523                    // that pass the validator function
524                    for (; i < length; i++) {
525                        callbackInverse = !callback(elems[i], i);
526                        if (callbackInverse !== callbackExpect) {
527                            matches.push(elems[i]);
528                        }
529                    }
530
531                    return matches;
532                },
533
534                // arg is for internal usage only
535                map: function (elems, callback, arg) {
536                    var length, value,
537                        i = 0,
538                        ret = [];
539
540                    // Go through the array, translating each of the items to their new values
541                    if (isArrayLike(elems)) {
542                        length = elems.length;
543                        for (; i < length; i++) {
544                            value = callback(elems[i], i, arg);
545
546                            if (value != null) {
547                                ret.push(value);
548                            }
549                        }
550
551                        // Go through every key on the object,
552                    } else {
553                        for (i in elems) {
554                            value = callback(elems[i], i, arg);
555
556                            if (value != null) {
557                                ret.push(value);
558                            }
559                        }
560                    }
561
562                    // Flatten any nested arrays
563                    return flat(ret);
564                },
565
566                // A global GUID counter for objects
567                guid: 1,
568
569                // jQuery.support is not used in Core but other projects attach their
570                // properties to it so it needs to exist.
571                support: support
572            });
573
574            if (typeof Symbol === "function") {
575                jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];
576            }
577
578            // Populate the class2type map
579            jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),
580                function (_i, name) {
581                    class2type["[object " + name + "]"] = name.toLowerCase();
582                });
583
584            function isArrayLike(obj) {
585
586                // Support: real iOS 8.2 only (not reproducible in simulator)
587                // `in` check used to prevent JIT error (gh-2145)
588                // hasOwn isn't used here due to false negatives
589                // regarding Nodelist length in IE
590                var length = !!obj && "length" in obj && obj.length,
591                    type = toType(obj);
592
593                if (isFunction(obj) || isWindow(obj)) {
594                    return false;
595                }
596
597                return type === "array" || length === 0 ||
598                    typeof length === "number" && length > 0 && (length - 1) in obj;
599            }
600
601
602            function nodeName(elem, name) {
603
604                return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
605
606            }
607
608            var pop = arr.pop;
609
610
611            var sort = arr.sort;
612
613
614            var splice = arr.splice;
615
616
617            var whitespace = "[\\x20\\t\\r\\n\\f]";
618
619
620            var rtrimCSS = new RegExp(
621                "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$",
622                "g"
623            );
624
625
626            // Note: an element does not contain itself
627            jQuery.contains = function (a, b) {
628                var bup = b && b.parentNode;
629
630                return a === bup || !!(bup && bup.nodeType === 1 && (
631
632                    // Support: IE 9 - 11+
633                    // IE doesn't have `contains` on SVG.
634                    a.contains ?
635                        a.contains(bup) :
636                        a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16
637                ));
638            };
639
640
641            // CSS string/identifier serialization
642            // https://drafts.csswg.org/cssom/#common-serializing-idioms
643            var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
644
645            function fcssescape(ch, asCodePoint) {
646                if (asCodePoint) {
647
648                    // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
649                    if (ch === "\0") {
650                        return "\uFFFD";
651                    }
652
653                    // Control characters and (dependent upon position) numbers get escaped as code points
654                    return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
655                }
656
657                // Other potentially-special ASCII characters get backslash-escaped
658                return "\\" + ch;
659            }
660
661            jQuery.escapeSelector = function (sel) {
662                return (sel + "").replace(rcssescape, fcssescape);
663            };
664
665
666            var preferredDoc = document,
667                pushNative = push;
668
669            (function () {
670
671                var i,
672                    Expr,
673                    outermostContext,
674                    sortInput,
675                    hasDuplicate,
676                    push = pushNative,
677
678                    // Local document vars
679                    document,
680                    documentElement,
681                    documentIsHTML,
682                    rbuggyQSA,
683                    matches,
684
685                    // Instance-specific data
686                    expando = jQuery.expando,
687                    dirruns = 0,
688                    done = 0,
689                    classCache = createCache(),
690                    tokenCache = createCache(),
691                    compilerCache = createCache(),
692                    nonnativeSelectorCache = createCache(),
693                    sortOrder = function (a, b) {
694                        if (a === b) {
695                            hasDuplicate = true;
696                        }
697                        return 0;
698                    },
699
700                    booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" +
701                        "loop|multiple|open|readonly|required|scoped",
702
703                    // Regular expressions
704
705                    // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
706                    identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
707                        "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
708
709                    // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors
710                    attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
711
712                        // Operator (capture 2)
713                        "*([*^$|!~]?=)" + whitespace +
714
715                        // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
716                        "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
717                        whitespace + "*\\]",
718
719                    pseudos = ":(" + identifier + ")(?:\\((" +
720
721                        // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
722                        // 1. quoted (capture 3; capture 4 or capture 5)
723                        "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
724
725                        // 2. simple (capture 6)
726                        "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
727
728                        // 3. anything else (capture 2)
729                        ".*" +
730                        ")\\)|)",
731
732                    // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
733                    rwhitespace = new RegExp(whitespace + "+", "g"),
734
735                    rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
736                    rleadingCombinator = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" +
737                        whitespace + "*"),
738                    rdescend = new RegExp(whitespace + "|>"),
739
740                    rpseudo = new RegExp(pseudos),
741                    ridentifier = new RegExp("^" + identifier + "$"),
742
743                    matchExpr = {
744                        ID: new RegExp("^#(" + identifier + ")"),
745                        CLASS: new RegExp("^\\.(" + identifier + ")"),
746                        TAG: new RegExp("^(" + identifier + "|[*])"),
747                        ATTR: new RegExp("^" + attributes),
748                        PSEUDO: new RegExp("^" + pseudos),
749                        CHILD: new RegExp(
750                            "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
751                            whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
752                            whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
753                        bool: new RegExp("^(?:" + booleans + ")$", "i"),
754
755                        // For use in libraries implementing .is()
756                        // We use this for POS matching in `select`
757                        needsContext: new RegExp("^" + whitespace +
758                            "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
759                            "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
760                    },
761
762                    rinputs = /^(?:input|select|textarea|button)$/i,
763                    rheader = /^h\d$/i,
764
765                    // Easily-parseable/retrievable ID or TAG or CLASS selectors
766                    rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
767
768                    rsibling = /[+~]/,
769
770                    // CSS escapes
771                    // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters
772                    runescape = new RegExp("\\\\[\\da-fA-F]{1,6}" + whitespace +
773                        "?|\\\\([^\\r\\n\\f])", "g"),
774                    funescape = function (escape, nonHex) {
775                        var high = "0x" + escape.slice(1) - 0x10000;
776
777                        if (nonHex) {
778
779                            // Strip the backslash prefix from a non-hex escape sequence
780                            return nonHex;
781                        }
782
783                        // Replace a hexadecimal escape sequence with the encoded Unicode code point
784                        // Support: IE <=11+
785                        // For values outside the Basic Multilingual Plane (BMP), manually construct a
786                        // surrogate pair
787                        return high < 0 ?
788                            String.fromCharCode(high + 0x10000) :
789                            String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
790                    },
791
792                    // Used for iframes; see `setDocument`.
793                    // Support: IE 9 - 11+, Edge 12 - 18+
794                    // Removing the function wrapper causes a "Permission Denied"
795                    // error in IE/Edge.
796                    unloadHandler = function () {
797                        setDocument();
798                    },
799
800                    inDisabledFieldset = addCombinator(
801                        function (elem) {
802                            return elem.disabled === true && nodeName(elem, "fieldset");
803                        },
804                        {dir: "parentNode", next: "legend"}
805                    );
806
807                // Support: IE <=9 only
808                // Accessing document.activeElement can throw unexpectedly
809                // https://bugs.jquery.com/ticket/13393
810                function safeActiveElement() {
811                    try {
812                        return document.activeElement;
813                    } catch (err) {
814                    }
815                }
816
817                // Optimize for push.apply( _, NodeList )
818                try {
819                    push.apply(
820                        (arr = slice.call(preferredDoc.childNodes)),
821                        preferredDoc.childNodes
822                    );
823
824                    // Support: Android <=4.0
825                    // Detect silently failing push.apply
826                    // eslint-disable-next-line no-unused-expressions
827                    arr[preferredDoc.childNodes.length].nodeType;
828                } catch (e) {
829                    push = {
830                        apply: function (target, els) {
831                            pushNative.apply(target, slice.call(els));
832                        },
833                        call: function (target) {
834                            pushNative.apply(target, slice.call(arguments, 1));
835                        }
836                    };
837                }
838
839                function find(selector, context, results, seed) {
840                    var m, i, elem, nid, match, groups, newSelector,
841                        newContext = context && context.ownerDocument,
842
843                        // nodeType defaults to 9, since context defaults to document
844                        nodeType = context ? context.nodeType : 9;
845
846                    results = results || [];
847
848                    // Return early from calls with invalid selector or context
849                    if (typeof selector !== "string" || !selector ||
850                        nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
851
852                        return results;
853                    }
854
855                    // Try to shortcut find operations (as opposed to filters) in HTML documents
856                    if (!seed) {
857                        setDocument(context);
858                        context = context || document;
859
860                        if (documentIsHTML) {
861
862                            // If the selector is sufficiently simple, try using a "get*By*" DOM method
863                            // (excepting DocumentFragment context, where the methods don't exist)
864                            if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
865
866                                // ID selector
867                                if ((m = match[1])) {
868
869                                    // Document context
870                                    if (nodeType === 9) {
871                                        if ((elem = context.getElementById(m))) {
872
873                                            // Support: IE 9 only
874                                            // getElementById can match elements by name instead of ID
875                                            if (elem.id === m) {
876                                                push.call(results, elem);
877                                                return results;
878                                            }
879                                        } else {
880                                            return results;
881                                        }
882
883                                        // Element context
884                                    } else {
885
886                                        // Support: IE 9 only
887                                        // getElementById can match elements by name instead of ID
888                                        if (newContext && (elem = newContext.getElementById(m)) &&
889                                            find.contains(context, elem) &&
890                                            elem.id === m) {
891
892                                            push.call(results, elem);
893                                            return results;
894                                        }
895                                    }
896
897                                    // Type selector
898                                } else if (match[2]) {
899                                    push.apply(results, context.getElementsByTagName(selector));
900                                    return results;
901
902                                    // Class selector
903                                } else if ((m = match[3]) && context.getElementsByClassName) {
904                                    push.apply(results, context.getElementsByClassName(m));
905                                    return results;
906                                }
907                            }
908
909                            // Take advantage of querySelectorAll
910                            if (!nonnativeSelectorCache[selector + " "] &&
911                                (!rbuggyQSA || !rbuggyQSA.test(selector))) {
912
913                                newSelector = selector;
914                                newContext = context;
915
916                                // qSA considers elements outside a scoping root when evaluating child or
917                                // descendant combinators, which is not what we want.
918                                // In such cases, we work around the behavior by prefixing every selector in the
919                                // list with an ID selector referencing the scope context.
920                                // The technique has to be used as well when a leading combinator is used
921                                // as such selectors are not recognized by querySelectorAll.
922                                // Thanks to Andrew Dupont for this technique.
923                                if (nodeType === 1 &&
924                                    (rdescend.test(selector) || rleadingCombinator.test(selector))) {
925
926                                    // Expand context for sibling selectors
927                                    newContext = rsibling.test(selector) && testContext(context.parentNode) ||
928                                        context;
929
930                                    // We can use :scope instead of the ID hack if the browser
931                                    // supports it & if we're not changing the context.
932                                    // Support: IE 11+, Edge 17 - 18+
933                                    // IE/Edge sometimes throw a "Permission denied" error when
934                                    // strict-comparing two documents; shallow comparisons work.
935                                    // eslint-disable-next-line eqeqeq
936                                    if (newContext != context || !support.scope) {
937
938                                        // Capture the context ID, setting it first if necessary
939                                        if ((nid = context.getAttribute("id"))) {
940                                            nid = jQuery.escapeSelector(nid);
941                                        } else {
942                                            context.setAttribute("id", (nid = expando));
943                                        }
944                                    }
945
946                                    // Prefix every selector in the list
947                                    groups = tokenize(selector);
948                                    i = groups.length;
949                                    while (i--) {
950                                        groups[i] = (nid ? "#" + nid : ":scope") + " " +
951                                            toSelector(groups[i]);
952                                    }
953                                    newSelector = groups.join(",");
954                                }
955
956                                try {
957                                    push.apply(results,
958                                        newContext.querySelectorAll(newSelector)
959                                    );
960                                    return results;
961                                } catch (qsaError) {
962                                    nonnativeSelectorCache(selector, true);
963                                } finally {
964                                    if (nid === expando) {
965                                        context.removeAttribute("id");
966                                    }
967                                }
968                            }
969                        }
970                    }
971
972                    // All others
973                    return select(selector.replace(rtrimCSS, "$1"), context, results, seed);
974                }
975
976                /**
977                 * Create key-value caches of limited size
978                 * @returns {function(string, object)} Returns the Object data after storing it on itself with
979                 *    property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
980                 *    deleting the oldest entry
981                 */
982                function createCache() {
983                    var keys = [];
984
985                    function cache(key, value) {
986
987                        // Use (key + " ") to avoid collision with native prototype properties
988                        // (see https://github.com/jquery/sizzle/issues/157)
989                        if (keys.push(key + " ") > Expr.cacheLength) {
990
991                            // Only keep the most recent entries
992                            delete cache[keys.shift()];
993                        }
994                        return (cache[key + " "] = value);
995                    }
996
997                    return cache;
998                }
999
1000                /**
1001                 * Mark a function for special use by jQuery selector module
1002                 * @param {Function} fn The function to mark
1003                 */
1004                function markFunction(fn) {
1005                    fn[expando] = true;
1006                    return fn;
1007                }
1008
1009                /**
1010                 * Support testing using an element
1011                 * @param {Function} fn Passed the created element and returns a boolean result
1012                 */
1013                function assert(fn) {
1014                    var el = document.createElement("fieldset");
1015
1016                    try {
1017                        return !!fn(el);
1018                    } catch (e) {
1019                        return false;
1020                    } finally {
1021
1022                        // Remove from its parent by default
1023                        if (el.parentNode) {
1024                            el.parentNode.removeChild(el);
1025                        }
1026
1027                        // release memory in IE
1028                        el = null;
1029                    }
1030                }
1031
1032                /**
1033                 * Returns a function to use in pseudos for input types
1034                 * @param {String} type
1035                 */
1036                function createInputPseudo(type) {
1037                    return function (elem) {
1038                        return nodeName(elem, "input") && elem.type === type;
1039                    };
1040                }
1041
1042                /**
1043                 * Returns a function to use in pseudos for buttons
1044                 * @param {String} type
1045                 */
1046                function createButtonPseudo(type) {
1047                    return function (elem) {
1048                        return (nodeName(elem, "input") || nodeName(elem, "button")) &&
1049                            elem.type === type;
1050                    };
1051                }
1052
1053                /**
1054                 * Returns a function to use in pseudos for :enabled/:disabled
1055                 * @param {Boolean} disabled true for :disabled; false for :enabled
1056                 */
1057                function createDisabledPseudo(disabled) {
1058
1059                    // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
1060                    return function (elem) {
1061
1062                        // Only certain elements can match :enabled or :disabled
1063                        // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
1064                        // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
1065                        if ("form" in elem) {
1066
1067                            // Check for inherited disabledness on relevant non-disabled elements:
1068                            // * listed form-associated elements in a disabled fieldset
1069                            //   https://html.spec.whatwg.org/multipage/forms.html#category-listed
1070                            //   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
1071                            // * option elements in a disabled optgroup
1072                            //   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
1073                            // All such elements have a "form" property.
1074                            if (elem.parentNode && elem.disabled === false) {
1075
1076                                // Option elements defer to a parent optgroup if present
1077                                if ("label" in elem) {
1078                                    if ("label" in elem.parentNode) {
1079                                        return elem.parentNode.disabled === disabled;
1080                                    } else {
1081                                        return elem.disabled === disabled;
1082                                    }
1083                                }
1084
1085                                // Support: IE 6 - 11+
1086                                // Use the isDisabled shortcut property to check for disabled fieldset ancestors
1087                                return elem.isDisabled === disabled ||
1088
1089                                    // Where there is no isDisabled, check manually
1090                                    elem.isDisabled !== !disabled &&
1091                                    inDisabledFieldset(elem) === disabled;
1092                            }
1093
1094                            return elem.disabled === disabled;
1095
1096                            // Try to winnow out elements that can't be disabled before trusting the disabled property.
1097                            // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1098                            // even exist on them, let alone have a boolean value.
1099                        } else if ("label" in elem) {
1100                            return elem.disabled === disabled;
1101                        }
1102
1103                        // Remaining elements are neither :enabled nor :disabled
1104                        return false;
1105                    };
1106                }
1107
1108                /**
1109                 * Returns a function to use in pseudos for positionals
1110                 * @param {Function} fn
1111                 */
1112                function createPositionalPseudo(fn) {
1113                    return markFunction(function (argument) {
1114                        argument = +argument;
1115                        return markFunction(function (seed, matches) {
1116                            var j,
1117                                matchIndexes = fn([], seed.length, argument),
1118                                i = matchIndexes.length;
1119
1120                            // Match elements found at the specified indexes
1121                            while (i--) {
1122                                if (seed[(j = matchIndexes[i])]) {
1123                                    seed[j] = !(matches[j] = seed[j]);
1124                                }
1125                            }
1126                        });
1127                    });
1128                }
1129
1130                /**
1131                 * Checks a node for validity as a jQuery selector context
1132                 * @param {Element|Object=} context
1133                 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1134                 */
1135                function testContext(context) {
1136                    return context && typeof context.getElementsByTagName !== "undefined" && context;
1137                }
1138
1139                /**
1140                 * Sets document-related variables once based on the current document
1141                 * @param {Element|Object} [node] An element or document object to use to set the document
1142                 * @returns {Object} Returns the current document
1143                 */
1144                function setDocument(node) {
1145                    var subWindow,
1146                        doc = node ? node.ownerDocument || node : preferredDoc;
1147
1148                    // Return early if doc is invalid or already selected
1149                    // Support: IE 11+, Edge 17 - 18+
1150                    // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1151                    // two documents; shallow comparisons work.
1152                    // eslint-disable-next-line eqeqeq
1153                    if (doc == document || doc.nodeType !== 9 || !doc.documentElement) {
1154                        return document;
1155                    }
1156
1157                    // Update global variables
1158                    document = doc;
1159                    documentElement = document.documentElement;
1160                    documentIsHTML = !jQuery.isXMLDoc(document);
1161
1162                    // Support: iOS 7 only, IE 9 - 11+
1163                    // Older browsers didn't support unprefixed `matches`.
1164                    matches = documentElement.matches ||
1165                        documentElement.webkitMatchesSelector ||
1166                        documentElement.msMatchesSelector;
1167
1168                    // Support: IE 9 - 11+, Edge 12 - 18+
1169                    // Accessing iframe documents after unload throws "permission denied" errors
1170                    // (see trac-13936).
1171                    // Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`,
1172                    // all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well.
1173                    if (documentElement.msMatchesSelector &&
1174
1175                        // Support: IE 11+, Edge 17 - 18+
1176                        // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1177                        // two documents; shallow comparisons work.
1178                        // eslint-disable-next-line eqeqeq
1179                        preferredDoc != document &&
1180                        (subWindow = document.defaultView) && subWindow.top !== subWindow) {
1181
1182                        // Support: IE 9 - 11+, Edge 12 - 18+
1183                        subWindow.addEventListener("unload", unloadHandler);
1184                    }
1185
1186                    // Support: IE <10
1187                    // Check if getElementById returns elements by name
1188                    // The broken getElementById methods don't pick up programmatically-set names,
1189                    // so use a roundabout getElementsByName test
1190                    support.getById = assert(function (el) {
1191                        documentElement.appendChild(el).id = jQuery.expando;
1192                        return !document.getElementsByName ||
1193                            !document.getElementsByName(jQuery.expando).length;
1194                    });
1195
1196                    // Support: IE 9 only
1197                    // Check to see if it's possible to do matchesSelector
1198                    // on a disconnected node.
1199                    support.disconnectedMatch = assert(function (el) {
1200                        return matches.call(el, "*");
1201                    });
1202
1203                    // Support: IE 9 - 11+, Edge 12 - 18+
1204                    // IE/Edge don't support the :scope pseudo-class.
1205                    support.scope = assert(function () {
1206                        return document.querySelectorAll(":scope");
1207                    });
1208
1209                    // Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only
1210                    // Make sure the `:has()` argument is parsed unforgivingly.
1211                    // We include `*` in the test to detect buggy implementations that are
1212                    // _selectively_ forgiving (specifically when the list includes at least
1213                    // one valid selector).
1214                    // Note that we treat complete lack of support for `:has()` as if it were
1215                    // spec-compliant support, which is fine because use of `:has()` in such
1216                    // environments will fail in the qSA path and fall back to jQuery traversal
1217                    // anyway.
1218                    support.cssHas = assert(function () {
1219                        try {
1220                            document.querySelector(":has(*,:jqfake)");
1221                            return false;
1222                        } catch (e) {
1223                            return true;
1224                        }
1225                    });
1226
1227                    // ID filter and find
1228                    if (support.getById) {
1229                        Expr.filter.ID = function (id) {
1230                            var attrId = id.replace(runescape, funescape);
1231                            return function (elem) {
1232                                return elem.getAttribute("id") === attrId;
1233                            };
1234                        };
1235                        Expr.find.ID = function (id, context) {
1236                            if (typeof context.getElementById !== "undefined" && documentIsHTML) {
1237                                var elem = context.getElementById(id);
1238                                return elem ? [elem] : [];
1239                            }
1240                        };
1241                    } else {
1242                        Expr.filter.ID = function (id) {
1243                            var attrId = id.replace(runescape, funescape);
1244                            return function (elem) {
1245                                var node = typeof elem.getAttributeNode !== "undefined" &&
1246                                    elem.getAttributeNode("id");
1247                                return node && node.value === attrId;
1248                            };
1249                        };
1250
1251                        // Support: IE 6 - 7 only
1252                        // getElementById is not reliable as a find shortcut
1253                        Expr.find.ID = function (id, context) {
1254                            if (typeof context.getElementById !== "undefined" && documentIsHTML) {
1255                                var node, i, elems,
1256                                    elem = context.getElementById(id);
1257
1258                                if (elem) {
1259
1260                                    // Verify the id attribute
1261                                    node = elem.getAttributeNode("id");
1262                                    if (node && node.value === id) {
1263                                        return [elem];
1264                                    }
1265
1266                                    // Fall back on getElementsByName
1267                                    elems = context.getElementsByName(id);
1268                                    i = 0;
1269                                    while ((elem = elems[i++])) {
1270                                        node = elem.getAttributeNode("id");
1271                                        if (node && node.value === id) {
1272                                            return [elem];
1273                                        }
1274                                    }
1275                                }
1276
1277                                return [];
1278                            }
1279                        };
1280                    }
1281
1282                    // Tag
1283                    Expr.find.TAG = function (tag, context) {
1284                        if (typeof context.getElementsByTagName !== "undefined") {
1285                            return context.getElementsByTagName(tag);
1286
1287                            // DocumentFragment nodes don't have gEBTN
1288                        } else {
1289                            return context.querySelectorAll(tag);
1290                        }
1291                    };
1292
1293                    // Class
1294                    Expr.find.CLASS = function (className, context) {
1295                        if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {
1296                            return context.getElementsByClassName(className);
1297                        }
1298                    };
1299
1300                    /* QSA/matchesSelector
1301			---------------------------------------------------------------------- */
1302
1303                    // QSA and matchesSelector support
1304
1305                    rbuggyQSA = [];
1306
1307                    // Build QSA regex
1308                    // Regex strategy adopted from Diego Perini
1309                    assert(function (el) {
1310
1311                        var input;
1312
1313                        documentElement.appendChild(el).innerHTML =
1314                            "<a id='" + expando + "' href='' disabled='disabled'></a>" +
1315                            "<select id='" + expando + "-\r\\' disabled='disabled'>" +
1316                            "<option selected=''></option></select>";
1317
1318                        // Support: iOS <=7 - 8 only
1319                        // Boolean attributes and "value" are not treated correctly in some XML documents
1320                        if (!el.querySelectorAll("[selected]").length) {
1321                            rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
1322                        }
1323
1324                        // Support: iOS <=7 - 8 only
1325                        if (!el.querySelectorAll("[id~=" + expando + "-]").length) {
1326                            rbuggyQSA.push("~=");
1327                        }
1328
1329                        // Support: iOS 8 only
1330                        // https://bugs.webkit.org/show_bug.cgi?id=136851
1331                        // In-page `selector#id sibling-combinator selector` fails
1332                        if (!el.querySelectorAll("a#" + expando + "+*").length) {
1333                            rbuggyQSA.push(".#.+[+~]");
1334                        }
1335
1336                        // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
1337                        // In some of the document kinds, these selectors wouldn't work natively.
1338                        // This is probably OK but for backwards compatibility we want to maintain
1339                        // handling them through jQuery traversal in jQuery 3.x.
1340                        if (!el.querySelectorAll(":checked").length) {
1341                            rbuggyQSA.push(":checked");
1342                        }
1343
1344                        // Support: Windows 8 Native Apps
1345                        // The type and name attributes are restricted during .innerHTML assignment
1346                        input = document.createElement("input");
1347                        input.setAttribute("type", "hidden");
1348                        el.appendChild(input).setAttribute("name", "D");
1349
1350                        // Support: IE 9 - 11+
1351                        // IE's :disabled selector does not pick up the children of disabled fieldsets
1352                        // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+
1353                        // In some of the document kinds, these selectors wouldn't work natively.
1354                        // This is probably OK but for backwards compatibility we want to maintain
1355                        // handling them through jQuery traversal in jQuery 3.x.
1356                        documentElement.appendChild(el).disabled = true;
1357                        if (el.querySelectorAll(":disabled").length !== 2) {
1358                            rbuggyQSA.push(":enabled", ":disabled");
1359                        }
1360
1361                        // Support: IE 11+, Edge 15 - 18+
1362                        // IE 11/Edge don't find elements on a `[name='']` query in some cases.
1363                        // Adding a temporary attribute to the document before the selection works
1364                        // around the issue.
1365                        // Interestingly, IE 10 & older don't seem to have the issue.
1366                        input = document.createElement("input");
1367                        input.setAttribute("name", "");
1368                        el.appendChild(input);
1369                        if (!el.querySelectorAll("[name='']").length) {
1370                            rbuggyQSA.push("\\[" + whitespace + "*name" + whitespace + "*=" +
1371                                whitespace + "*(?:''|\"\")");
1372                        }
1373                    });
1374
1375                    if (!support.cssHas) {
1376
1377                        // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+
1378                        // Our regular `try-catch` mechanism fails to detect natively-unsupported
1379                        // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`)
1380                        // in browsers that parse the `:has()` argument as a forgiving selector list.
1381                        // https://drafts.csswg.org/selectors/#relational now requires the argument
1382                        // to be parsed unforgivingly, but browsers have not yet fully adjusted.
1383                        rbuggyQSA.push(":has");
1384                    }
1385
1386                    rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
1387
1388                    /* Sorting
1389			---------------------------------------------------------------------- */
1390
1391                    // Document order sorting
1392                    sortOrder = function (a, b) {
1393
1394                        // Flag for duplicate removal
1395                        if (a === b) {
1396                            hasDuplicate = true;
1397                            return 0;
1398                        }
1399
1400                        // Sort on method existence if only one input has compareDocumentPosition
1401                        var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1402                        if (compare) {
1403                            return compare;
1404                        }
1405
1406                        // Calculate position if both inputs belong to the same document
1407                        // Support: IE 11+, Edge 17 - 18+
1408                        // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1409                        // two documents; shallow comparisons work.
1410                        // eslint-disable-next-line eqeqeq
1411                        compare = (a.ownerDocument || a) == (b.ownerDocument || b) ?
1412                            a.compareDocumentPosition(b) :
1413
1414                            // Otherwise we know they are disconnected
1415                            1;
1416
1417                        // Disconnected nodes
1418                        if (compare & 1 ||
1419                            (!support.sortDetached && b.compareDocumentPosition(a) === compare)) {
1420
1421                            // Choose the first element that is related to our preferred document
1422                            // Support: IE 11+, Edge 17 - 18+
1423                            // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1424                            // two documents; shallow comparisons work.
1425                            // eslint-disable-next-line eqeqeq
1426                            if (a === document || a.ownerDocument == preferredDoc &&
1427                                find.contains(preferredDoc, a)) {
1428                                return -1;
1429                            }
1430
1431                            // Support: IE 11+, Edge 17 - 18+
1432                            // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1433                            // two documents; shallow comparisons work.
1434                            // eslint-disable-next-line eqeqeq
1435                            if (b === document || b.ownerDocument == preferredDoc &&
1436                                find.contains(preferredDoc, b)) {
1437                                return 1;
1438                            }
1439
1440                            // Maintain original order
1441                            return sortInput ?
1442                                (indexOf.call(sortInput, a) - indexOf.call(sortInput, b)) :
1443                                0;
1444                        }
1445
1446                        return compare & 4 ? -1 : 1;
1447                    };
1448
1449                    return document;
1450                }
1451
1452                find.matches = function (expr, elements) {
1453                    return find(expr, null, null, elements);
1454                };
1455
1456                find.matchesSelector = function (elem, expr) {
1457                    setDocument(elem);
1458
1459                    if (documentIsHTML &&
1460                        !nonnativeSelectorCache[expr + " "] &&
1461                        (!rbuggyQSA || !rbuggyQSA.test(expr))) {
1462
1463                        try {
1464                            var ret = matches.call(elem, expr);
1465
1466                            // IE 9's matchesSelector returns false on disconnected nodes
1467                            if (ret || support.disconnectedMatch ||
1468
1469                                // As well, disconnected nodes are said to be in a document
1470                                // fragment in IE 9
1471                                elem.document && elem.document.nodeType !== 11) {
1472                                return ret;
1473                            }
1474                        } catch (e) {
1475                            nonnativeSelectorCache(expr, true);
1476                        }
1477                    }
1478
1479                    return find(expr, document, null, [elem]).length > 0;
1480                };
1481
1482                find.contains = function (context, elem) {
1483
1484                    // Set document vars if needed
1485                    // Support: IE 11+, Edge 17 - 18+
1486                    // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1487                    // two documents; shallow comparisons work.
1488                    // eslint-disable-next-line eqeqeq
1489                    if ((context.ownerDocument || context) != document) {
1490                        setDocument(context);
1491                    }
1492                    return jQuery.contains(context, elem);
1493                };
1494
1495
1496                find.attr = function (elem, name) {
1497
1498                    // Set document vars if needed
1499                    // Support: IE 11+, Edge 17 - 18+
1500                    // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1501                    // two documents; shallow comparisons work.
1502                    // eslint-disable-next-line eqeqeq
1503                    if ((elem.ownerDocument || elem) != document) {
1504                        setDocument(elem);
1505                    }
1506
1507                    var fn = Expr.attrHandle[name.toLowerCase()],
1508
1509                        // Don't get fooled by Object.prototype properties (see trac-13807)
1510                        val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ?
1511                            fn(elem, name, !documentIsHTML) :
1512                            undefined;
1513
1514                    if (val !== undefined) {
1515                        return val;
1516                    }
1517
1518                    return elem.getAttribute(name);
1519                };
1520
1521                find.error = function (msg) {
1522                    throw new Error("Syntax error, unrecognized expression: " + msg);
1523                };
1524
1525                /**
1526                 * Document sorting and removing duplicates
1527                 * @param {ArrayLike} results
1528                 */
1529                jQuery.uniqueSort = function (results) {
1530                    var elem,
1531                        duplicates = [],
1532                        j = 0,
1533                        i = 0;
1534
1535                    // Unless we *know* we can detect duplicates, assume their presence
1536                    //
1537                    // Support: Android <=4.0+
1538                    // Testing for detecting duplicates is unpredictable so instead assume we can't
1539                    // depend on duplicate detection in all browsers without a stable sort.
1540                    hasDuplicate = !support.sortStable;
1541                    sortInput = !support.sortStable && slice.call(results, 0);
1542                    sort.call(results, sortOrder);
1543
1544                    if (hasDuplicate) {
1545                        while ((elem = results[i++])) {
1546                            if (elem === results[i]) {
1547                                j = duplicates.push(i);
1548                            }
1549                        }
1550                        while (j--) {
1551                            splice.call(results, duplicates[j], 1);
1552                        }
1553                    }
1554
1555                    // Clear input after sorting to release objects
1556                    // See https://github.com/jquery/sizzle/pull/225
1557                    sortInput = null;
1558
1559                    return results;
1560                };
1561
1562                jQuery.fn.uniqueSort = function () {
1563                    return this.pushStack(jQuery.uniqueSort(slice.apply(this)));
1564                };
1565
1566                Expr = jQuery.expr = {
1567
1568                    // Can be adjusted by the user
1569                    cacheLength: 50,
1570
1571                    createPseudo: markFunction,
1572
1573                    match: matchExpr,
1574
1575                    attrHandle: {},
1576
1577                    find: {},
1578
1579                    relative: {
1580                        ">": {dir: "parentNode", first: true},
1581                        " ": {dir: "parentNode"},
1582                        "+": {dir: "previousSibling", first: true},
1583                        "~": {dir: "previousSibling"}
1584                    },
1585
1586                    preFilter: {
1587                        ATTR: function (match) {
1588                            match[1] = match[1].replace(runescape, funescape);
1589
1590                            // Move the given value to match[3] whether quoted or unquoted
1591                            match[3] = (match[3] || match[4] || match[5] || "")
1592                                .replace(runescape, funescape);
1593
1594                            if (match[2] === "~=") {
1595                                match[3] = " " + match[3] + " ";
1596                            }
1597
1598                            return match.slice(0, 4);
1599                        },
1600
1601                        CHILD: function (match) {
1602
1603                            /* matches from matchExpr["CHILD"]
1604						1 type (only|nth|...)
1605						2 what (child|of-type)
1606						3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1607						4 xn-component of xn+y argument ([+-]?\d*n|)
1608						5 sign of xn-component
1609						6 x of xn-component
1610						7 sign of y-component
1611						8 y of y-component
1612					*/
1613                            match[1] = match[1].toLowerCase();
1614
1615                            if (match[1].slice(0, 3) === "nth") {
1616
1617                                // nth-* requires argument
1618                                if (!match[3]) {
1619                                    find.error(match[0]);
1620                                }
1621
1622                                // numeric x and y parameters for Expr.filter.CHILD
1623                                // remember that false/true cast respectively to 0/1
1624                                match[4] = +(match[4] ?
1625                                        match[5] + (match[6] || 1) :
1626                                        2 * (match[3] === "even" || match[3] === "odd")
1627                                );
1628                                match[5] = +((match[7] + match[8]) || match[3] === "odd");
1629
1630                                // other types prohibit arguments
1631                            } else if (match[3]) {
1632                                find.error(match[0]);
1633                            }
1634
1635                            return match;
1636                        },
1637
1638                        PSEUDO: function (match) {
1639                            var excess,
1640                                unquoted = !match[6] && match[2];
1641
1642                            if (matchExpr.CHILD.test(match[0])) {
1643                                return null;
1644                            }
1645
1646                            // Accept quoted arguments as-is
1647                            if (match[3]) {
1648                                match[2] = match[4] || match[5] || "";
1649
1650                                // Strip excess characters from unquoted arguments
1651                            } else if (unquoted && rpseudo.test(unquoted) &&
1652
1653                                // Get excess from tokenize (recursively)
1654                                (excess = tokenize(unquoted, true)) &&
1655
1656                                // advance to the next closing parenthesis
1657                                (excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
1658
1659                                // excess is a negative index
1660                                match[0] = match[0].slice(0, excess);
1661                                match[2] = unquoted.slice(0, excess);
1662                            }
1663
1664                            // Return only captures needed by the pseudo filter method (type and argument)
1665                            return match.slice(0, 3);
1666                        }
1667                    },
1668
1669                    filter: {
1670
1671                        TAG: function (nodeNameSelector) {
1672                            var expectedNodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
1673                            return nodeNameSelector === "*" ?
1674                                function () {
1675                                    return true;
1676                                } :
1677                                function (elem) {
1678                                    return nodeName(elem, expectedNodeName);
1679                                };
1680                        },
1681
1682                        CLASS: function (className) {
1683                            var pattern = classCache[className + " "];
1684
1685                            return pattern ||
1686                                (pattern = new RegExp("(^|" + whitespace + ")" + className +
1687                                    "(" + whitespace + "|$)")) &&
1688                                classCache(className, function (elem) {
1689                                    return pattern.test(
1690                                        typeof elem.className === "string" && elem.className ||
1691                                        typeof elem.getAttribute !== "undefined" &&
1692                                        elem.getAttribute("class") ||
1693                                        ""
1694                                    );
1695                                });
1696                        },
1697
1698                        ATTR: function (name, operator, check) {
1699                            return function (elem) {
1700                                var result = find.attr(elem, name);
1701
1702                                if (result == null) {
1703                                    return operator === "!=";
1704                                }
1705                                if (!operator) {
1706                                    return true;
1707                                }
1708
1709                                result += "";
1710
1711                                if (operator === "=") {
1712                                    return result === check;
1713                                }
1714                                if (operator === "!=") {
1715                                    return result !== check;
1716                                }
1717                                if (operator === "^=") {
1718                                    return check && result.indexOf(check) === 0;
1719                                }
1720                                if (operator === "*=") {
1721                                    return check && result.indexOf(check) > -1;
1722                                }
1723                                if (operator === "$=") {
1724                                    return check && result.slice(-check.length) === check;
1725                                }
1726                                if (operator === "~=") {
1727                                    return (" " + result.replace(rwhitespace, " ") + " ")
1728                                        .indexOf(check) > -1;
1729                                }
1730                                if (operator === "|=") {
1731                                    return result === check || result.slice(0, check.length + 1) === check + "-";
1732                                }
1733
1734                                return false;
1735                            };
1736                        },
1737
1738                        CHILD: function (type, what, _argument, first, last) {
1739                            var simple = type.slice(0, 3) !== "nth",
1740                                forward = type.slice(-4) !== "last",
1741                                ofType = what === "of-type";
1742
1743                            return first === 1 && last === 0 ?
1744
1745                                // Shortcut for :nth-*(n)
1746                                function (elem) {
1747                                    return !!elem.parentNode;
1748                                } :
1749
1750                                function (elem, _context, xml) {
1751                                    var cache, outerCache, node, nodeIndex, start,
1752                                        dir = simple !== forward ? "nextSibling" : "previousSibling",
1753                                        parent = elem.parentNode,
1754                                        name = ofType && elem.nodeName.toLowerCase(),
1755                                        useCache = !xml && !ofType,
1756                                        diff = false;
vendor: 105,126 bytes, lines 1757-4071
1757
1758                                    if (parent) {
1759
1760                                        // :(first|last|only)-(child|of-type)
1761                                        if (simple) {
1762                                            while (dir) {
1763                                                node = elem;
1764                                                while ((node = node[dir])) {
1765                                                    if (ofType ?
1766                                                        nodeName(node, name) :
1767                                                        node.nodeType === 1) {
1768
1769                                                        return false;
1770                                                    }
1771                                                }
1772
1773                                                // Reverse direction for :only-* (if we haven't yet done so)
1774                                                start = dir = type === "only" && !start && "nextSibling";
1775                                            }
1776                                            return true;
1777                                        }
1778
1779                                        start = [forward ? parent.firstChild : parent.lastChild];
1780
1781                                        // non-xml :nth-child(...) stores cache data on `parent`
1782                                        if (forward && useCache) {
1783
1784                                            // Seek `elem` from a previously-cached index
1785                                            outerCache = parent[expando] || (parent[expando] = {});
1786                                            cache = outerCache[type] || [];
1787                                            nodeIndex = cache[0] === dirruns && cache[1];
1788                                            diff = nodeIndex && cache[2];
1789                                            node = nodeIndex && parent.childNodes[nodeIndex];
1790
1791                                            while ((node = ++nodeIndex && node && node[dir] ||
1792
1793                                                // Fallback to seeking `elem` from the start
1794                                                (diff = nodeIndex = 0) || start.pop())) {
1795
1796                                                // When found, cache indexes on `parent` and break
1797                                                if (node.nodeType === 1 && ++diff && node === elem) {
1798                                                    outerCache[type] = [dirruns, nodeIndex, diff];
1799                                                    break;
1800                                                }
1801                                            }
1802
1803                                        } else {
1804
1805                                            // Use previously-cached element index if available
1806                                            if (useCache) {
1807                                                outerCache = elem[expando] || (elem[expando] = {});
1808                                                cache = outerCache[type] || [];
1809                                                nodeIndex = cache[0] === dirruns && cache[1];
1810                                                diff = nodeIndex;
1811                                            }
1812
1813                                            // xml :nth-child(...)
1814                                            // or :nth-last-child(...) or :nth(-last)?-of-type(...)
1815                                            if (diff === false) {
1816
1817                                                // Use the same loop as above to seek `elem` from the start
1818                                                while ((node = ++nodeIndex && node && node[dir] ||
1819                                                    (diff = nodeIndex = 0) || start.pop())) {
1820
1821                                                    if ((ofType ?
1822                                                            nodeName(node, name) :
1823                                                            node.nodeType === 1) &&
1824                                                        ++diff) {
1825
1826                                                        // Cache the index of each encountered element
1827                                                        if (useCache) {
1828                                                            outerCache = node[expando] ||
1829                                                                (node[expando] = {});
1830                                                            outerCache[type] = [dirruns, diff];
1831                                                        }
1832
1833                                                        if (node === elem) {
1834                                                            break;
1835                                                        }
1836                                                    }
1837                                                }
1838                                            }
1839                                        }
1840
1841                                        // Incorporate the offset, then check against cycle size
1842                                        diff -= last;
1843                                        return diff === first || (diff % first === 0 && diff / first >= 0);
1844                                    }
1845                                };
1846                        },
1847
1848                        PSEUDO: function (pseudo, argument) {
1849
1850                            // pseudo-class names are case-insensitive
1851                            // https://www.w3.org/TR/selectors/#pseudo-classes
1852                            // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1853                            // Remember that setFilters inherits from pseudos
1854                            var args,
1855                                fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] ||
1856                                    find.error("unsupported pseudo: " + pseudo);
1857
1858                            // The user may use createPseudo to indicate that
1859                            // arguments are needed to create the filter function
1860                            // just as jQuery does
1861                            if (fn[expando]) {
1862                                return fn(argument);
1863                            }
1864
1865                            // But maintain support for old signatures
1866                            if (fn.length > 1) {
1867                                args = [pseudo, pseudo, "", argument];
1868                                return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ?
1869                                    markFunction(function (seed, matches) {
1870                                        var idx,
1871                                            matched = fn(seed, argument),
1872                                            i = matched.length;
1873                                        while (i--) {
1874                                            idx = indexOf.call(seed, matched[i]);
1875                                            seed[idx] = !(matches[idx] = matched[i]);
1876                                        }
1877                                    }) :
1878                                    function (elem) {
1879                                        return fn(elem, 0, args);
1880                                    };
1881                            }
1882
1883                            return fn;
1884                        }
1885                    },
1886
1887                    pseudos: {
1888
1889                        // Potentially complex pseudos
1890                        not: markFunction(function (selector) {
1891
1892                            // Trim the selector passed to compile
1893                            // to avoid treating leading and trailing
1894                            // spaces as combinators
1895                            var input = [],
1896                                results = [],
1897                                matcher = compile(selector.replace(rtrimCSS, "$1"));
1898
1899                            return matcher[expando] ?
1900                                markFunction(function (seed, matches, _context, xml) {
1901                                    var elem,
1902                                        unmatched = matcher(seed, null, xml, []),
1903                                        i = seed.length;
1904
1905                                    // Match elements unmatched by `matcher`
1906                                    while (i--) {
1907                                        if ((elem = unmatched[i])) {
1908                                            seed[i] = !(matches[i] = elem);
1909                                        }
1910                                    }
1911                                }) :
1912                                function (elem, _context, xml) {
1913                                    input[0] = elem;
1914                                    matcher(input, null, xml, results);
1915
1916                                    // Don't keep the element
1917                                    // (see https://github.com/jquery/sizzle/issues/299)
1918                                    input[0] = null;
1919                                    return !results.pop();
1920                                };
1921                        }),
1922
1923                        has: markFunction(function (selector) {
1924                            return function (elem) {
1925                                return find(selector, elem).length > 0;
1926                            };
1927                        }),
1928
1929                        contains: markFunction(function (text) {
1930                            text = text.replace(runescape, funescape);
1931                            return function (elem) {
1932                                return (elem.textContent || jQuery.text(elem)).indexOf(text) > -1;
1933                            };
1934                        }),
1935
1936                        // "Whether an element is represented by a :lang() selector
1937                        // is based solely on the element's language value
1938                        // being equal to the identifier C,
1939                        // or beginning with the identifier C immediately followed by "-".
1940                        // The matching of C against the element's language value is performed case-insensitively.
1941                        // The identifier C does not have to be a valid language name."
1942                        // https://www.w3.org/TR/selectors/#lang-pseudo
1943                        lang: markFunction(function (lang) {
1944
1945                            // lang value must be a valid identifier
1946                            if (!ridentifier.test(lang || "")) {
1947                                find.error("unsupported lang: " + lang);
1948                            }
1949                            lang = lang.replace(runescape, funescape).toLowerCase();
1950                            return function (elem) {
1951                                var elemLang;
1952                                do {
1953                                    if ((elemLang = documentIsHTML ?
1954                                        elem.lang :
1955                                        elem.getAttribute("xml:lang") || elem.getAttribute("lang"))) {
1956
1957                                        elemLang = elemLang.toLowerCase();
1958                                        return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
1959                                    }
1960                                } while ((elem = elem.parentNode) && elem.nodeType === 1);
1961                                return false;
1962                            };
1963                        }),
1964
1965                        // Miscellaneous
1966                        target: function (elem) {
1967                            var hash = window.location && window.location.hash;
1968                            return hash && hash.slice(1) === elem.id;
1969                        },
1970
1971                        root: function (elem) {
1972                            return elem === documentElement;
1973                        },
1974
1975                        focus: function (elem) {
1976                            return elem === safeActiveElement() &&
1977                                document.hasFocus() &&
1978                                !!(elem.type || elem.href || ~elem.tabIndex);
1979                        },
1980
1981                        // Boolean properties
1982                        enabled: createDisabledPseudo(false),
1983                        disabled: createDisabledPseudo(true),
1984
1985                        checked: function (elem) {
1986
1987                            // In CSS3, :checked should return both checked and selected elements
1988                            // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1989                            return (nodeName(elem, "input") && !!elem.checked) ||
1990                                (nodeName(elem, "option") && !!elem.selected);
1991                        },
1992
1993                        selected: function (elem) {
1994
1995                            // Support: IE <=11+
1996                            // Accessing the selectedIndex property
1997                            // forces the browser to treat the default option as
1998                            // selected when in an optgroup.
1999                            if (elem.parentNode) {
2000                                // eslint-disable-next-line no-unused-expressions
2001                                elem.parentNode.selectedIndex;
2002                            }
2003
2004                            return elem.selected === true;
2005                        },
2006
2007                        // Contents
2008                        empty: function (elem) {
2009
2010                            // https://www.w3.org/TR/selectors/#empty-pseudo
2011                            // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2012                            //   but not by others (comment: 8; processing instruction: 7; etc.)
2013                            // nodeType < 6 works because attributes (2) do not appear as children
2014                            for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
2015                                if (elem.nodeType < 6) {
2016                                    return false;
2017                                }
2018                            }
2019                            return true;
2020                        },
2021
2022                        parent: function (elem) {
2023                            return !Expr.pseudos.empty(elem);
2024                        },
2025
2026                        // Element/input types
2027                        header: function (elem) {
2028                            return rheader.test(elem.nodeName);
2029                        },
2030
2031                        input: function (elem) {
2032                            return rinputs.test(elem.nodeName);
2033                        },
2034
2035                        button: function (elem) {
2036                            return nodeName(elem, "input") && elem.type === "button" ||
2037                                nodeName(elem, "button");
2038                        },
2039
2040                        text: function (elem) {
2041                            var attr;
2042                            return nodeName(elem, "input") && elem.type === "text" &&
2043
2044                                // Support: IE <10 only
2045                                // New HTML5 attribute values (e.g., "search") appear
2046                                // with elem.type === "text"
2047                                ((attr = elem.getAttribute("type")) == null ||
2048                                    attr.toLowerCase() === "text");
2049                        },
2050
2051                        // Position-in-collection
2052                        first: createPositionalPseudo(function () {
2053                            return [0];
2054                        }),
2055
2056                        last: createPositionalPseudo(function (_matchIndexes, length) {
2057                            return [length - 1];
2058                        }),
2059
2060                        eq: createPositionalPseudo(function (_matchIndexes, length, argument) {
2061                            return [argument < 0 ? argument + length : argument];
2062                        }),
2063
2064                        even: createPositionalPseudo(function (matchIndexes, length) {
2065                            var i = 0;
2066                            for (; i < length; i += 2) {
2067                                matchIndexes.push(i);
2068                            }
2069                            return matchIndexes;
2070                        }),
2071
2072                        odd: createPositionalPseudo(function (matchIndexes, length) {
2073                            var i = 1;
2074                            for (; i < length; i += 2) {
2075                                matchIndexes.push(i);
2076                            }
2077                            return matchIndexes;
2078                        }),
2079
2080                        lt: createPositionalPseudo(function (matchIndexes, length, argument) {
2081                            var i;
2082
2083                            if (argument < 0) {
2084                                i = argument + length;
2085                            } else if (argument > length) {
2086                                i = length;
2087                            } else {
2088                                i = argument;
2089                            }
2090
2091                            for (; --i >= 0;) {
2092                                matchIndexes.push(i);
2093                            }
2094                            return matchIndexes;
2095                        }),
2096
2097                        gt: createPositionalPseudo(function (matchIndexes, length, argument) {
2098                            var i = argument < 0 ? argument + length : argument;
2099                            for (; ++i < length;) {
2100                                matchIndexes.push(i);
2101                            }
2102                            return matchIndexes;
2103                        })
2104                    }
2105                };
2106
2107                Expr.pseudos.nth = Expr.pseudos.eq;
2108
2109                // Add button/input type pseudos
2110                for (i in {radio: true, checkbox: true, file: true, password: true, image: true}) {
2111                    Expr.pseudos[i] = createInputPseudo(i);
2112                }
2113                for (i in {submit: true, reset: true}) {
2114                    Expr.pseudos[i] = createButtonPseudo(i);
2115                }
2116
2117                // Easy API for creating new setFilters
2118                function setFilters() {
2119                }
2120
2121                setFilters.prototype = Expr.filters = Expr.pseudos;
2122                Expr.setFilters = new setFilters();
2123
2124                function tokenize(selector, parseOnly) {
2125                    var matched, match, tokens, type,
2126                        soFar, groups, preFilters,
2127                        cached = tokenCache[selector + " "];
2128
2129                    if (cached) {
2130                        return parseOnly ? 0 : cached.slice(0);
2131                    }
2132
2133                    soFar = selector;
2134                    groups = [];
2135                    preFilters = Expr.preFilter;
2136
2137                    while (soFar) {
2138
2139                        // Comma and first run
2140                        if (!matched || (match = rcomma.exec(soFar))) {
2141                            if (match) {
2142
2143                                // Don't consume trailing commas as valid
2144                                soFar = soFar.slice(match[0].length) || soFar;
2145                            }
2146                            groups.push((tokens = []));
2147                        }
2148
2149                        matched = false;
2150
2151                        // Combinators
2152                        if ((match = rleadingCombinator.exec(soFar))) {
2153                            matched = match.shift();
2154                            tokens.push({
2155                                value: matched,
2156
2157                                // Cast descendant combinators to space
2158                                type: match[0].replace(rtrimCSS, " ")
2159                            });
2160                            soFar = soFar.slice(matched.length);
2161                        }
2162
2163                        // Filters
2164                        for (type in Expr.filter) {
2165                            if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] ||
2166                                (match = preFilters[type](match)))) {
2167                                matched = match.shift();
2168                                tokens.push({
2169                                    value: matched,
2170                                    type: type,
2171                                    matches: match
2172                                });
2173                                soFar = soFar.slice(matched.length);
2174                            }
2175                        }
2176
2177                        if (!matched) {
2178                            break;
2179                        }
2180                    }
2181
2182                    // Return the length of the invalid excess
2183                    // if we're just parsing
2184                    // Otherwise, throw an error or return tokens
2185                    if (parseOnly) {
2186                        return soFar.length;
2187                    }
2188
2189                    return soFar ?
2190                        find.error(selector) :
2191
2192                        // Cache the tokens
2193                        tokenCache(selector, groups).slice(0);
2194                }
2195
2196                function toSelector(tokens) {
2197                    var i = 0,
2198                        len = tokens.length,
2199                        selector = "";
2200                    for (; i < len; i++) {
2201                        selector += tokens[i].value;
2202                    }
2203                    return selector;
2204                }
2205
2206                function addCombinator(matcher, combinator, base) {
2207                    var dir = combinator.dir,
2208                        skip = combinator.next,
2209                        key = skip || dir,
2210                        checkNonElements = base && key === "parentNode",
2211                        doneName = done++;
2212
2213                    return combinator.first ?
2214
2215                        // Check against closest ancestor/preceding element
2216                        function (elem, context, xml) {
2217                            while ((elem = elem[dir])) {
2218                                if (elem.nodeType === 1 || checkNonElements) {
2219                                    return matcher(elem, context, xml);
2220                                }
2221                            }
2222                            return false;
2223                        } :
2224
2225                        // Check against all ancestor/preceding elements
2226                        function (elem, context, xml) {
2227                            var oldCache, outerCache,
2228                                newCache = [dirruns, doneName];
2229
2230                            // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2231                            if (xml) {
2232                                while ((elem = elem[dir])) {
2233                                    if (elem.nodeType === 1 || checkNonElements) {
2234                                        if (matcher(elem, context, xml)) {
2235                                            return true;
2236                                        }
2237                                    }
2238                                }
2239                            } else {
2240                                while ((elem = elem[dir])) {
2241                                    if (elem.nodeType === 1 || checkNonElements) {
2242                                        outerCache = elem[expando] || (elem[expando] = {});
2243
2244                                        if (skip && nodeName(elem, skip)) {
2245                                            elem = elem[dir] || elem;
2246                                        } else if ((oldCache = outerCache[key]) &&
2247                                            oldCache[0] === dirruns && oldCache[1] === doneName) {
2248
2249                                            // Assign to newCache so results back-propagate to previous elements
2250                                            return (newCache[2] = oldCache[2]);
2251                                        } else {
2252
2253                                            // Reuse newcache so results back-propagate to previous elements
2254                                            outerCache[key] = newCache;
2255
2256                                            // A match means we're done; a fail means we have to keep checking
2257                                            if ((newCache[2] = matcher(elem, context, xml))) {
2258                                                return true;
2259                                            }
2260                                        }
2261                                    }
2262                                }
2263                            }
2264                            return false;
2265                        };
2266                }
2267
2268                function elementMatcher(matchers) {
2269                    return matchers.length > 1 ?
2270                        function (elem, context, xml) {
2271                            var i = matchers.length;
2272                            while (i--) {
2273                                if (!matchers[i](elem, context, xml)) {
2274                                    return false;
2275                                }
2276                            }
2277                            return true;
2278                        } :
2279                        matchers[0];
2280                }
2281
2282                function multipleContexts(selector, contexts, results) {
2283                    var i = 0,
2284                        len = contexts.length;
2285                    for (; i < len; i++) {
2286                        find(selector, contexts[i], results);
2287                    }
2288                    return results;
2289                }
2290
2291                function condense(unmatched, map, filter, context, xml) {
2292                    var elem,
2293                        newUnmatched = [],
2294                        i = 0,
2295                        len = unmatched.length,
2296                        mapped = map != null;
2297
2298                    for (; i < len; i++) {
2299                        if ((elem = unmatched[i])) {
2300                            if (!filter || filter(elem, context, xml)) {
2301                                newUnmatched.push(elem);
2302                                if (mapped) {
2303                                    map.push(i);
2304                                }
2305                            }
2306                        }
2307                    }
2308
2309                    return newUnmatched;
2310                }
2311
2312                function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
2313                    if (postFilter && !postFilter[expando]) {
2314                        postFilter = setMatcher(postFilter);
2315                    }
2316                    if (postFinder && !postFinder[expando]) {
2317                        postFinder = setMatcher(postFinder, postSelector);
2318                    }
2319                    return markFunction(function (seed, results, context, xml) {
2320                        var temp, i, elem, matcherOut,
2321                            preMap = [],
2322                            postMap = [],
2323                            preexisting = results.length,
2324
2325                            // Get initial elements from seed or context
2326                            elems = seed ||
2327                                multipleContexts(selector || "*",
2328                                    context.nodeType ? [context] : context, []),
2329
2330                            // Prefilter to get matcher input, preserving a map for seed-results synchronization
2331                            matcherIn = preFilter && (seed || !selector) ?
2332                                condense(elems, preMap, preFilter, context, xml) :
2333                                elems;
2334
2335                        if (matcher) {
2336
2337                            // If we have a postFinder, or filtered seed, or non-seed postFilter
2338                            // or preexisting results,
2339                            matcherOut = postFinder || (seed ? preFilter : preexisting || postFilter) ?
2340
2341                                // ...intermediate processing is necessary
2342                                [] :
2343
2344                                // ...otherwise use results directly
2345                                results;
2346
2347                            // Find primary matches
2348                            matcher(matcherIn, matcherOut, context, xml);
2349                        } else {
2350                            matcherOut = matcherIn;
2351                        }
2352
2353                        // Apply postFilter
2354                        if (postFilter) {
2355                            temp = condense(matcherOut, postMap);
2356                            postFilter(temp, [], context, xml);
2357
2358                            // Un-match failing elements by moving them back to matcherIn
2359                            i = temp.length;
2360                            while (i--) {
2361                                if ((elem = temp[i])) {
2362                                    matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
2363                                }
2364                            }
2365                        }
2366
2367                        if (seed) {
2368                            if (postFinder || preFilter) {
2369                                if (postFinder) {
2370
2371                                    // Get the final matcherOut by condensing this intermediate into postFinder contexts
2372                                    temp = [];
2373                                    i = matcherOut.length;
2374                                    while (i--) {
2375                                        if ((elem = matcherOut[i])) {
2376
2377                                            // Restore matcherIn since elem is not yet a final match
2378                                            temp.push((matcherIn[i] = elem));
2379                                        }
2380                                    }
2381                                    postFinder(null, (matcherOut = []), temp, xml);
2382                                }
2383
2384                                // Move matched elements from seed to results to keep them synchronized
2385                                i = matcherOut.length;
2386                                while (i--) {
2387                                    if ((elem = matcherOut[i]) &&
2388                                        (temp = postFinder ? indexOf.call(seed, elem) : preMap[i]) > -1) {
2389
2390                                        seed[temp] = !(results[temp] = elem);
2391                                    }
2392                                }
2393                            }
2394
2395                            // Add elements to results, through postFinder if defined
2396                        } else {
2397                            matcherOut = condense(
2398                                matcherOut === results ?
2399                                    matcherOut.splice(preexisting, matcherOut.length) :
2400                                    matcherOut
2401                            );
2402                            if (postFinder) {
2403                                postFinder(null, results, matcherOut, xml);
2404                            } else {
2405                                push.apply(results, matcherOut);
2406                            }
2407                        }
2408                    });
2409                }
2410
2411                function matcherFromTokens(tokens) {
2412                    var checkContext, matcher, j,
2413                        len = tokens.length,
2414                        leadingRelative = Expr.relative[tokens[0].type],
2415                        implicitRelative = leadingRelative || Expr.relative[" "],
2416                        i = leadingRelative ? 1 : 0,
2417
2418                        // The foundational matcher ensures that elements are reachable from top-level context(s)
2419                        matchContext = addCombinator(function (elem) {
2420                            return elem === checkContext;
2421                        }, implicitRelative, true),
2422                        matchAnyContext = addCombinator(function (elem) {
2423                            return indexOf.call(checkContext, elem) > -1;
2424                        }, implicitRelative, true),
2425                        matchers = [function (elem, context, xml) {
2426
2427                            // Support: IE 11+, Edge 17 - 18+
2428                            // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2429                            // two documents; shallow comparisons work.
2430                            // eslint-disable-next-line eqeqeq
2431                            var ret = (!leadingRelative && (xml || context != outermostContext)) || (
2432                                (checkContext = context).nodeType ?
2433                                    matchContext(elem, context, xml) :
2434                                    matchAnyContext(elem, context, xml));
2435
2436                            // Avoid hanging onto element
2437                            // (see https://github.com/jquery/sizzle/issues/299)
2438                            checkContext = null;
2439                            return ret;
2440                        }];
2441
2442                    for (; i < len; i++) {
2443                        if ((matcher = Expr.relative[tokens[i].type])) {
2444                            matchers = [addCombinator(elementMatcher(matchers), matcher)];
2445                        } else {
2446                            matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
2447
2448                            // Return special upon seeing a positional matcher
2449                            if (matcher[expando]) {
2450
2451                                // Find the next relative operator (if any) for proper handling
2452                                j = ++i;
2453                                for (; j < len; j++) {
2454                                    if (Expr.relative[tokens[j].type]) {
2455                                        break;
2456                                    }
2457                                }
2458                                return setMatcher(
2459                                    i > 1 && elementMatcher(matchers),
2460                                    i > 1 && toSelector(
2461                                        // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2462                                        tokens.slice(0, i - 1)
2463                                            .concat({value: tokens[i - 2].type === " " ? "*" : ""})
2464                                    ).replace(rtrimCSS, "$1"),
2465                                    matcher,
2466                                    i < j && matcherFromTokens(tokens.slice(i, j)),
2467                                    j < len && matcherFromTokens((tokens = tokens.slice(j))),
2468                                    j < len && toSelector(tokens)
2469                                );
2470                            }
2471                            matchers.push(matcher);
2472                        }
2473                    }
2474
2475                    return elementMatcher(matchers);
2476                }
2477
2478                function matcherFromGroupMatchers(elementMatchers, setMatchers) {
2479                    var bySet = setMatchers.length > 0,
2480                        byElement = elementMatchers.length > 0,
2481                        superMatcher = function (seed, context, xml, results, outermost) {
2482                            var elem, j, matcher,
2483                                matchedCount = 0,
2484                                i = "0",
2485                                unmatched = seed && [],
2486                                setMatched = [],
2487                                contextBackup = outermostContext,
2488
2489                                // We must always have either seed elements or outermost context
2490                                elems = seed || byElement && Expr.find.TAG("*", outermost),
2491
2492                                // Use integer dirruns iff this is the outermost matcher
2493                                dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2494                                len = elems.length;
2495
2496                            if (outermost) {
2497
2498                                // Support: IE 11+, Edge 17 - 18+
2499                                // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2500                                // two documents; shallow comparisons work.
2501                                // eslint-disable-next-line eqeqeq
2502                                outermostContext = context == document || context || outermost;
2503                            }
2504
2505                            // Add elements passing elementMatchers directly to results
2506                            // Support: iOS <=7 - 9 only
2507                            // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching
2508                            // elements by id. (see trac-14142)
2509                            for (; i !== len && (elem = elems[i]) != null; i++) {
2510                                if (byElement && elem) {
2511                                    j = 0;
2512
2513                                    // Support: IE 11+, Edge 17 - 18+
2514                                    // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2515                                    // two documents; shallow comparisons work.
2516                                    // eslint-disable-next-line eqeqeq
2517                                    if (!context && elem.ownerDocument != document) {
2518                                        setDocument(elem);
2519                                        xml = !documentIsHTML;
2520                                    }
2521                                    while ((matcher = elementMatchers[j++])) {
2522                                        if (matcher(elem, context || document, xml)) {
2523                                            push.call(results, elem);
2524                                            break;
2525                                        }
2526                                    }
2527                                    if (outermost) {
2528                                        dirruns = dirrunsUnique;
2529                                    }
2530                                }
2531
2532                                // Track unmatched elements for set filters
2533                                if (bySet) {
2534
2535                                    // They will have gone through all possible matchers
2536                                    if ((elem = !matcher && elem)) {
2537                                        matchedCount--;
2538                                    }
2539
2540                                    // Lengthen the array for every element, matched or not
2541                                    if (seed) {
2542                                        unmatched.push(elem);
2543                                    }
2544                                }
2545                            }
2546
2547                            // `i` is now the count of elements visited above, and adding it to `matchedCount`
2548                            // makes the latter nonnegative.
2549                            matchedCount += i;
2550
2551                            // Apply set filters to unmatched elements
2552                            // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2553                            // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2554                            // no element matchers and no seed.
2555                            // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2556                            // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2557                            // numerically zero.
2558                            if (bySet && i !== matchedCount) {
2559                                j = 0;
2560                                while ((matcher = setMatchers[j++])) {
2561                                    matcher(unmatched, setMatched, context, xml);
2562                                }
2563
2564                                if (seed) {
2565
2566                                    // Reintegrate element matches to eliminate the need for sorting
2567                                    if (matchedCount > 0) {
2568                                        while (i--) {
2569                                            if (!(unmatched[i] || setMatched[i])) {
2570                                                setMatched[i] = pop.call(results);
2571                                            }
2572                                        }
2573                                    }
2574
2575                                    // Discard index placeholder values to get only actual matches
2576                                    setMatched = condense(setMatched);
2577                                }
2578
2579                                // Add matches to results
2580                                push.apply(results, setMatched);
2581
2582                                // Seedless set matches succeeding multiple successful matchers stipulate sorting
2583                                if (outermost && !seed && setMatched.length > 0 &&
2584                                    (matchedCount + setMatchers.length) > 1) {
2585
2586                                    jQuery.uniqueSort(results);
2587                                }
2588                            }
2589
2590                            // Override manipulation of globals by nested matchers
2591                            if (outermost) {
2592                                dirruns = dirrunsUnique;
2593                                outermostContext = contextBackup;
2594                            }
2595
2596                            return unmatched;
2597                        };
2598
2599                    return bySet ?
2600                        markFunction(superMatcher) :
2601                        superMatcher;
2602                }
2603
2604                function compile(selector, match /* Internal Use Only */) {
2605                    var i,
2606                        setMatchers = [],
2607                        elementMatchers = [],
2608                        cached = compilerCache[selector + " "];
2609
2610                    if (!cached) {
2611
2612                        // Generate a function of recursive functions that can be used to check each element
2613                        if (!match) {
2614                            match = tokenize(selector);
2615                        }
2616                        i = match.length;
2617                        while (i--) {
2618                            cached = matcherFromTokens(match[i]);
2619                            if (cached[expando]) {
2620                                setMatchers.push(cached);
2621                            } else {
2622                                elementMatchers.push(cached);
2623                            }
2624                        }
2625
2626                        // Cache the compiled function
2627                        cached = compilerCache(selector,
2628                            matcherFromGroupMatchers(elementMatchers, setMatchers));
2629
2630                        // Save selector and tokenization
2631                        cached.selector = selector;
2632                    }
2633                    return cached;
2634                }
2635
2636                /**
2637                 * A low-level selection function that works with jQuery's compiled
2638                 *  selector functions
2639                 * @param {String|Function} selector A selector or a pre-compiled
2640                 *  selector function built with jQuery selector compile
2641                 * @param {Element} context
2642                 * @param {Array} [results]
2643                 * @param {Array} [seed] A set of elements to match against
2644                 */
2645                function select(selector, context, results, seed) {
2646                    var i, tokens, token, type, find,
2647                        compiled = typeof selector === "function" && selector,
2648                        match = !seed && tokenize((selector = compiled.selector || selector));
2649
2650                    results = results || [];
2651
2652                    // Try to minimize operations if there is only one selector in the list and no seed
2653                    // (the latter of which guarantees us context)
2654                    if (match.length === 1) {
2655
2656                        // Reduce context if the leading compound selector is an ID
2657                        tokens = match[0] = match[0].slice(0);
2658                        if (tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2659                            context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
2660
2661                            context = (Expr.find.ID(
2662                                token.matches[0].replace(runescape, funescape),
2663                                context
2664                            ) || [])[0];
2665                            if (!context) {
2666                                return results;
2667
2668                                // Precompiled matchers will still verify ancestry, so step up a level
2669                            } else if (compiled) {
2670                                context = context.parentNode;
2671                            }
2672
2673                            selector = selector.slice(tokens.shift().value.length);
2674                        }
2675
2676                        // Fetch a seed set for right-to-left matching
2677                        i = matchExpr.needsContext.test(selector) ? 0 : tokens.length;
2678                        while (i--) {
2679                            token = tokens[i];
2680
2681                            // Abort if we hit a combinator
2682                            if (Expr.relative[(type = token.type)]) {
2683                                break;
2684                            }
2685                            if ((find = Expr.find[type])) {
2686
2687                                // Search, expanding context for leading sibling combinators
2688                                if ((seed = find(
2689                                    token.matches[0].replace(runescape, funescape),
2690                                    rsibling.test(tokens[0].type) &&
2691                                    testContext(context.parentNode) || context
2692                                ))) {
2693
2694                                    // If seed is empty or no tokens remain, we can return early
2695                                    tokens.splice(i, 1);
2696                                    selector = seed.length && toSelector(tokens);
2697                                    if (!selector) {
2698                                        push.apply(results, seed);
2699                                        return results;
2700                                    }
2701
2702                                    break;
2703                                }
2704                            }
2705                        }
2706                    }
2707
2708                    // Compile and execute a filtering function if one is not provided
2709                    // Provide `match` to avoid retokenization if we modified the selector above
2710                    (compiled || compile(selector, match))(
2711                        seed,
2712                        context,
2713                        !documentIsHTML,
2714                        results,
2715                        !context || rsibling.test(selector) && testContext(context.parentNode) || context
2716                    );
2717                    return results;
2718                }
2719
2720                // One-time assignments
2721
2722                // Support: Android <=4.0 - 4.1+
2723                // Sort stability
2724                support.sortStable = expando.split("").sort(sortOrder).join("") === expando;
2725
2726                // Initialize against the default document
2727                setDocument();
2728
2729                // Support: Android <=4.0 - 4.1+
2730                // Detached nodes confoundingly follow *each other*
2731                support.sortDetached = assert(function (el) {
2732
2733                    // Should return 1, but returns 4 (following)
2734                    return el.compareDocumentPosition(document.createElement("fieldset")) & 1;
2735                });
2736
2737                jQuery.find = find;
2738
2739                // Deprecated
2740                jQuery.expr[":"] = jQuery.expr.pseudos;
2741                jQuery.unique = jQuery.uniqueSort;
2742
2743                // These have always been private, but they used to be documented as part of
2744                // Sizzle so let's maintain them for now for backwards compatibility purposes.
2745                find.compile = compile;
2746                find.select = select;
2747                find.setDocument = setDocument;
2748                find.tokenize = tokenize;
2749
2750                find.escape = jQuery.escapeSelector;
2751                find.getText = jQuery.text;
2752                find.isXML = jQuery.isXMLDoc;
2753                find.selectors = jQuery.expr;
2754                find.support = jQuery.support;
2755                find.uniqueSort = jQuery.uniqueSort;
2756
2757                /* eslint-enable */
2758
2759            })();
2760
2761
2762            var dir = function (elem, dir, until) {
2763                var matched = [],
2764                    truncate = until !== undefined;
2765
2766                while ((elem = elem[dir]) && elem.nodeType !== 9) {
2767                    if (elem.nodeType === 1) {
2768                        if (truncate && jQuery(elem).is(until)) {
2769                            break;
2770                        }
2771                        matched.push(elem);
2772                    }
2773                }
2774                return matched;
2775            };
2776
2777
2778            var siblings = function (n, elem) {
2779                var matched = [];
2780
2781                for (; n; n = n.nextSibling) {
2782                    if (n.nodeType === 1 && n !== elem) {
2783                        matched.push(n);
2784                    }
2785                }
2786
2787                return matched;
2788            };
2789
2790
2791            var rneedsContext = jQuery.expr.match.needsContext;
2792
2793            var rsingleTag = (/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i);
2794
2795
2796            // Implement the identical functionality for filter and not
2797            function winnow(elements, qualifier, not) {
2798                if (isFunction(qualifier)) {
2799                    return jQuery.grep(elements, function (elem, i) {
2800                        return !!qualifier.call(elem, i, elem) !== not;
2801                    });
2802                }
2803
2804                // Single element
2805                if (qualifier.nodeType) {
2806                    return jQuery.grep(elements, function (elem) {
2807                        return (elem === qualifier) !== not;
2808                    });
2809                }
2810
2811                // Arraylike of elements (jQuery, arguments, Array)
2812                if (typeof qualifier !== "string") {
2813                    return jQuery.grep(elements, function (elem) {
2814                        return (indexOf.call(qualifier, elem) > -1) !== not;
2815                    });
2816                }
2817
2818                // Filtered directly for both simple and complex selectors
2819                return jQuery.filter(qualifier, elements, not);
2820            }
2821
2822            jQuery.filter = function (expr, elems, not) {
2823                var elem = elems[0];
2824
2825                if (not) {
2826                    expr = ":not(" + expr + ")";
2827                }
2828
2829                if (elems.length === 1 && elem.nodeType === 1) {
2830                    return jQuery.find.matchesSelector(elem, expr) ? [elem] : [];
2831                }
2832
2833                return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {
2834                    return elem.nodeType === 1;
2835                }));
2836            };
2837
2838            jQuery.fn.extend({
2839                find: function (selector) {
2840                    var i, ret,
2841                        len = this.length,
2842                        self = this;
2843
2844                    if (typeof selector !== "string") {
2845                        return this.pushStack(jQuery(selector).filter(function () {
2846                            for (i = 0; i < len; i++) {
2847                                if (jQuery.contains(self[i], this)) {
2848                                    return true;
2849                                }
2850                            }
2851                        }));
2852                    }
2853
2854                    ret = this.pushStack([]);
2855
2856                    for (i = 0; i < len; i++) {
2857                        jQuery.find(selector, self[i], ret);
2858                    }
2859
2860                    return len > 1 ? jQuery.uniqueSort(ret) : ret;
2861                },
2862                filter: function (selector) {
2863                    return this.pushStack(winnow(this, selector || [], false));
2864                },
2865                not: function (selector) {
2866                    return this.pushStack(winnow(this, selector || [], true));
2867                },
2868                is: function (selector) {
2869                    return !!winnow(
2870                        this,
2871
2872                        // If this is a positional/relative selector, check membership in the returned set
2873                        // so $("p:first").is("p:last") won't return true for a doc with two "p".
2874                        typeof selector === "string" && rneedsContext.test(selector) ?
2875                            jQuery(selector) :
2876                            selector || [],
2877                        false
2878                    ).length;
2879                }
2880            });
2881
2882
2883            // Initialize a jQuery object
2884
2885
2886            // A central reference to the root jQuery(document)
2887            var rootjQuery,
2888
2889                // A simple way to check for HTML strings
2890                // Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521)
2891                // Strict HTML recognition (trac-11290: must start with <)
2892                // Shortcut simple #id case for speed
2893                rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
2894
2895                init = jQuery.fn.init = function (selector, context, root) {
2896                    var match, elem;
2897
2898                    // HANDLE: $(""), $(null), $(undefined), $(false)
2899                    if (!selector) {
2900                        return this;
2901                    }
2902
2903                    // Method init() accepts an alternate rootjQuery
2904                    // so migrate can support jQuery.sub (gh-2101)
2905                    root = root || rootjQuery;
2906
2907                    // Handle HTML strings
2908                    if (typeof selector === "string") {
2909                        if (selector[0] === "<" &&
2910                            selector[selector.length - 1] === ">" &&
2911                            selector.length >= 3) {
2912
2913                            // Assume that strings that start and end with <> are HTML and skip the regex check
2914                            match = [null, selector, null];
2915
2916                        } else {
2917                            match = rquickExpr.exec(selector);
2918                        }
2919
2920                        // Match html or make sure no context is specified for #id
2921                        if (match && (match[1] || !context)) {
2922
2923                            // HANDLE: $(html) -> $(array)
2924                            if (match[1]) {
2925                                context = context instanceof jQuery ? context[0] : context;
2926
2927                                // Option to run scripts is true for back-compat
2928                                // Intentionally let the error be thrown if parseHTML is not present
2929                                jQuery.merge(this, jQuery.parseHTML(
2930                                    match[1],
2931                                    context && context.nodeType ? context.ownerDocument || context : document,
2932                                    true
2933                                ));
2934
2935                                // HANDLE: $(html, props)
2936                                if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
2937                                    for (match in context) {
2938
2939                                        // Properties of context are called as methods if possible
2940                                        if (isFunction(this[match])) {
2941                                            this[match](context[match]);
2942
2943                                            // ...and otherwise set as attributes
2944                                        } else {
2945                                            this.attr(match, context[match]);
2946                                        }
2947                                    }
2948                                }
2949
2950                                return this;
2951
2952                                // HANDLE: $(#id)
2953                            } else {
2954                                elem = document.getElementById(match[2]);
2955
2956                                if (elem) {
2957
2958                                    // Inject the element directly into the jQuery object
2959                                    this[0] = elem;
2960                                    this.length = 1;
2961                                }
2962                                return this;
2963                            }
2964
2965                            // HANDLE: $(expr, $(...))
2966                        } else if (!context || context.jquery) {
2967                            return (context || root).find(selector);
2968
2969                            // HANDLE: $(expr, context)
2970                            // (which is just equivalent to: $(context).find(expr)
2971                        } else {
2972                            return this.constructor(context).find(selector);
2973                        }
2974
2975                        // HANDLE: $(DOMElement)
2976                    } else if (selector.nodeType) {
2977                        this[0] = selector;
2978                        this.length = 1;
2979                        return this;
2980
2981                        // HANDLE: $(function)
2982                        // Shortcut for document ready
2983                    } else if (isFunction(selector)) {
2984                        return root.ready !== undefined ?
2985                            root.ready(selector) :
2986
2987                            // Execute immediately if ready is not present
2988                            selector(jQuery);
2989                    }
2990
2991                    return jQuery.makeArray(selector, this);
2992                };
2993
2994            // Give the init function the jQuery prototype for later instantiation
2995            init.prototype = jQuery.fn;
2996
2997            // Initialize central reference
2998            rootjQuery = jQuery(document);
2999
3000
3001            var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3002
3003                // Methods guaranteed to produce a unique set when starting from a unique set
3004                guaranteedUnique = {
3005                    children: true,
3006                    contents: true,
3007                    next: true,
3008                    prev: true
3009                };
3010
3011            jQuery.fn.extend({
3012                has: function (target) {
3013                    var targets = jQuery(target, this),
3014                        l = targets.length;
3015
3016                    return this.filter(function () {
3017                        var i = 0;
3018                        for (; i < l; i++) {
3019                            if (jQuery.contains(this, targets[i])) {
3020                                return true;
3021                            }
3022                        }
3023                    });
3024                },
3025
3026                closest: function (selectors, context) {
3027                    var cur,
3028                        i = 0,
3029                        l = this.length,
3030                        matched = [],
3031                        targets = typeof selectors !== "string" && jQuery(selectors);
3032
3033                    // Positional selectors never match, since there's no _selection_ context
3034                    if (!rneedsContext.test(selectors)) {
3035                        for (; i < l; i++) {
3036                            for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
3037
3038                                // Always skip document fragments
3039                                if (cur.nodeType < 11 && (targets ?
3040                                    targets.index(cur) > -1 :
3041
3042                                    // Don't pass non-elements to jQuery#find
3043                                    cur.nodeType === 1 &&
3044                                    jQuery.find.matchesSelector(cur, selectors))) {
3045
3046                                    matched.push(cur);
3047                                    break;
3048                                }
3049                            }
3050                        }
3051                    }
3052
3053                    return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched);
3054                },
3055
3056                // Determine the position of an element within the set
3057                index: function (elem) {
3058
3059                    // No argument, return index in parent
3060                    if (!elem) {
3061                        return (this[0] && this[0].parentNode) ? this.first().prevAll().length : -1;
3062                    }
3063
3064                    // Index in selector
3065                    if (typeof elem === "string") {
3066                        return indexOf.call(jQuery(elem), this[0]);
3067                    }
3068
3069                    // Locate the position of the desired element
3070                    return indexOf.call(this,
3071
3072                        // If it receives a jQuery object, the first element is used
3073                        elem.jquery ? elem[0] : elem
3074                    );
3075                },
3076
3077                add: function (selector, context) {
3078                    return this.pushStack(
3079                        jQuery.uniqueSort(
3080                            jQuery.merge(this.get(), jQuery(selector, context))
3081                        )
3082                    );
3083                },
3084
3085                addBack: function (selector) {
3086                    return this.add(selector == null ?
3087                        this.prevObject : this.prevObject.filter(selector)
3088                    );
3089                }
3090            });
3091
3092            function sibling(cur, dir) {
3093                while ((cur = cur[dir]) && cur.nodeType !== 1) {
3094                }
3095                return cur;
3096            }
3097
3098            jQuery.each({
3099                parent: function (elem) {
3100                    var parent = elem.parentNode;
3101                    return parent && parent.nodeType !== 11 ? parent : null;
3102                },
3103                parents: function (elem) {
3104                    return dir(elem, "parentNode");
3105                },
3106                parentsUntil: function (elem, _i, until) {
3107                    return dir(elem, "parentNode", until);
3108                },
3109                next: function (elem) {
3110                    return sibling(elem, "nextSibling");
3111                },
3112                prev: function (elem) {
3113                    return sibling(elem, "previousSibling");
3114                },
3115                nextAll: function (elem) {
3116                    return dir(elem, "nextSibling");
3117                },
3118                prevAll: function (elem) {
3119                    return dir(elem, "previousSibling");
3120                },
3121                nextUntil: function (elem, _i, until) {
3122                    return dir(elem, "nextSibling", until);
3123                },
3124                prevUntil: function (elem, _i, until) {
3125                    return dir(elem, "previousSibling", until);
3126                },
3127                siblings: function (elem) {
3128                    return siblings((elem.parentNode || {}).firstChild, elem);
3129                },
3130                children: function (elem) {
3131                    return siblings(elem.firstChild);
3132                },
3133                contents: function (elem) {
3134                    if (elem.contentDocument != null &&
3135
3136                        // Support: IE 11+
3137                        // <object> elements with no `data` attribute has an object
3138                        // `contentDocument` with a `null` prototype.
3139                        getProto(elem.contentDocument)) {
3140
3141                        return elem.contentDocument;
3142                    }
3143
3144                    // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
3145                    // Treat the template element as a regular one in browsers that
3146                    // don't support it.
3147                    if (nodeName(elem, "template")) {
3148                        elem = elem.content || elem;
3149                    }
3150
3151                    return jQuery.merge([], elem.childNodes);
3152                }
3153            }, function (name, fn) {
3154                jQuery.fn[name] = function (until, selector) {
3155                    var matched = jQuery.map(this, fn, until);
3156
3157                    if (name.slice(-5) !== "Until") {
3158                        selector = until;
3159                    }
3160
3161                    if (selector && typeof selector === "string") {
3162                        matched = jQuery.filter(selector, matched);
3163                    }
3164
3165                    if (this.length > 1) {
3166
3167                        // Remove duplicates
3168                        if (!guaranteedUnique[name]) {
3169                            jQuery.uniqueSort(matched);
3170                        }
3171
3172                        // Reverse order for parents* and prev-derivatives
3173                        if (rparentsprev.test(name)) {
3174                            matched.reverse();
3175                        }
3176                    }
3177
3178                    return this.pushStack(matched);
3179                };
3180            });
3181            var rnothtmlwhite = (/[^\x20\t\r\n\f]+/g);
3182
3183
3184            // Convert String-formatted options into Object-formatted ones
3185            function createOptions(options) {
3186                var object = {};
3187                jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) {
3188                    object[flag] = true;
3189                });
3190                return object;
3191            }
3192
3193            /*
3194		 * Create a callback list using the following parameters:
3195		 *
3196		 *	options: an optional list of space-separated options that will change how
3197		 *			the callback list behaves or a more traditional option object
3198		 *
3199		 * By default a callback list will act like an event callback list and can be
3200		 * "fired" multiple times.
3201		 *
3202		 * Possible options:
3203		 *
3204		 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3205		 *
3206		 *	memory:			will keep track of previous values and will call any callback added
3207		 *					after the list has been fired right away with the latest "memorized"
3208		 *					values (like a Deferred)
3209		 *
3210		 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3211		 *
3212		 *	stopOnFalse:	interrupt callings when a callback returns false
3213		 *
3214		 */
3215            jQuery.Callbacks = function (options) {
3216
3217                // Convert options from String-formatted to Object-formatted if needed
3218                // (we check in cache first)
3219                options = typeof options === "string" ?
3220                    createOptions(options) :
3221                    jQuery.extend({}, options);
3222
3223                var // Flag to know if list is currently firing
3224                    firing,
3225
3226                    // Last fire value for non-forgettable lists
3227                    memory,
3228
3229                    // Flag to know if list was already fired
3230                    fired,
3231
3232                    // Flag to prevent firing
3233                    locked,
3234
3235                    // Actual callback list
3236                    list = [],
3237
3238                    // Queue of execution data for repeatable lists
3239                    queue = [],
3240
3241                    // Index of currently firing callback (modified by add/remove as needed)
3242                    firingIndex = -1,
3243
3244                    // Fire callbacks
3245                    fire = function () {
3246
3247                        // Enforce single-firing
3248                        locked = locked || options.once;
3249
3250                        // Execute callbacks for all pending executions,
3251                        // respecting firingIndex overrides and runtime changes
3252                        fired = firing = true;
3253                        for (; queue.length; firingIndex = -1) {
3254                            memory = queue.shift();
3255                            while (++firingIndex < list.length) {
3256
3257                                // Run callback and check for early termination
3258                                if (list[firingIndex].apply(memory[0], memory[1]) === false &&
3259                                    options.stopOnFalse) {
3260
3261                                    // Jump to end and forget the data so .add doesn't re-fire
3262                                    firingIndex = list.length;
3263                                    memory = false;
3264                                }
3265                            }
3266                        }
3267
3268                        // Forget the data if we're done with it
3269                        if (!options.memory) {
3270                            memory = false;
3271                        }
3272
3273                        firing = false;
3274
3275                        // Clean up if we're done firing for good
3276                        if (locked) {
3277
3278                            // Keep an empty list if we have data for future add calls
3279                            if (memory) {
3280                                list = [];
3281
3282                                // Otherwise, this object is spent
3283                            } else {
3284                                list = "";
3285                            }
3286                        }
3287                    },
3288
3289                    // Actual Callbacks object
3290                    self = {
3291
3292                        // Add a callback or a collection of callbacks to the list
3293                        add: function () {
3294                            if (list) {
3295
3296                                // If we have memory from a past run, we should fire after adding
3297                                if (memory && !firing) {
3298                                    firingIndex = list.length - 1;
3299                                    queue.push(memory);
3300                                }
3301
3302                                (function add(args) {
3303                                    jQuery.each(args, function (_, arg) {
3304                                        if (isFunction(arg)) {
3305                                            if (!options.unique || !self.has(arg)) {
3306                                                list.push(arg);
3307                                            }
3308                                        } else if (arg && arg.length && toType(arg) !== "string") {
3309
3310                                            // Inspect recursively
3311                                            add(arg);
3312                                        }
3313                                    });
3314                                })(arguments);
3315
3316                                if (memory && !firing) {
3317                                    fire();
3318                                }
3319                            }
3320                            return this;
3321                        },
3322
3323                        // Remove a callback from the list
3324                        remove: function () {
3325                            jQuery.each(arguments, function (_, arg) {
3326                                var index;
3327                                while ((index = jQuery.inArray(arg, list, index)) > -1) {
3328                                    list.splice(index, 1);
3329
3330                                    // Handle firing indexes
3331                                    if (index <= firingIndex) {
3332                                        firingIndex--;
3333                                    }
3334                                }
3335                            });
3336                            return this;
3337                        },
3338
3339                        // Check if a given callback is in the list.
3340                        // If no argument is given, return whether or not list has callbacks attached.
3341                        has: function (fn) {
3342                            return fn ?
3343                                jQuery.inArray(fn, list) > -1 :
3344                                list.length > 0;
3345                        },
3346
3347                        // Remove all callbacks from the list
3348                        empty: function () {
3349                            if (list) {
3350                                list = [];
3351                            }
3352                            return this;
3353                        },
3354
3355                        // Disable .fire and .add
3356                        // Abort any current/pending executions
3357                        // Clear all callbacks and values
3358                        disable: function () {
3359                            locked = queue = [];
3360                            list = memory = "";
3361                            return this;
3362                        },
3363                        disabled: function () {
3364                            return !list;
3365                        },
3366
3367                        // Disable .fire
3368                        // Also disable .add unless we have memory (since it would have no effect)
3369                        // Abort any pending executions
3370                        lock: function () {
3371                            locked = queue = [];
3372                            if (!memory && !firing) {
3373                                list = memory = "";
3374                            }
3375                            return this;
3376                        },
3377                        locked: function () {
3378                            return !!locked;
3379                        },
3380
3381                        // Call all callbacks with the given context and arguments
3382                        fireWith: function (context, args) {
3383                            if (!locked) {
3384                                args = args || [];
3385                                args = [context, args.slice ? args.slice() : args];
3386                                queue.push(args);
3387                                if (!firing) {
3388                                    fire();
3389                                }
3390                            }
3391                            return this;
3392                        },
3393
3394                        // Call all the callbacks with the given arguments
3395                        fire: function () {
3396                            self.fireWith(this, arguments);
3397                            return this;
3398                        },
3399
3400                        // To know if the callbacks have already been called at least once
3401                        fired: function () {
3402                            return !!fired;
3403                        }
3404                    };
3405
3406                return self;
3407            };
3408
3409
3410            function Identity(v) {
3411                return v;
3412            }
3413
3414            function Thrower(ex) {
3415                throw ex;
3416            }
3417
3418            function adoptValue(value, resolve, reject, noValue) {
3419                var method;
3420
3421                try {
3422
3423                    // Check for promise aspect first to privilege synchronous behavior
3424                    if (value && isFunction((method = value.promise))) {
3425                        method.call(value).done(resolve).fail(reject);
3426
3427                        // Other thenables
3428                    } else if (value && isFunction((method = value.then))) {
3429                        method.call(value, resolve, reject);
3430
3431                        // Other non-thenables
3432                    } else {
3433
3434                        // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
3435                        // * false: [ value ].slice( 0 ) => resolve( value )
3436                        // * true: [ value ].slice( 1 ) => resolve()
3437                        resolve.apply(undefined, [value].slice(noValue));
3438                    }
3439
3440                    // For Promises/A+, convert exceptions into rejections
3441                    // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
3442                    // Deferred#then to conditionally suppress rejection.
3443                } catch (value) {
3444
3445                    // Support: Android 4.0 only
3446                    // Strict mode functions invoked without .call/.apply get global-object context
3447                    reject.apply(undefined, [value]);
3448                }
3449            }
3450
3451            jQuery.extend({
3452
3453                Deferred: function (func) {
3454                    var tuples = [
3455
3456                            // action, add listener, callbacks,
3457                            // ... .then handlers, argument index, [final state]
3458                            ["notify", "progress", jQuery.Callbacks("memory"),
3459                                jQuery.Callbacks("memory"), 2],
3460                            ["resolve", "done", jQuery.Callbacks("once memory"),
3461                                jQuery.Callbacks("once memory"), 0, "resolved"],
3462                            ["reject", "fail", jQuery.Callbacks("once memory"),
3463                                jQuery.Callbacks("once memory"), 1, "rejected"]
3464                        ],
3465                        state = "pending",
3466                        promise = {
3467                            state: function () {
3468                                return state;
3469                            },
3470                            always: function () {
3471                                deferred.done(arguments).fail(arguments);
3472                                return this;
3473                            },
3474                            "catch": function (fn) {
3475                                return promise.then(null, fn);
3476                            },
3477
3478                            // Keep pipe for back-compat
3479                            pipe: function ( /* fnDone, fnFail, fnProgress */) {
3480                                var fns = arguments;
3481
3482                                return jQuery.Deferred(function (newDefer) {
3483                                    jQuery.each(tuples, function (_i, tuple) {
3484
3485                                        // Map tuples (progress, done, fail) to arguments (done, fail, progress)
3486                                        var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]];
3487
3488                                        // deferred.progress(function() { bind to newDefer or newDefer.notify })
3489                                        // deferred.done(function() { bind to newDefer or newDefer.resolve })
3490                                        // deferred.fail(function() { bind to newDefer or newDefer.reject })
3491                                        deferred[tuple[1]](function () {
3492                                            var returned = fn && fn.apply(this, arguments);
3493                                            if (returned && isFunction(returned.promise)) {
3494                                                returned.promise()
3495                                                    .progress(newDefer.notify)
3496                                                    .done(newDefer.resolve)
3497                                                    .fail(newDefer.reject);
3498                                            } else {
3499                                                newDefer[tuple[0] + "With"](
3500                                                    this,
3501                                                    fn ? [returned] : arguments
3502                                                );
3503                                            }
3504                                        });
3505                                    });
3506                                    fns = null;
3507                                }).promise();
3508                            },
3509                            then: function (onFulfilled, onRejected, onProgress) {
3510                                var maxDepth = 0;
3511
3512                                function resolve(depth, deferred, handler, special) {
3513                                    return function () {
3514                                        var that = this,
3515                                            args = arguments,
3516                                            mightThrow = function () {
3517                                                var returned, then;
3518
3519                                                // Support: Promises/A+ section 2.3.3.3.3
3520                                                // https://promisesaplus.com/#point-59
3521                                                // Ignore double-resolution attempts
3522                                                if (depth < maxDepth) {
3523                                                    return;
3524                                                }
3525
3526                                                returned = handler.apply(that, args);
3527
3528                                                // Support: Promises/A+ section 2.3.1
3529                                                // https://promisesaplus.com/#point-48
3530                                                if (returned === deferred.promise()) {
3531                                                    throw new TypeError("Thenable self-resolution");
3532                                                }
3533
3534                                                // Support: Promises/A+ sections 2.3.3.1, 3.5
3535                                                // https://promisesaplus.com/#point-54
3536                                                // https://promisesaplus.com/#point-75
3537                                                // Retrieve `then` only once
3538                                                then = returned &&
3539
3540                                                    // Support: Promises/A+ section 2.3.4
3541                                                    // https://promisesaplus.com/#point-64
3542                                                    // Only check objects and functions for thenability
3543                                                    (typeof returned === "object" ||
3544                                                        typeof returned === "function") &&
3545                                                    returned.then;
3546
3547                                                // Handle a returned thenable
3548                                                if (isFunction(then)) {
3549
3550                                                    // Special processors (notify) just wait for resolution
3551                                                    if (special) {
3552                                                        then.call(
3553                                                            returned,
3554                                                            resolve(maxDepth, deferred, Identity, special),
3555                                                            resolve(maxDepth, deferred, Thrower, special)
3556                                                        );
3557
3558                                                        // Normal processors (resolve) also hook into progress
3559                                                    } else {
3560
3561                                                        // ...and disregard older resolution values
3562                                                        maxDepth++;
3563
3564                                                        then.call(
3565                                                            returned,
3566                                                            resolve(maxDepth, deferred, Identity, special),
3567                                                            resolve(maxDepth, deferred, Thrower, special),
3568                                                            resolve(maxDepth, deferred, Identity,
3569                                                                deferred.notifyWith)
3570                                                        );
3571                                                    }
3572
3573                                                    // Handle all other returned values
3574                                                } else {
3575
3576                                                    // Only substitute handlers pass on context
3577                                                    // and multiple values (non-spec behavior)
3578                                                    if (handler !== Identity) {
3579                                                        that = undefined;
3580                                                        args = [returned];
3581                                                    }
3582
3583                                                    // Process the value(s)
3584                                                    // Default process is resolve
3585                                                    (special || deferred.resolveWith)(that, args);
3586                                                }
3587                                            },
3588
3589                                            // Only normal processors (resolve) catch and reject exceptions
3590                                            process = special ?
3591                                                mightThrow :
3592                                                function () {
3593                                                    try {
3594                                                        mightThrow();
3595                                                    } catch (e) {
3596
3597                                                        if (jQuery.Deferred.exceptionHook) {
3598                                                            jQuery.Deferred.exceptionHook(e,
3599                                                                process.error);
3600                                                        }
3601
3602                                                        // Support: Promises/A+ section 2.3.3.3.4.1
3603                                                        // https://promisesaplus.com/#point-61
3604                                                        // Ignore post-resolution exceptions
3605                                                        if (depth + 1 >= maxDepth) {
3606
3607                                                            // Only substitute handlers pass on context
3608                                                            // and multiple values (non-spec behavior)
3609                                                            if (handler !== Thrower) {
3610                                                                that = undefined;
3611                                                                args = [e];
3612                                                            }
3613
3614                                                            deferred.rejectWith(that, args);
3615                                                        }
3616                                                    }
3617                                                };
3618
3619                                        // Support: Promises/A+ section 2.3.3.3.1
3620                                        // https://promisesaplus.com/#point-57
3621                                        // Re-resolve promises immediately to dodge false rejection from
3622                                        // subsequent errors
3623                                        if (depth) {
3624                                            process();
3625                                        } else {
3626
3627                                            // Call an optional hook to record the error, in case of exception
3628                                            // since it's otherwise lost when execution goes async
3629                                            if (jQuery.Deferred.getErrorHook) {
3630                                                process.error = jQuery.Deferred.getErrorHook();
3631
3632                                                // The deprecated alias of the above. While the name suggests
3633                                                // returning the stack, not an error instance, jQuery just passes
3634                                                // it directly to `console.warn` so both will work; an instance
3635                                                // just better cooperates with source maps.
3636                                            } else if (jQuery.Deferred.getStackHook) {
3637                                                process.error = jQuery.Deferred.getStackHook();
3638                                            }
3639                                            window.setTimeout(process);
3640                                        }
3641                                    };
3642                                }
3643
3644                                return jQuery.Deferred(function (newDefer) {
3645
3646                                    // progress_handlers.add( ... )
3647                                    tuples[0][3].add(
3648                                        resolve(
3649                                            0,
3650                                            newDefer,
3651                                            isFunction(onProgress) ?
3652                                                onProgress :
3653                                                Identity,
3654                                            newDefer.notifyWith
3655                                        )
3656                                    );
3657
3658                                    // fulfilled_handlers.add( ... )
3659                                    tuples[1][3].add(
3660                                        resolve(
3661                                            0,
3662                                            newDefer,
3663                                            isFunction(onFulfilled) ?
3664                                                onFulfilled :
3665                                                Identity
3666                                        )
3667                                    );
3668
3669                                    // rejected_handlers.add( ... )
3670                                    tuples[2][3].add(
3671                                        resolve(
3672                                            0,
3673                                            newDefer,
3674                                            isFunction(onRejected) ?
3675                                                onRejected :
3676                                                Thrower
3677                                        )
3678                                    );
3679                                }).promise();
3680                            },
3681
3682                            // Get a promise for this deferred
3683                            // If obj is provided, the promise aspect is added to the object
3684                            promise: function (obj) {
3685                                return obj != null ? jQuery.extend(obj, promise) : promise;
3686                            }
3687                        },
3688                        deferred = {};
3689
3690                    // Add list-specific methods
3691                    jQuery.each(tuples, function (i, tuple) {
3692                        var list = tuple[2],
3693                            stateString = tuple[5];
3694
3695                        // promise.progress = list.add
3696                        // promise.done = list.add
3697                        // promise.fail = list.add
3698                        promise[tuple[1]] = list.add;
3699
3700                        // Handle state
3701                        if (stateString) {
3702                            list.add(
3703                                function () {
3704
3705                                    // state = "resolved" (i.e., fulfilled)
3706                                    // state = "rejected"
3707                                    state = stateString;
3708                                },
3709
3710                                // rejected_callbacks.disable
3711                                // fulfilled_callbacks.disable
3712                                tuples[3 - i][2].disable,
3713
3714                                // rejected_handlers.disable
3715                                // fulfilled_handlers.disable
3716                                tuples[3 - i][3].disable,
3717
3718                                // progress_callbacks.lock
3719                                tuples[0][2].lock,
3720
3721                                // progress_handlers.lock
3722                                tuples[0][3].lock
3723                            );
3724                        }
3725
3726                        // progress_handlers.fire
3727                        // fulfilled_handlers.fire
3728                        // rejected_handlers.fire
3729                        list.add(tuple[3].fire);
3730
3731                        // deferred.notify = function() { deferred.notifyWith(...) }
3732                        // deferred.resolve = function() { deferred.resolveWith(...) }
3733                        // deferred.reject = function() { deferred.rejectWith(...) }
3734                        deferred[tuple[0]] = function () {
3735                            deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments);
3736                            return this;
3737                        };
3738
3739                        // deferred.notifyWith = list.fireWith
3740                        // deferred.resolveWith = list.fireWith
3741                        // deferred.rejectWith = list.fireWith
3742                        deferred[tuple[0] + "With"] = list.fireWith;
3743                    });
3744
3745                    // Make the deferred a promise
3746                    promise.promise(deferred);
3747
3748                    // Call given func if any
3749                    if (func) {
3750                        func.call(deferred, deferred);
3751                    }
3752
3753                    // All done!
3754                    return deferred;
3755                },
3756
3757                // Deferred helper
3758                when: function (singleValue) {
3759                    var
3760
3761                        // count of uncompleted subordinates
3762                        remaining = arguments.length,
3763
3764                        // count of unprocessed arguments
3765                        i = remaining,
3766
3767                        // subordinate fulfillment data
3768                        resolveContexts = Array(i),
3769                        resolveValues = slice.call(arguments),
3770
3771                        // the primary Deferred
3772                        primary = jQuery.Deferred(),
3773
3774                        // subordinate callback factory
3775                        updateFunc = function (i) {
3776                            return function (value) {
3777                                resolveContexts[i] = this;
3778                                resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value;
3779                                if (!(--remaining)) {
3780                                    primary.resolveWith(resolveContexts, resolveValues);
3781                                }
3782                            };
3783                        };
3784
3785                    // Single- and empty arguments are adopted like Promise.resolve
3786                    if (remaining <= 1) {
3787                        adoptValue(singleValue, primary.done(updateFunc(i)).resolve, primary.reject,
3788                            !remaining);
3789
3790                        // Use .then() to unwrap secondary thenables (cf. gh-3000)
3791                        if (primary.state() === "pending" ||
3792                            isFunction(resolveValues[i] && resolveValues[i].then)) {
3793
3794                            return primary.then();
3795                        }
3796                    }
3797
3798                    // Multiple arguments are aggregated like Promise.all array elements
3799                    while (i--) {
3800                        adoptValue(resolveValues[i], updateFunc(i), primary.reject);
3801                    }
3802
3803                    return primary.promise();
3804                }
3805            });
3806
3807
3808            // These usually indicate a programmer mistake during development,
3809            // warn about them ASAP rather than swallowing them by default.
3810            var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
3811
3812            // If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error
3813            // captured before the async barrier to get the original error cause
3814            // which may otherwise be hidden.
3815            jQuery.Deferred.exceptionHook = function (error, asyncError) {
3816
3817                // Support: IE 8 - 9 only
3818                // Console exists when dev tools are open, which can happen at any time
3819                if (window.console && window.console.warn && error && rerrorNames.test(error.name)) {
3820                    window.console.warn("jQuery.Deferred exception: " + error.message,
3821                        error.stack, asyncError);
3822                }
3823            };
3824
3825
3826            jQuery.readyException = function (error) {
3827                window.setTimeout(function () {
3828                    throw error;
3829                });
3830            };
3831
3832
3833            // The deferred used on DOM ready
3834            var readyList = jQuery.Deferred();
3835
3836            jQuery.fn.ready = function (fn) {
3837
3838                readyList
3839                    .then(fn)
3840
3841                    // Wrap jQuery.readyException in a function so that the lookup
3842                    // happens at the time of error handling instead of callback
3843                    // registration.
3844                    .catch(function (error) {
3845                        jQuery.readyException(error);
3846                    });
3847
3848                return this;
3849            };
3850
3851            jQuery.extend({
3852
3853                // Is the DOM ready to be used? Set to true once it occurs.
3854                isReady: false,
3855
3856                // A counter to track how many items to wait for before
3857                // the ready event fires. See trac-6781
3858                readyWait: 1,
3859
3860                // Handle when the DOM is ready
3861                ready: function (wait) {
3862
3863                    // Abort if there are pending holds or we're already ready
3864                    if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
3865                        return;
3866                    }
3867
3868                    // Remember that the DOM is ready
3869                    jQuery.isReady = true;
3870
3871                    // If a normal DOM Ready event fired, decrement, and wait if need be
3872                    if (wait !== true && --jQuery.readyWait > 0) {
3873                        return;
3874                    }
3875
3876                    // If there are functions bound, to execute
3877                    readyList.resolveWith(document, [jQuery]);
3878                }
3879            });
3880
3881            jQuery.ready.then = readyList.then;
3882
3883            // The ready event handler and self cleanup method
3884            function completed() {
3885                document.removeEventListener("DOMContentLoaded", completed);
3886                window.removeEventListener("load", completed);
3887                jQuery.ready();
3888            }
3889
3890            // Catch cases where $(document).ready() is called
3891            // after the browser event has already occurred.
3892            // Support: IE <=9 - 10 only
3893            // Older IE sometimes signals "interactive" too soon
3894            if (document.readyState === "complete" ||
3895                (document.readyState !== "loading" && !document.documentElement.doScroll)) {
3896
3897                // Handle it asynchronously to allow scripts the opportunity to delay ready
3898                window.setTimeout(jQuery.ready);
3899
3900            } else {
3901
3902                // Use the handy event callback
3903                document.addEventListener("DOMContentLoaded", completed);
3904
3905                // A fallback to window.onload, that will always work
3906                window.addEventListener("load", completed);
3907            }
3908
3909
3910            // Multifunctional method to get and set values of a collection
3911            // The value/s can optionally be executed if it's a function
3912            var access = function (elems, fn, key, value, chainable, emptyGet, raw) {
3913                var i = 0,
3914                    len = elems.length,
3915                    bulk = key == null;
3916
3917                // Sets many values
3918                if (toType(key) === "object") {
3919                    chainable = true;
3920                    for (i in key) {
3921                        access(elems, fn, i, key[i], true, emptyGet, raw);
3922                    }
3923
3924                    // Sets one value
3925                } else if (value !== undefined) {
3926                    chainable = true;
3927
3928                    if (!isFunction(value)) {
3929                        raw = true;
3930                    }
3931
3932                    if (bulk) {
3933
3934                        // Bulk operations run against the entire set
3935                        if (raw) {
3936                            fn.call(elems, value);
3937                            fn = null;
3938
3939                            // ...except when executing function values
3940                        } else {
3941                            bulk = fn;
3942                            fn = function (elem, _key, value) {
3943                                return bulk.call(jQuery(elem), value);
3944                            };
3945                        }
3946                    }
3947
3948                    if (fn) {
3949                        for (; i < len; i++) {
3950                            fn(
3951                                elems[i], key, raw ?
3952                                    value :
3953                                    value.call(elems[i], i, fn(elems[i], key))
3954                            );
3955                        }
3956                    }
3957                }
3958
3959                if (chainable) {
3960                    return elems;
3961                }
3962
3963                // Gets
3964                if (bulk) {
3965                    return fn.call(elems);
3966                }
3967
3968                return len ? fn(elems[0], key) : emptyGet;
3969            };
3970
3971
3972            // Matches dashed string for camelizing
3973            var rmsPrefix = /^-ms-/,
3974                rdashAlpha = /-([a-z])/g;
3975
3976            // Used by camelCase as callback to replace()
3977            function fcamelCase(_all, letter) {
3978                return letter.toUpperCase();
3979            }
3980
3981            // Convert dashed to camelCase; used by the css and data modules
3982            // Support: IE <=9 - 11, Edge 12 - 15
3983            // Microsoft forgot to hump their vendor prefix (trac-9572)
3984            function camelCase(string) {
3985                return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
3986            }
3987
3988            var acceptData = function (owner) {
3989
3990                // Accepts only:
3991                //  - Node
3992                //    - Node.ELEMENT_NODE
3993                //    - Node.DOCUMENT_NODE
3994                //  - Object
3995                //    - Any
3996                return owner.nodeType === 1 || owner.nodeType === 9 || !(+owner.nodeType);
3997            };
3998
3999
4000            function Data() {
4001                this.expando = jQuery.expando + Data.uid++;
4002            }
4003
4004            Data.uid = 1;
4005
4006            Data.prototype = {
4007
4008                cache: function (owner) {
4009
4010                    // Check if the owner object already has a cache
4011                    var value = owner[this.expando];
4012
4013                    // If not, create one
4014                    if (!value) {
4015                        value = {};
4016
4017                        // We can accept data for non-element nodes in modern browsers,
4018                        // but we should not, see trac-8335.
4019                        // Always return an empty object.
4020                        if (acceptData(owner)) {
4021
4022                            // If it is a node unlikely to be stringify-ed or looped over
4023                            // use plain assignment
4024                            if (owner.nodeType) {
4025                                owner[this.expando] = value;
4026
4027                                // Otherwise secure it in a non-enumerable property
4028                                // configurable must be true to allow the property to be
4029                                // deleted when data is removed
4030                            } else {
4031                                Object.defineProperty(owner, this.expando, {
4032                                    value: value,
4033                                    configurable: true
4034                                });
4035                            }
4036                        }
4037                    }
4038
4039                    return value;
4040                },
4041                set: function (owner, data, value) {
4042                    var prop,
4043                        cache = this.cache(owner);
4044
4045                    // Handle: [ owner, key, value ] args
4046                    // Always use camelCase key (gh-2257)
4047                    if (typeof data === "string") {
4048                        cache[camelCase(data)] = value;
4049
4050                        // Handle: [ owner, { properties } ] args
4051                    } else {
4052
4053                        // Copy the properties one-by-one to the cache object
4054                        for (prop in data) {
4055                            cache[camelCase(prop)] = data[prop];
4056                        }
4057                    }
4058                    return cache;
4059                },
4060                get: function (owner, key) {
4061                    return key === undefined ?
4062                        this.cache(owner) :
4063
4064                        // Always use camelCase key (gh-2257)
4065                        owner[this.expando] && owner[this.expando][camelCase(key)];
4066                },
4067                access: function (owner, key, value) {
4068
4069                    // In cases where either:
4070                    //
4071                    //   1. No key was specified
vendor: 8,807 bytes, lines 4072-4290
4072                    //   2. A string key was specified, but no value provided
4073                    //
4074                    // Take the "read" path and allow the get method to determine
4075                    // which value to return, respectively either:
4076                    //
4077                    //   1. The entire cache object
4078                    //   2. The data stored at the key
4079                    //
4080                    if (key === undefined ||
4081                        ((key && typeof key === "string") && value === undefined)) {
4082
4083                        return this.get(owner, key);
4084                    }
4085
4086                    // When the key is not a string, or both a key and value
4087                    // are specified, set or extend (existing objects) with either:
4088                    //
4089                    //   1. An object of properties
4090                    //   2. A key and value
4091                    //
4092                    this.set(owner, key, value);
4093
4094                    // Since the "set" path can have two possible entry points
4095                    // return the expected data based on which path was taken[*]
4096                    return value !== undefined ? value : key;
4097                },
4098                remove: function (owner, key) {
4099                    var i,
4100                        cache = owner[this.expando];
4101
4102                    if (cache === undefined) {
4103                        return;
4104                    }
4105
4106                    if (key !== undefined) {
4107
4108                        // Support array or space separated string of keys
4109                        if (Array.isArray(key)) {
4110
4111                            // If key is an array of keys...
4112                            // We always set camelCase keys, so remove that.
4113                            key = key.map(camelCase);
4114                        } else {
4115                            key = camelCase(key);
4116
4117                            // If a key with the spaces exists, use it.
4118                            // Otherwise, create an array by matching non-whitespace
4119                            key = key in cache ?
4120                                [key] :
4121                                (key.match(rnothtmlwhite) || []);
4122                        }
4123
4124                        i = key.length;
4125
4126                        while (i--) {
4127                            delete cache[key[i]];
4128                        }
4129                    }
4130
4131                    // Remove the expando if there's no more data
4132                    if (key === undefined || jQuery.isEmptyObject(cache)) {
4133
4134                        // Support: Chrome <=35 - 45
4135                        // Webkit & Blink performance suffers when deleting properties
4136                        // from DOM nodes, so set to undefined instead
4137                        // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4138                        if (owner.nodeType) {
4139                            owner[this.expando] = undefined;
4140                        } else {
4141                            delete owner[this.expando];
4142                        }
4143                    }
4144                },
4145                hasData: function (owner) {
4146                    var cache = owner[this.expando];
4147                    return cache !== undefined && !jQuery.isEmptyObject(cache);
4148                }
4149            };
4150            var dataPriv = new Data();
4151
4152            var dataUser = new Data();
4153
4154
4155            //	Implementation Summary
4156            //
4157            //	1. Enforce API surface and semantic compatibility with 1.9.x branch
4158            //	2. Improve the module's maintainability by reducing the storage
4159            //		paths to a single mechanism.
4160            //	3. Use the same single mechanism to support "private" and "user" data.
4161            //	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4162            //	5. Avoid exposing implementation details on user objects (eg. expando properties)
4163            //	6. Provide a clear path for implementation upgrade to WeakMap in 2014
4164
4165            var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4166                rmultiDash = /[A-Z]/g;
4167
4168            function getData(data) {
4169                if (data === "true") {
4170                    return true;
4171                }
4172
4173                if (data === "false") {
4174                    return false;
4175                }
4176
4177                if (data === "null") {
4178                    return null;
4179                }
4180
4181                // Only convert to a number if it doesn't change the string
4182                if (data === +data + "") {
4183                    return +data;
4184                }
4185
4186                if (rbrace.test(data)) {
4187                    return JSON.parse(data);
4188                }
4189
4190                return data;
4191            }
4192
4193            function dataAttr(elem, key, data) {
4194                var name;
4195
4196                // If nothing was found internally, try to fetch any
4197                // data from the HTML5 data-* attribute
4198                if (data === undefined && elem.nodeType === 1) {
4199                    name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase();
4200                    data = elem.getAttribute(name);
4201
4202                    if (typeof data === "string") {
4203                        try {
4204                            data = getData(data);
4205                        } catch (e) {
4206                        }
4207
4208                        // Make sure we set the data so it isn't changed later
4209                        dataUser.set(elem, key, data);
4210                    } else {
4211                        data = undefined;
4212                    }
4213                }
4214                return data;
4215            }
4216
4217            jQuery.extend({
4218                hasData: function (elem) {
4219                    return dataUser.hasData(elem) || dataPriv.hasData(elem);
4220                },
4221
4222                data: function (elem, name, data) {
4223                    return dataUser.access(elem, name, data);
4224                },
4225
4226                removeData: function (elem, name) {
4227                    dataUser.remove(elem, name);
4228                },
4229
4230                // TODO: Now that all calls to _data and _removeData have been replaced
4231                // with direct calls to dataPriv methods, these can be deprecated.
4232                _data: function (elem, name, data) {
4233                    return dataPriv.access(elem, name, data);
4234                },
4235
4236                _removeData: function (elem, name) {
4237                    dataPriv.remove(elem, name);
4238                }
4239            });
4240
4241            jQuery.fn.extend({
4242                data: function (key, value) {
4243                    var i, name, data,
4244                        elem = this[0],
4245                        attrs = elem && elem.attributes;
4246
4247                    // Gets all values
4248                    if (key === undefined) {
4249                        if (this.length) {
4250                            data = dataUser.get(elem);
4251
4252                            if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) {
4253                                i = attrs.length;
4254                                while (i--) {
4255
4256                                    // Support: IE 11 only
4257                                    // The attrs elements can be null (trac-14894)
4258                                    if (attrs[i]) {
4259                                        name = attrs[i].name;
4260                                        if (name.indexOf("data-") === 0) {
4261                                            name = camelCase(name.slice(5));
4262                                            dataAttr(elem, name, data[name]);
4263                                        }
4264                                    }
4265                                }
4266                                dataPriv.set(elem, "hasDataAttrs", true);
4267                            }
4268                        }
4269
4270                        return data;
4271                    }
4272
4273                    // Sets multiple values
4274                    if (typeof key === "object") {
4275                        return this.each(function () {
4276                            dataUser.set(this, key);
4277                        });
4278                    }
4279
4280                    return access(this, function (value) {
4281                        var data;
4282
4283                        // The calling jQuery object (element matches) is not empty
4284                        // (and therefore has an element appears at this[ 0 ]) and the
4285                        // `value` parameter was not undefined. An empty jQuery object
4286                        // will result in `undefined` for elem = this[ 0 ] which will
4287                        // throw an exception if an attempt to read a data cache is made.
4288                        if (elem && value === undefined) {
4289
4290                            // Attempt to get data from the cache
vendor: 30,306 bytes, lines 4291-5061
4291                            // The key will always be camelCased in Data
4292                            data = dataUser.get(elem, key);
4293                            if (data !== undefined) {
4294                                return data;
4295                            }
4296
4297                            // Attempt to "discover" the data in
4298                            // HTML5 custom data-* attrs
4299                            data = dataAttr(elem, key);
4300                            if (data !== undefined) {
4301                                return data;
4302                            }
4303
4304                            // We tried really hard, but the data doesn't exist.
4305                            return;
4306                        }
4307
4308                        // Set the data...
4309                        this.each(function () {
4310
4311                            // We always store the camelCased key
4312                            dataUser.set(this, key, value);
4313                        });
4314                    }, null, value, arguments.length > 1, null, true);
4315                },
4316
4317                removeData: function (key) {
4318                    return this.each(function () {
4319                        dataUser.remove(this, key);
4320                    });
4321                }
4322            });
4323
4324
4325            jQuery.extend({
4326                queue: function (elem, type, data) {
4327                    var queue;
4328
4329                    if (elem) {
4330                        type = (type || "fx") + "queue";
4331                        queue = dataPriv.get(elem, type);
4332
4333                        // Speed up dequeue by getting out quickly if this is just a lookup
4334                        if (data) {
4335                            if (!queue || Array.isArray(data)) {
4336                                queue = dataPriv.access(elem, type, jQuery.makeArray(data));
4337                            } else {
4338                                queue.push(data);
4339                            }
4340                        }
4341                        return queue || [];
4342                    }
4343                },
4344
4345                dequeue: function (elem, type) {
4346                    type = type || "fx";
4347
4348                    var queue = jQuery.queue(elem, type),
4349                        startLength = queue.length,
4350                        fn = queue.shift(),
4351                        hooks = jQuery._queueHooks(elem, type),
4352                        next = function () {
4353                            jQuery.dequeue(elem, type);
4354                        };
4355
4356                    // If the fx queue is dequeued, always remove the progress sentinel
4357                    if (fn === "inprogress") {
4358                        fn = queue.shift();
4359                        startLength--;
4360                    }
4361
4362                    if (fn) {
4363
4364                        // Add a progress sentinel to prevent the fx queue from being
4365                        // automatically dequeued
4366                        if (type === "fx") {
4367                            queue.unshift("inprogress");
4368                        }
4369
4370                        // Clear up the last queue stop function
4371                        delete hooks.stop;
4372                        fn.call(elem, next, hooks);
4373                    }
4374
4375                    if (!startLength && hooks) {
4376                        hooks.empty.fire();
4377                    }
4378                },
4379
4380                // Not public - generate a queueHooks object, or return the current one
4381                _queueHooks: function (elem, type) {
4382                    var key = type + "queueHooks";
4383                    return dataPriv.get(elem, key) || dataPriv.access(elem, key, {
4384                        empty: jQuery.Callbacks("once memory").add(function () {
4385                            dataPriv.remove(elem, [type + "queue", key]);
4386                        })
4387                    });
4388                }
4389            });
4390
4391            jQuery.fn.extend({
4392                queue: function (type, data) {
4393                    var setter = 2;
4394
4395                    if (typeof type !== "string") {
4396                        data = type;
4397                        type = "fx";
4398                        setter--;
4399                    }
4400
4401                    if (arguments.length < setter) {
4402                        return jQuery.queue(this[0], type);
4403                    }
4404
4405                    return data === undefined ?
4406                        this :
4407                        this.each(function () {
4408                            var queue = jQuery.queue(this, type, data);
4409
4410                            // Ensure a hooks for this queue
4411                            jQuery._queueHooks(this, type);
4412
4413                            if (type === "fx" && queue[0] !== "inprogress") {
4414                                jQuery.dequeue(this, type);
4415                            }
4416                        });
4417                },
4418                dequeue: function (type) {
4419                    return this.each(function () {
4420                        jQuery.dequeue(this, type);
4421                    });
4422                },
4423                clearQueue: function (type) {
4424                    return this.queue(type || "fx", []);
4425                },
4426
4427                // Get a promise resolved when queues of a certain type
4428                // are emptied (fx is the type by default)
4429                promise: function (type, obj) {
4430                    var tmp,
4431                        count = 1,
4432                        defer = jQuery.Deferred(),
4433                        elements = this,
4434                        i = this.length,
4435                        resolve = function () {
4436                            if (!(--count)) {
4437                                defer.resolveWith(elements, [elements]);
4438                            }
4439                        };
4440
4441                    if (typeof type !== "string") {
4442                        obj = type;
4443                        type = undefined;
4444                    }
4445                    type = type || "fx";
4446
4447                    while (i--) {
4448                        tmp = dataPriv.get(elements[i], type + "queueHooks");
4449                        if (tmp && tmp.empty) {
4450                            count++;
4451                            tmp.empty.add(resolve);
4452                        }
4453                    }
4454                    resolve();
4455                    return defer.promise(obj);
4456                }
4457            });
4458            var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
4459
4460            var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i");
4461
4462
4463            var cssExpand = ["Top", "Right", "Bottom", "Left"];
4464
4465            var documentElement = document.documentElement;
4466
4467
4468            var isAttached = function (elem) {
4469                    return jQuery.contains(elem.ownerDocument, elem);
4470                },
4471                composed = {composed: true};
4472
4473            // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
4474            // Check attachment across shadow DOM boundaries when possible (gh-3504)
4475            // Support: iOS 10.0-10.2 only
4476            // Early iOS 10 versions support `attachShadow` but not `getRootNode`,
4477            // leading to errors. We need to check for `getRootNode`.
4478            if (documentElement.getRootNode) {
4479                isAttached = function (elem) {
4480                    return jQuery.contains(elem.ownerDocument, elem) ||
4481                        elem.getRootNode(composed) === elem.ownerDocument;
4482                };
4483            }
4484            var isHiddenWithinTree = function (elem, el) {
4485
4486                // isHiddenWithinTree might be called from jQuery#filter function;
4487                // in that case, element will be second argument
4488                elem = el || elem;
4489
4490                // Inline style trumps all
4491                return elem.style.display === "none" ||
4492                    elem.style.display === "" &&
4493
4494                    // Otherwise, check computed style
4495                    // Support: Firefox <=43 - 45
4496                    // Disconnected elements can have computed display: none, so first confirm that elem is
4497                    // in the document.
4498                    isAttached(elem) &&
4499
4500                    jQuery.css(elem, "display") === "none";
4501            };
4502
4503
4504            function adjustCSS(elem, prop, valueParts, tween) {
4505                var adjusted, scale,
4506                    maxIterations = 20,
4507                    currentValue = tween ?
4508                        function () {
4509                            return tween.cur();
4510                        } :
4511                        function () {
4512                            return jQuery.css(elem, prop, "");
4513                        },
4514                    initial = currentValue(),
4515                    unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"),
4516
4517                    // Starting value computation is required for potential unit mismatches
4518                    initialInUnit = elem.nodeType &&
4519                        (jQuery.cssNumber[prop] || unit !== "px" && +initial) &&
4520                        rcssNum.exec(jQuery.css(elem, prop));
4521
4522                if (initialInUnit && initialInUnit[3] !== unit) {
4523
4524                    // Support: Firefox <=54
4525                    // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
4526                    initial = initial / 2;
4527
4528                    // Trust units reported by jQuery.css
4529                    unit = unit || initialInUnit[3];
4530
4531                    // Iteratively approximate from a nonzero starting point
4532                    initialInUnit = +initial || 1;
4533
4534                    while (maxIterations--) {
4535
4536                        // Evaluate and update our best guess (doubling guesses that zero out).
4537                        // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
4538                        jQuery.style(elem, prop, initialInUnit + unit);
4539                        if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) {
4540                            maxIterations = 0;
4541                        }
4542                        initialInUnit = initialInUnit / scale;
4543
4544                    }
4545
4546                    initialInUnit = initialInUnit * 2;
4547                    jQuery.style(elem, prop, initialInUnit + unit);
4548
4549                    // Make sure we update the tween properties later on
4550                    valueParts = valueParts || [];
4551                }
4552
4553                if (valueParts) {
4554                    initialInUnit = +initialInUnit || +initial || 0;
4555
4556                    // Apply relative offset (+=/-=) if specified
4557                    adjusted = valueParts[1] ?
4558                        initialInUnit + (valueParts[1] + 1) * valueParts[2] :
4559                        +valueParts[2];
4560                    if (tween) {
4561                        tween.unit = unit;
4562                        tween.start = initialInUnit;
4563                        tween.end = adjusted;
4564                    }
4565                }
4566                return adjusted;
4567            }
4568
4569
4570            var defaultDisplayMap = {};
4571
4572            function getDefaultDisplay(elem) {
4573                var temp,
4574                    doc = elem.ownerDocument,
4575                    nodeName = elem.nodeName,
4576                    display = defaultDisplayMap[nodeName];
4577
4578                if (display) {
4579                    return display;
4580                }
4581
4582                temp = doc.body.appendChild(doc.createElement(nodeName));
4583                display = jQuery.css(temp, "display");
4584
4585                temp.parentNode.removeChild(temp);
4586
4587                if (display === "none") {
4588                    display = "block";
4589                }
4590                defaultDisplayMap[nodeName] = display;
4591
4592                return display;
4593            }
4594
4595            function showHide(elements, show) {
4596                var display, elem,
4597                    values = [],
4598                    index = 0,
4599                    length = elements.length;
4600
4601                // Determine new display value for elements that need to change
4602                for (; index < length; index++) {
4603                    elem = elements[index];
4604                    if (!elem.style) {
4605                        continue;
4606                    }
4607
4608                    display = elem.style.display;
4609                    if (show) {
4610
4611                        // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
4612                        // check is required in this first loop unless we have a nonempty display value (either
4613                        // inline or about-to-be-restored)
4614                        if (display === "none") {
4615                            values[index] = dataPriv.get(elem, "display") || null;
4616                            if (!values[index]) {
4617                                elem.style.display = "";
4618                            }
4619                        }
4620                        if (elem.style.display === "" && isHiddenWithinTree(elem)) {
4621                            values[index] = getDefaultDisplay(elem);
4622                        }
4623                    } else {
4624                        if (display !== "none") {
4625                            values[index] = "none";
4626
4627                            // Remember what we're overwriting
4628                            dataPriv.set(elem, "display", display);
4629                        }
4630                    }
4631                }
4632
4633                // Set the display of the elements in a second loop to avoid constant reflow
4634                for (index = 0; index < length; index++) {
4635                    if (values[index] != null) {
4636                        elements[index].style.display = values[index];
4637                    }
4638                }
4639
4640                return elements;
4641            }
4642
4643            jQuery.fn.extend({
4644                show: function () {
4645                    return showHide(this, true);
4646                },
4647                hide: function () {
4648                    return showHide(this);
4649                },
4650                toggle: function (state) {
4651                    if (typeof state === "boolean") {
4652                        return state ? this.show() : this.hide();
4653                    }
4654
4655                    return this.each(function () {
4656                        if (isHiddenWithinTree(this)) {
4657                            jQuery(this).show();
4658                        } else {
4659                            jQuery(this).hide();
4660                        }
4661                    });
4662                }
4663            });
4664            var rcheckableType = (/^(?:checkbox|radio)$/i);
4665
4666            var rtagName = (/<([a-z][^\/\0>\x20\t\r\n\f]*)/i);
4667
4668            var rscriptType = (/^$|^module$|\/(?:java|ecma)script/i);
4669
4670
4671            (function () {
4672                var fragment = document.createDocumentFragment(),
4673                    div = fragment.appendChild(document.createElement("div")),
4674                    input = document.createElement("input");
4675
4676                // Support: Android 4.0 - 4.3 only
4677                // Check state lost if the name is set (trac-11217)
4678                // Support: Windows Web Apps (WWA)
4679                // `name` and `type` must use .setAttribute for WWA (trac-14901)
4680                input.setAttribute("type", "radio");
4681                input.setAttribute("checked", "checked");
4682                input.setAttribute("name", "t");
4683
4684                div.appendChild(input);
4685
4686                // Support: Android <=4.1 only
4687                // Older WebKit doesn't clone checked state correctly in fragments
4688                support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked;
4689
4690                // Support: IE <=11 only
4691                // Make sure textarea (and checkbox) defaultValue is properly cloned
4692                div.innerHTML = "<textarea>x</textarea>";
4693                support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;
4694
4695                // Support: IE <=9 only
4696                // IE <=9 replaces <option> tags with their contents when inserted outside of
4697                // the select element.
4698                div.innerHTML = "<option></option>";
4699                support.option = !!div.lastChild;
4700            })();
4701
4702
4703            // We have to close these tags to support XHTML (trac-13200)
4704            var wrapMap = {
4705
4706                // XHTML parsers do not magically insert elements in the
4707                // same way that tag soup parsers do. So we cannot shorten
4708                // this by omitting <tbody> or other required elements.
4709                thead: [1, "<table>", "</table>"],
4710                col: [2, "<table><colgroup>", "</colgroup></table>"],
4711                tr: [2, "<table><tbody>", "</tbody></table>"],
4712                td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
4713
4714                _default: [0, "", ""]
4715            };
4716
4717            wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4718            wrapMap.th = wrapMap.td;
4719
4720            // Support: IE <=9 only
4721            if (!support.option) {
4722                wrapMap.optgroup = wrapMap.option = [1, "<select multiple='multiple'>", "</select>"];
4723            }
4724
4725
4726            function getAll(context, tag) {
4727
4728                // Support: IE <=9 - 11 only
4729                // Use typeof to avoid zero-argument method invocation on host objects (trac-15151)
4730                var ret;
4731
4732                if (typeof context.getElementsByTagName !== "undefined") {
4733                    ret = context.getElementsByTagName(tag || "*");
4734
4735                } else if (typeof context.querySelectorAll !== "undefined") {
4736                    ret = context.querySelectorAll(tag || "*");
4737
4738                } else {
4739                    ret = [];
4740                }
4741
4742                if (tag === undefined || tag && nodeName(context, tag)) {
4743                    return jQuery.merge([context], ret);
4744                }
4745
4746                return ret;
4747            }
4748
4749
4750            // Mark scripts as having already been evaluated
4751            function setGlobalEval(elems, refElements) {
4752                var i = 0,
4753                    l = elems.length;
4754
4755                for (; i < l; i++) {
4756                    dataPriv.set(
4757                        elems[i],
4758                        "globalEval",
4759                        !refElements || dataPriv.get(refElements[i], "globalEval")
4760                    );
4761                }
4762            }
4763
4764
4765            var rhtml = /<|&#?\w+;/;
4766
4767            function buildFragment(elems, context, scripts, selection, ignored) {
4768                var elem, tmp, tag, wrap, attached, j,
4769                    fragment = context.createDocumentFragment(),
4770                    nodes = [],
4771                    i = 0,
4772                    l = elems.length;
4773
4774                for (; i < l; i++) {
4775                    elem = elems[i];
4776
4777                    if (elem || elem === 0) {
4778
4779                        // Add nodes directly
4780                        if (toType(elem) === "object") {
4781
4782                            // Support: Android <=4.0 only, PhantomJS 1 only
4783                            // push.apply(_, arraylike) throws on ancient WebKit
4784                            jQuery.merge(nodes, elem.nodeType ? [elem] : elem);
4785
4786                            // Convert non-html into a text node
4787                        } else if (!rhtml.test(elem)) {
4788                            nodes.push(context.createTextNode(elem));
4789
4790                            // Convert html into DOM nodes
4791                        } else {
4792                            tmp = tmp || fragment.appendChild(context.createElement("div"));
4793
4794                            // Deserialize a standard representation
4795                            tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
4796                            wrap = wrapMap[tag] || wrapMap._default;
4797                            tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2];
4798
4799                            // Descend through wrappers to the right content
4800                            j = wrap[0];
4801                            while (j--) {
4802                                tmp = tmp.lastChild;
4803                            }
4804
4805                            // Support: Android <=4.0 only, PhantomJS 1 only
4806                            // push.apply(_, arraylike) throws on ancient WebKit
4807                            jQuery.merge(nodes, tmp.childNodes);
4808
4809                            // Remember the top-level container
4810                            tmp = fragment.firstChild;
4811
4812                            // Ensure the created nodes are orphaned (trac-12392)
4813                            tmp.textContent = "";
4814                        }
4815                    }
4816                }
4817
4818                // Remove wrapper from fragment
4819                fragment.textContent = "";
4820
4821                i = 0;
4822                while ((elem = nodes[i++])) {
4823
4824                    // Skip elements already in the context collection (trac-4087)
4825                    if (selection && jQuery.inArray(elem, selection) > -1) {
4826                        if (ignored) {
4827                            ignored.push(elem);
4828                        }
4829                        continue;
4830                    }
4831
4832                    attached = isAttached(elem);
4833
4834                    // Append to fragment
4835                    tmp = getAll(fragment.appendChild(elem), "script");
4836
4837                    // Preserve script evaluation history
4838                    if (attached) {
4839                        setGlobalEval(tmp);
4840                    }
4841
4842                    // Capture executables
4843                    if (scripts) {
4844                        j = 0;
4845                        while ((elem = tmp[j++])) {
4846                            if (rscriptType.test(elem.type || "")) {
4847                                scripts.push(elem);
4848                            }
4849                        }
4850                    }
4851                }
4852
4853                return fragment;
4854            }
4855
4856
4857            var rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4858
4859            function returnTrue() {
4860                return true;
4861            }
4862
4863            function returnFalse() {
4864                return false;
4865            }
4866
4867            function on(elem, types, selector, data, fn, one) {
4868                var origFn, type;
4869
4870                // Types can be a map of types/handlers
4871                if (typeof types === "object") {
4872
4873                    // ( types-Object, selector, data )
4874                    if (typeof selector !== "string") {
4875
4876                        // ( types-Object, data )
4877                        data = data || selector;
4878                        selector = undefined;
4879                    }
4880                    for (type in types) {
4881                        on(elem, type, selector, data, types[type], one);
4882                    }
4883                    return elem;
4884                }
4885
4886                if (data == null && fn == null) {
4887
4888                    // ( types, fn )
4889                    fn = selector;
4890                    data = selector = undefined;
4891                } else if (fn == null) {
4892                    if (typeof selector === "string") {
4893
4894                        // ( types, selector, fn )
4895                        fn = data;
4896                        data = undefined;
4897                    } else {
4898
4899                        // ( types, data, fn )
4900                        fn = data;
4901                        data = selector;
4902                        selector = undefined;
4903                    }
4904                }
4905                if (fn === false) {
4906                    fn = returnFalse;
4907                } else if (!fn) {
4908                    return elem;
4909                }
4910
4911                if (one === 1) {
4912                    origFn = fn;
4913                    fn = function (event) {
4914
4915                        // Can use an empty set, since event contains the info
4916                        jQuery().off(event);
4917                        return origFn.apply(this, arguments);
4918                    };
4919
4920                    // Use same guid so caller can remove using origFn
4921                    fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
4922                }
4923                return elem.each(function () {
4924                    jQuery.event.add(this, types, fn, data, selector);
4925                });
4926            }
4927
4928            /*
4929		 * Helper functions for managing events -- not part of the public interface.
4930		 * Props to Dean Edwards' addEvent library for many of the ideas.
4931		 */
4932            jQuery.event = {
4933
4934                global: {},
4935
4936                add: function (elem, types, handler, data, selector) {
4937
4938                    var handleObjIn, eventHandle, tmp,
4939                        events, t, handleObj,
4940                        special, handlers, type, namespaces, origType,
4941                        elemData = dataPriv.get(elem);
4942
4943                    // Only attach events to objects that accept data
4944                    if (!acceptData(elem)) {
4945                        return;
4946                    }
4947
4948                    // Caller can pass in an object of custom data in lieu of the handler
4949                    if (handler.handler) {
4950                        handleObjIn = handler;
4951                        handler = handleObjIn.handler;
4952                        selector = handleObjIn.selector;
4953                    }
4954
4955                    // Ensure that invalid selectors throw exceptions at attach time
4956                    // Evaluate against documentElement in case elem is a non-element node (e.g., document)
4957                    if (selector) {
4958                        jQuery.find.matchesSelector(documentElement, selector);
4959                    }
4960
4961                    // Make sure that the handler has a unique ID, used to find/remove it later
4962                    if (!handler.guid) {
4963                        handler.guid = jQuery.guid++;
4964                    }
4965
4966                    // Init the element's event structure and main handler, if this is the first
4967                    if (!(events = elemData.events)) {
4968                        events = elemData.events = Object.create(null);
4969                    }
4970                    if (!(eventHandle = elemData.handle)) {
4971                        eventHandle = elemData.handle = function (e) {
4972
4973                            // Discard the second event of a jQuery.event.trigger() and
4974                            // when an event is called after a page has unloaded
4975                            return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
4976                                jQuery.event.dispatch.apply(elem, arguments) : undefined;
4977                        };
4978                    }
4979
4980                    // Handle multiple events separated by a space
4981                    types = (types || "").match(rnothtmlwhite) || [""];
4982                    t = types.length;
4983                    while (t--) {
4984                        tmp = rtypenamespace.exec(types[t]) || [];
4985                        type = origType = tmp[1];
4986                        namespaces = (tmp[2] || "").split(".").sort();
4987
4988                        // There *must* be a type, no attaching namespace-only handlers
4989                        if (!type) {
4990                            continue;
4991                        }
4992
4993                        // If event changes its type, use the special event handlers for the changed type
4994                        special = jQuery.event.special[type] || {};
4995
4996                        // If selector defined, determine special event api type, otherwise given type
4997                        type = (selector ? special.delegateType : special.bindType) || type;
4998
4999                        // Update special based on newly reset type
5000                        special = jQuery.event.special[type] || {};
5001
5002                        // handleObj is passed to all event handlers
5003                        handleObj = jQuery.extend({
5004                            type: type,
5005                            origType: origType,
5006                            data: data,
5007                            handler: handler,
5008                            guid: handler.guid,
5009                            selector: selector,
5010                            needsContext: selector && jQuery.expr.match.needsContext.test(selector),
5011                            namespace: namespaces.join(".")
5012                        }, handleObjIn);
5013
5014                        // Init the event handler queue if we're the first
5015                        if (!(handlers = events[type])) {
5016                            handlers = events[type] = [];
5017                            handlers.delegateCount = 0;
5018
5019                            // Only use addEventListener if the special events handler returns false
5020                            if (!special.setup ||
5021                                special.setup.call(elem, data, namespaces, eventHandle) === false) {
5022
5023                                if (elem.addEventListener) {
5024                                    elem.addEventListener(type, eventHandle);
5025                                }
5026                            }
5027                        }
5028
5029                        if (special.add) {
5030                            special.add.call(elem, handleObj);
5031
5032                            if (!handleObj.handler.guid) {
5033                                handleObj.handler.guid = handler.guid;
5034                            }
5035                        }
5036
5037                        // Add to the element's handler list, delegates in front
5038                        if (selector) {
5039                            handlers.splice(handlers.delegateCount++, 0, handleObj);
5040                        } else {
5041                            handlers.push(handleObj);
5042                        }
5043
5044                        // Keep track of which events have ever been used, for event optimization
5045                        jQuery.event.global[type] = true;
5046                    }
5047
5048                },
5049
5050                // Detach an event or set of events from an element
5051                remove: function (elem, types, handler, selector, mappedTypes) {
5052
5053                    var j, origCount, tmp,
5054                        events, t, handleObj,
5055                        special, handlers, type, namespaces, origType,
5056                        elemData = dataPriv.hasData(elem) && dataPriv.get(elem);
5057
5058                    if (!elemData || !(events = elemData.events)) {
5059                        return;
5060                    }
5061
vendor: 5,041 bytes, lines 5062-5165
5062                    // Once for each type.namespace in types; type may be omitted
5063                    types = (types || "").match(rnothtmlwhite) || [""];
5064                    t = types.length;
5065                    while (t--) {
5066                        tmp = rtypenamespace.exec(types[t]) || [];
5067                        type = origType = tmp[1];
5068                        namespaces = (tmp[2] || "").split(".").sort();
5069
5070                        // Unbind all events (on this namespace, if provided) for the element
5071                        if (!type) {
5072                            for (type in events) {
5073                                jQuery.event.remove(elem, type + types[t], handler, selector, true);
5074                            }
5075                            continue;
5076                        }
5077
5078                        special = jQuery.event.special[type] || {};
5079                        type = (selector ? special.delegateType : special.bindType) || type;
5080                        handlers = events[type] || [];
5081                        tmp = tmp[2] &&
5082                            new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");
5083
5084                        // Remove matching events
5085                        origCount = j = handlers.length;
5086                        while (j--) {
5087                            handleObj = handlers[j];
5088
5089                            if ((mappedTypes || origType === handleObj.origType) &&
5090                                (!handler || handler.guid === handleObj.guid) &&
5091                                (!tmp || tmp.test(handleObj.namespace)) &&
5092                                (!selector || selector === handleObj.selector ||
5093                                    selector === "**" && handleObj.selector)) {
5094                                handlers.splice(j, 1);
5095
5096                                if (handleObj.selector) {
5097                                    handlers.delegateCount--;
5098                                }
5099                                if (special.remove) {
5100                                    special.remove.call(elem, handleObj);
5101                                }
5102                            }
5103                        }
5104
5105                        // Remove generic event handler if we removed something and no more handlers exist
5106                        // (avoids potential for endless recursion during removal of special event handlers)
5107                        if (origCount && !handlers.length) {
5108                            if (!special.teardown ||
5109                                special.teardown.call(elem, namespaces, elemData.handle) === false) {
5110
5111                                jQuery.removeEvent(elem, type, elemData.handle);
5112                            }
5113
5114                            delete events[type];
5115                        }
5116                    }
5117
5118                    // Remove data and the expando if it's no longer used
5119                    if (jQuery.isEmptyObject(events)) {
5120                        dataPriv.remove(elem, "handle events");
5121                    }
5122                },
5123
5124                dispatch: function (nativeEvent) {
5125
5126                    var i, j, ret, matched, handleObj, handlerQueue,
5127                        args = new Array(arguments.length),
5128
5129                        // Make a writable jQuery.Event from the native event object
5130                        event = jQuery.event.fix(nativeEvent),
5131
5132                        handlers = (
5133                            dataPriv.get(this, "events") || Object.create(null)
5134                        )[event.type] || [],
5135                        special = jQuery.event.special[event.type] || {};
5136
5137                    // Use the fix-ed jQuery.Event rather than the (read-only) native event
5138                    args[0] = event;
5139
5140                    for (i = 1; i < arguments.length; i++) {
5141                        args[i] = arguments[i];
5142                    }
5143
5144                    event.delegateTarget = this;
5145
5146                    // Call the preDispatch hook for the mapped type, and let it bail if desired
5147                    if (special.preDispatch && special.preDispatch.call(this, event) === false) {
5148                        return;
5149                    }
5150
5151                    // Determine handlers
5152                    handlerQueue = jQuery.event.handlers.call(this, event, handlers);
5153
5154                    // Run delegates first; they may want to stop propagation beneath us
5155                    i = 0;
5156                    while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
5157                        event.currentTarget = matched.elem;
5158
5159                        j = 0;
5160                        while ((handleObj = matched.handlers[j++]) &&
5161                        !event.isImmediatePropagationStopped()) {
5162
5163                            // If the event is namespaced, then each handler is only invoked if it is
5164                            // specially universal or its namespaces are a superset of the event's.
5165                            if (!event.rnamespace || handleObj.namespace === false ||
vendor: 93,695 bytes, lines 5166-7305
5166                                event.rnamespace.test(handleObj.namespace)) {
5167
5168                                event.handleObj = handleObj;
5169                                event.data = handleObj.data;
5170
5171                                ret = ((jQuery.event.special[handleObj.origType] || {}).handle ||
5172                                    handleObj.handler).apply(matched.elem, args);
5173
5174                                if (ret !== undefined) {
5175                                    if ((event.result = ret) === false) {
5176                                        event.preventDefault();
5177                                        event.stopPropagation();
5178                                    }
5179                                }
5180                            }
5181                        }
5182                    }
5183
5184                    // Call the postDispatch hook for the mapped type
5185                    if (special.postDispatch) {
5186                        special.postDispatch.call(this, event);
5187                    }
5188
5189                    return event.result;
5190                },
5191
5192                handlers: function (event, handlers) {
5193                    var i, handleObj, sel, matchedHandlers, matchedSelectors,
5194                        handlerQueue = [],
5195                        delegateCount = handlers.delegateCount,
5196                        cur = event.target;
5197
5198                    // Find delegate handlers
5199                    if (delegateCount &&
5200
5201                        // Support: IE <=9
5202                        // Black-hole SVG <use> instance trees (trac-13180)
5203                        cur.nodeType &&
5204
5205                        // Support: Firefox <=42
5206                        // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
5207                        // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
5208                        // Support: IE 11 only
5209                        // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
5210                        !(event.type === "click" && event.button >= 1)) {
5211
5212                        for (; cur !== this; cur = cur.parentNode || this) {
5213
5214                            // Don't check non-elements (trac-13208)
5215                            // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764)
5216                            if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) {
5217                                matchedHandlers = [];
5218                                matchedSelectors = {};
5219                                for (i = 0; i < delegateCount; i++) {
5220                                    handleObj = handlers[i];
5221
5222                                    // Don't conflict with Object.prototype properties (trac-13203)
5223                                    sel = handleObj.selector + " ";
5224
5225                                    if (matchedSelectors[sel] === undefined) {
5226                                        matchedSelectors[sel] = handleObj.needsContext ?
5227                                            jQuery(sel, this).index(cur) > -1 :
5228                                            jQuery.find(sel, this, null, [cur]).length;
5229                                    }
5230                                    if (matchedSelectors[sel]) {
5231                                        matchedHandlers.push(handleObj);
5232                                    }
5233                                }
5234                                if (matchedHandlers.length) {
5235                                    handlerQueue.push({elem: cur, handlers: matchedHandlers});
5236                                }
5237                            }
5238                        }
5239                    }
5240
5241                    // Add the remaining (directly-bound) handlers
5242                    cur = this;
5243                    if (delegateCount < handlers.length) {
5244                        handlerQueue.push({elem: cur, handlers: handlers.slice(delegateCount)});
5245                    }
5246
5247                    return handlerQueue;
5248                },
5249
5250                addProp: function (name, hook) {
5251                    Object.defineProperty(jQuery.Event.prototype, name, {
5252                        enumerable: true,
5253                        configurable: true,
5254
5255                        get: isFunction(hook) ?
5256                            function () {
5257                                if (this.originalEvent) {
5258                                    return hook(this.originalEvent);
5259                                }
5260                            } :
5261                            function () {
5262                                if (this.originalEvent) {
5263                                    return this.originalEvent[name];
5264                                }
5265                            },
5266
5267                        set: function (value) {
5268                            Object.defineProperty(this, name, {
5269                                enumerable: true,
5270                                configurable: true,
5271                                writable: true,
5272                                value: value
5273                            });
5274                        }
5275                    });
5276                },
5277
5278                fix: function (originalEvent) {
5279                    return originalEvent[jQuery.expando] ?
5280                        originalEvent :
5281                        new jQuery.Event(originalEvent);
5282                },
5283
5284                special: {
5285                    load: {
5286
5287                        // Prevent triggered image.load events from bubbling to window.load
5288                        noBubble: true
5289                    },
5290                    click: {
5291
5292                        // Utilize native event to ensure correct state for checkable inputs
5293                        setup: function (data) {
5294
5295                            // For mutual compressibility with _default, replace `this` access with a local var.
5296                            // `|| data` is dead code meant only to preserve the variable through minification.
5297                            var el = this || data;
5298
5299                            // Claim the first handler
5300                            if (rcheckableType.test(el.type) &&
5301                                el.click && nodeName(el, "input")) {
5302
5303                                // dataPriv.set( el, "click", ... )
5304                                leverageNative(el, "click", true);
5305                            }
5306
5307                            // Return false to allow normal processing in the caller
5308                            return false;
5309                        },
5310                        trigger: function (data) {
5311
5312                            // For mutual compressibility with _default, replace `this` access with a local var.
5313                            // `|| data` is dead code meant only to preserve the variable through minification.
5314                            var el = this || data;
5315
5316                            // Force setup before triggering a click
5317                            if (rcheckableType.test(el.type) &&
5318                                el.click && nodeName(el, "input")) {
5319
5320                                leverageNative(el, "click");
5321                            }
5322
5323                            // Return non-false to allow normal event-path propagation
5324                            return true;
5325                        },
5326
5327                        // For cross-browser consistency, suppress native .click() on links
5328                        // Also prevent it if we're currently inside a leveraged native-event stack
5329                        _default: function (event) {
5330                            var target = event.target;
5331                            return rcheckableType.test(target.type) &&
5332                                target.click && nodeName(target, "input") &&
5333                                dataPriv.get(target, "click") ||
5334                                nodeName(target, "a");
5335                        }
5336                    },
5337
5338                    beforeunload: {
5339                        postDispatch: function (event) {
5340
5341                            // Support: Firefox 20+
5342                            // Firefox doesn't alert if the returnValue field is not set.
5343                            if (event.result !== undefined && event.originalEvent) {
5344                                event.originalEvent.returnValue = event.result;
5345                            }
5346                        }
5347                    }
5348                }
5349            };
5350
5351            // Ensure the presence of an event listener that handles manually-triggered
5352            // synthetic events by interrupting progress until reinvoked in response to
5353            // *native* events that it fires directly, ensuring that state changes have
5354            // already occurred before other listeners are invoked.
5355            function leverageNative(el, type, isSetup) {
5356
5357                // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add
5358                if (!isSetup) {
5359                    if (dataPriv.get(el, type) === undefined) {
5360                        jQuery.event.add(el, type, returnTrue);
5361                    }
5362                    return;
5363                }
5364
5365                // Register the controller as a special universal handler for all event namespaces
5366                dataPriv.set(el, type, false);
5367                jQuery.event.add(el, type, {
5368                    namespace: false,
5369                    handler: function (event) {
5370                        var result,
5371                            saved = dataPriv.get(this, type);
5372
5373                        if ((event.isTrigger & 1) && this[type]) {
5374
5375                            // Interrupt processing of the outer synthetic .trigger()ed event
5376                            if (!saved) {
5377
5378                                // Store arguments for use when handling the inner native event
5379                                // There will always be at least one argument (an event object), so this array
5380                                // will not be confused with a leftover capture object.
5381                                saved = slice.call(arguments);
5382                                dataPriv.set(this, type, saved);
5383
5384                                // Trigger the native event and capture its result
5385                                this[type]();
5386                                result = dataPriv.get(this, type);
5387                                dataPriv.set(this, type, false);
5388
5389                                if (saved !== result) {
5390
5391                                    // Cancel the outer synthetic event
5392                                    event.stopImmediatePropagation();
5393                                    event.preventDefault();
5394
5395                                    return result;
5396                                }
5397
5398                                // If this is an inner synthetic event for an event with a bubbling surrogate
5399                                // (focus or blur), assume that the surrogate already propagated from triggering
5400                                // the native event and prevent that from happening again here.
5401                                // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
5402                                // bubbling surrogate propagates *after* the non-bubbling base), but that seems
5403                                // less bad than duplication.
5404                            } else if ((jQuery.event.special[type] || {}).delegateType) {
5405                                event.stopPropagation();
5406                            }
5407
5408                            // If this is a native event triggered above, everything is now in order
5409                            // Fire an inner synthetic event with the original arguments
5410                        } else if (saved) {
5411
5412                            // ...and capture the result
5413                            dataPriv.set(this, type, jQuery.event.trigger(
5414                                saved[0],
5415                                saved.slice(1),
5416                                this
5417                            ));
5418
5419                            // Abort handling of the native event by all jQuery handlers while allowing
5420                            // native handlers on the same element to run. On target, this is achieved
5421                            // by stopping immediate propagation just on the jQuery event. However,
5422                            // the native event is re-wrapped by a jQuery one on each level of the
5423                            // propagation so the only way to stop it for jQuery is to stop it for
5424                            // everyone via native `stopPropagation()`. This is not a problem for
5425                            // focus/blur which don't bubble, but it does also stop click on checkboxes
5426                            // and radios. We accept this limitation.
5427                            event.stopPropagation();
5428                            event.isImmediatePropagationStopped = returnTrue;
5429                        }
5430                    }
5431                });
5432            }
5433
5434            jQuery.removeEvent = function (elem, type, handle) {
5435
5436                // This "if" is needed for plain objects
5437                if (elem.removeEventListener) {
5438                    elem.removeEventListener(type, handle);
5439                }
5440            };
5441
5442            jQuery.Event = function (src, props) {
5443
5444                // Allow instantiation without the 'new' keyword
5445                if (!(this instanceof jQuery.Event)) {
5446                    return new jQuery.Event(src, props);
5447                }
5448
5449                // Event object
5450                if (src && src.type) {
5451                    this.originalEvent = src;
5452                    this.type = src.type;
5453
5454                    // Events bubbling up the document may have been marked as prevented
5455                    // by a handler lower down the tree; reflect the correct value.
5456                    this.isDefaultPrevented = src.defaultPrevented ||
5457                    src.defaultPrevented === undefined &&
5458
5459                    // Support: Android <=2.3 only
5460                    src.returnValue === false ?
5461                        returnTrue :
5462                        returnFalse;
5463
5464                    // Create target properties
5465                    // Support: Safari <=6 - 7 only
5466                    // Target should not be a text node (trac-504, trac-13143)
5467                    this.target = (src.target && src.target.nodeType === 3) ?
5468                        src.target.parentNode :
5469                        src.target;
5470
5471                    this.currentTarget = src.currentTarget;
5472                    this.relatedTarget = src.relatedTarget;
5473
5474                    // Event type
5475                } else {
5476                    this.type = src;
5477                }
5478
5479                // Put explicitly provided properties onto the event object
5480                if (props) {
5481                    jQuery.extend(this, props);
5482                }
5483
5484                // Create a timestamp if incoming event doesn't have one
5485                this.timeStamp = src && src.timeStamp || Date.now();
5486
5487                // Mark it as fixed
5488                this[jQuery.expando] = true;
5489            };
5490
5491            // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5492            // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5493            jQuery.Event.prototype = {
5494                constructor: jQuery.Event,
5495                isDefaultPrevented: returnFalse,
5496                isPropagationStopped: returnFalse,
5497                isImmediatePropagationStopped: returnFalse,
5498                isSimulated: false,
5499
5500                preventDefault: function () {
5501                    var e = this.originalEvent;
5502
5503                    this.isDefaultPrevented = returnTrue;
5504
5505                    if (e && !this.isSimulated) {
5506                        e.preventDefault();
5507                    }
5508                },
5509                stopPropagation: function () {
5510                    var e = this.originalEvent;
5511
5512                    this.isPropagationStopped = returnTrue;
5513
5514                    if (e && !this.isSimulated) {
5515                        e.stopPropagation();
5516                    }
5517                },
5518                stopImmediatePropagation: function () {
5519                    var e = this.originalEvent;
5520
5521                    this.isImmediatePropagationStopped = returnTrue;
5522
5523                    if (e && !this.isSimulated) {
5524                        e.stopImmediatePropagation();
5525                    }
5526
5527                    this.stopPropagation();
5528                }
5529            };
5530
5531            // Includes all common event props including KeyEvent and MouseEvent specific props
5532            jQuery.each({
5533                altKey: true,
5534                bubbles: true,
5535                cancelable: true,
5536                changedTouches: true,
5537                ctrlKey: true,
5538                detail: true,
5539                eventPhase: true,
5540                metaKey: true,
5541                pageX: true,
5542                pageY: true,
5543                shiftKey: true,
5544                view: true,
5545                "char": true,
5546                code: true,
5547                charCode: true,
5548                key: true,
5549                keyCode: true,
5550                button: true,
5551                buttons: true,
5552                clientX: true,
5553                clientY: true,
5554                offsetX: true,
5555                offsetY: true,
5556                pointerId: true,
5557                pointerType: true,
5558                screenX: true,
5559                screenY: true,
5560                targetTouches: true,
5561                toElement: true,
5562                touches: true,
5563                which: true
5564            }, jQuery.event.addProp);
5565
5566            jQuery.each({focus: "focusin", blur: "focusout"}, function (type, delegateType) {
5567
5568                function focusMappedHandler(nativeEvent) {
5569                    if (document.documentMode) {
5570
5571                        // Support: IE 11+
5572                        // Attach a single focusin/focusout handler on the document while someone wants
5573                        // focus/blur. This is because the former are synchronous in IE while the latter
5574                        // are async. In other browsers, all those handlers are invoked synchronously.
5575
5576                        // `handle` from private data would already wrap the event, but we need
5577                        // to change the `type` here.
5578                        var handle = dataPriv.get(this, "handle"),
5579                            event = jQuery.event.fix(nativeEvent);
5580                        event.type = nativeEvent.type === "focusin" ? "focus" : "blur";
5581                        event.isSimulated = true;
5582
5583                        // First, handle focusin/focusout
5584                        handle(nativeEvent);
5585
5586                        // ...then, handle focus/blur
5587                        //
5588                        // focus/blur don't bubble while focusin/focusout do; simulate the former by only
5589                        // invoking the handler at the lower level.
5590                        if (event.target === event.currentTarget) {
5591
5592                            // The setup part calls `leverageNative`, which, in turn, calls
5593                            // `jQuery.event.add`, so event handle will already have been set
5594                            // by this point.
5595                            handle(event);
5596                        }
5597                    } else {
5598
5599                        // For non-IE browsers, attach a single capturing handler on the document
5600                        // while someone wants focusin/focusout.
5601                        jQuery.event.simulate(delegateType, nativeEvent.target,
5602                            jQuery.event.fix(nativeEvent));
5603                    }
5604                }
5605
5606                jQuery.event.special[type] = {
5607
5608                    // Utilize native event if possible so blur/focus sequence is correct
5609                    setup: function () {
5610
5611                        var attaches;
5612
5613                        // Claim the first handler
5614                        // dataPriv.set( this, "focus", ... )
5615                        // dataPriv.set( this, "blur", ... )
5616                        leverageNative(this, type, true);
5617
5618                        if (document.documentMode) {
5619
5620                            // Support: IE 9 - 11+
5621                            // We use the same native handler for focusin & focus (and focusout & blur)
5622                            // so we need to coordinate setup & teardown parts between those events.
5623                            // Use `delegateType` as the key as `type` is already used by `leverageNative`.
5624                            attaches = dataPriv.get(this, delegateType);
5625                            if (!attaches) {
5626                                this.addEventListener(delegateType, focusMappedHandler);
5627                            }
5628                            dataPriv.set(this, delegateType, (attaches || 0) + 1);
5629                        } else {
5630
5631                            // Return false to allow normal processing in the caller
5632                            return false;
5633                        }
5634                    },
5635                    trigger: function () {
5636
5637                        // Force setup before trigger
5638                        leverageNative(this, type);
5639
5640                        // Return non-false to allow normal event-path propagation
5641                        return true;
5642                    },
5643
5644                    teardown: function () {
5645                        var attaches;
5646
5647                        if (document.documentMode) {
5648                            attaches = dataPriv.get(this, delegateType) - 1;
5649                            if (!attaches) {
5650                                this.removeEventListener(delegateType, focusMappedHandler);
5651                                dataPriv.remove(this, delegateType);
5652                            } else {
5653                                dataPriv.set(this, delegateType, attaches);
5654                            }
5655                        } else {
5656
5657                            // Return false to indicate standard teardown should be applied
5658                            return false;
5659                        }
5660                    },
5661
5662                    // Suppress native focus or blur if we're currently inside
5663                    // a leveraged native-event stack
5664                    _default: function (event) {
5665                        return dataPriv.get(event.target, type);
5666                    },
5667
5668                    delegateType: delegateType
5669                };
5670
5671                // Support: Firefox <=44
5672                // Firefox doesn't have focus(in | out) events
5673                // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
5674                //
5675                // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
5676                // focus(in | out) events fire after focus & blur events,
5677                // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
5678                // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
5679                //
5680                // Support: IE 9 - 11+
5681                // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch,
5682                // attach a single handler for both events in IE.
5683                jQuery.event.special[delegateType] = {
5684                    setup: function () {
5685
5686                        // Handle: regular nodes (via `this.ownerDocument`), window
5687                        // (via `this.document`) & document (via `this`).
5688                        var doc = this.ownerDocument || this.document || this,
5689                            dataHolder = document.documentMode ? this : doc,
5690                            attaches = dataPriv.get(dataHolder, delegateType);
5691
5692                        // Support: IE 9 - 11+
5693                        // We use the same native handler for focusin & focus (and focusout & blur)
5694                        // so we need to coordinate setup & teardown parts between those events.
5695                        // Use `delegateType` as the key as `type` is already used by `leverageNative`.
5696                        if (!attaches) {
5697                            if (document.documentMode) {
5698                                this.addEventListener(delegateType, focusMappedHandler);
5699                            } else {
5700                                doc.addEventListener(type, focusMappedHandler, true);
5701                            }
5702                        }
5703                        dataPriv.set(dataHolder, delegateType, (attaches || 0) + 1);
5704                    },
5705                    teardown: function () {
5706                        var doc = this.ownerDocument || this.document || this,
5707                            dataHolder = document.documentMode ? this : doc,
5708                            attaches = dataPriv.get(dataHolder, delegateType) - 1;
5709
5710                        if (!attaches) {
5711                            if (document.documentMode) {
5712                                this.removeEventListener(delegateType, focusMappedHandler);
5713                            } else {
5714                                doc.removeEventListener(type, focusMappedHandler, true);
5715                            }
5716                            dataPriv.remove(dataHolder, delegateType);
5717                        } else {
5718                            dataPriv.set(dataHolder, delegateType, attaches);
5719                        }
5720                    }
5721                };
5722            });
5723
5724            // Create mouseenter/leave events using mouseover/out and event-time checks
5725            // so that event delegation works in jQuery.
5726            // Do the same for pointerenter/pointerleave and pointerover/pointerout
5727            //
5728            // Support: Safari 7 only
5729            // Safari sends mouseenter too often; see:
5730            // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
5731            // for the description of the bug (it existed in older Chrome versions as well).
5732            jQuery.each({
5733                mouseenter: "mouseover",
5734                mouseleave: "mouseout",
5735                pointerenter: "pointerover",
5736                pointerleave: "pointerout"
5737            }, function (orig, fix) {
5738                jQuery.event.special[orig] = {
5739                    delegateType: fix,
5740                    bindType: fix,
5741
5742                    handle: function (event) {
5743                        var ret,
5744                            target = this,
5745                            related = event.relatedTarget,
5746                            handleObj = event.handleObj;
5747
5748                        // For mouseenter/leave call the handler if related is outside the target.
5749                        // NB: No relatedTarget if the mouse left/entered the browser window
5750                        if (!related || (related !== target && !jQuery.contains(target, related))) {
5751                            event.type = handleObj.origType;
5752                            ret = handleObj.handler.apply(this, arguments);
5753                            event.type = fix;
5754                        }
5755                        return ret;
5756                    }
5757                };
5758            });
5759
5760            jQuery.fn.extend({
5761
5762                on: function (types, selector, data, fn) {
5763                    return on(this, types, selector, data, fn);
5764                },
5765                one: function (types, selector, data, fn) {
5766                    return on(this, types, selector, data, fn, 1);
5767                },
5768                off: function (types, selector, fn) {
5769                    var handleObj, type;
5770                    if (types && types.preventDefault && types.handleObj) {
5771
5772                        // ( event )  dispatched jQuery.Event
5773                        handleObj = types.handleObj;
5774                        jQuery(types.delegateTarget).off(
5775                            handleObj.namespace ?
5776                                handleObj.origType + "." + handleObj.namespace :
5777                                handleObj.origType,
5778                            handleObj.selector,
5779                            handleObj.handler
5780                        );
5781                        return this;
5782                    }
5783                    if (typeof types === "object") {
5784
5785                        // ( types-object [, selector] )
5786                        for (type in types) {
5787                            this.off(type, selector, types[type]);
5788                        }
5789                        return this;
5790                    }
5791                    if (selector === false || typeof selector === "function") {
5792
5793                        // ( types [, fn] )
5794                        fn = selector;
5795                        selector = undefined;
5796                    }
5797                    if (fn === false) {
5798                        fn = returnFalse;
5799                    }
5800                    return this.each(function () {
5801                        jQuery.event.remove(this, types, fn, selector);
5802                    });
5803                }
5804            });
5805
5806
5807            var
5808
5809                // Support: IE <=10 - 11, Edge 12 - 13 only
5810                // In IE/Edge using regex groups here causes severe slowdowns.
5811                // See https://connect.microsoft.com/IE/feedback/details/1736512/
5812                rnoInnerhtml = /<script|<style|<link/i,
5813
5814                // checked="checked" or checked
5815                rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5816
5817                rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g;
5818
5819            // Prefer a tbody over its parent table for containing new rows
5820            function manipulationTarget(elem, content) {
5821                if (nodeName(elem, "table") &&
5822                    nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) {
5823
5824                    return jQuery(elem).children("tbody")[0] || elem;
5825                }
5826
5827                return elem;
5828            }
5829
5830            // Replace/restore the type attribute of script elements for safe DOM manipulation
5831            function disableScript(elem) {
5832                elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
5833                return elem;
5834            }
5835
5836            function restoreScript(elem) {
5837                if ((elem.type || "").slice(0, 5) === "true/") {
5838                    elem.type = elem.type.slice(5);
5839                } else {
5840                    elem.removeAttribute("type");
5841                }
5842
5843                return elem;
5844            }
5845
5846            function cloneCopyEvent(src, dest) {
5847                var i, l, type, pdataOld, udataOld, udataCur, events;
5848
5849                if (dest.nodeType !== 1) {
5850                    return;
5851                }
5852
5853                // 1. Copy private data: events, handlers, etc.
5854                if (dataPriv.hasData(src)) {
5855                    pdataOld = dataPriv.get(src);
5856                    events = pdataOld.events;
5857
5858                    if (events) {
5859                        dataPriv.remove(dest, "handle events");
5860
5861                        for (type in events) {
5862                            for (i = 0, l = events[type].length; i < l; i++) {
5863                                jQuery.event.add(dest, type, events[type][i]);
5864                            }
5865                        }
5866                    }
5867                }
5868
5869                // 2. Copy user data
5870                if (dataUser.hasData(src)) {
5871                    udataOld = dataUser.access(src);
5872                    udataCur = jQuery.extend({}, udataOld);
5873
5874                    dataUser.set(dest, udataCur);
5875                }
5876            }
5877
5878            // Fix IE bugs, see support tests
5879            function fixInput(src, dest) {
5880                var nodeName = dest.nodeName.toLowerCase();
5881
5882                // Fails to persist the checked state of a cloned checkbox or radio button.
5883                if (nodeName === "input" && rcheckableType.test(src.type)) {
5884                    dest.checked = src.checked;
5885
5886                    // Fails to return the selected option to the default selected state when cloning options
5887                } else if (nodeName === "input" || nodeName === "textarea") {
5888                    dest.defaultValue = src.defaultValue;
5889                }
5890            }
5891
5892            function domManip(collection, args, callback, ignored) {
5893
5894                // Flatten any nested arrays
5895                args = flat(args);
5896
5897                var fragment, first, scripts, hasScripts, node, doc,
5898                    i = 0,
5899                    l = collection.length,
5900                    iNoClone = l - 1,
5901                    value = args[0],
5902                    valueIsFunction = isFunction(value);
5903
5904                // We can't cloneNode fragments that contain checked, in WebKit
5905                if (valueIsFunction ||
5906                    (l > 1 && typeof value === "string" &&
5907                        !support.checkClone && rchecked.test(value))) {
5908                    return collection.each(function (index) {
5909                        var self = collection.eq(index);
5910                        if (valueIsFunction) {
5911                            args[0] = value.call(this, index, self.html());
5912                        }
5913                        domManip(self, args, callback, ignored);
5914                    });
5915                }
5916
5917                if (l) {
5918                    fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored);
5919                    first = fragment.firstChild;
5920
5921                    if (fragment.childNodes.length === 1) {
5922                        fragment = first;
5923                    }
5924
5925                    // Require either new content or an interest in ignored elements to invoke the callback
5926                    if (first || ignored) {
5927                        scripts = jQuery.map(getAll(fragment, "script"), disableScript);
5928                        hasScripts = scripts.length;
5929
5930                        // Use the original fragment for the last item
5931                        // instead of the first because it can end up
5932                        // being emptied incorrectly in certain situations (trac-8070).
5933                        for (; i < l; i++) {
5934                            node = fragment;
5935
5936                            if (i !== iNoClone) {
5937                                node = jQuery.clone(node, true, true);
5938
5939                                // Keep references to cloned scripts for later restoration
5940                                if (hasScripts) {
5941
5942                                    // Support: Android <=4.0 only, PhantomJS 1 only
5943                                    // push.apply(_, arraylike) throws on ancient WebKit
5944                                    jQuery.merge(scripts, getAll(node, "script"));
5945                                }
5946                            }
5947
5948                            callback.call(collection[i], node, i);
5949                        }
5950
5951                        if (hasScripts) {
5952                            doc = scripts[scripts.length - 1].ownerDocument;
5953
5954                            // Re-enable scripts
5955                            jQuery.map(scripts, restoreScript);
5956
5957                            // Evaluate executable scripts on first document insertion
5958                            for (i = 0; i < hasScripts; i++) {
5959                                node = scripts[i];
5960                                if (rscriptType.test(node.type || "") &&
5961                                    !dataPriv.access(node, "globalEval") &&
5962                                    jQuery.contains(doc, node)) {
5963
5964                                    if (node.src && (node.type || "").toLowerCase() !== "module") {
5965
5966                                        // Optional AJAX dependency, but won't run scripts if not present
5967                                        if (jQuery._evalUrl && !node.noModule) {
5968                                            jQuery._evalUrl(node.src, {
5969                                                nonce: node.nonce || node.getAttribute("nonce")
5970                                            }, doc);
5971                                        }
5972                                    } else {
5973
5974                                        // Unwrap a CDATA section containing script contents. This shouldn't be
5975                                        // needed as in XML documents they're already not visible when
5976                                        // inspecting element contents and in HTML documents they have no
5977                                        // meaning but we're preserving that logic for backwards compatibility.
5978                                        // This will be removed completely in 4.0. See gh-4904.
5979                                        DOMEval(node.textContent.replace(rcleanScript, ""), node, doc);
5980                                    }
5981                                }
5982                            }
5983                        }
5984                    }
5985                }
5986
5987                return collection;
5988            }
5989
5990            function remove(elem, selector, keepData) {
5991                var node,
5992                    nodes = selector ? jQuery.filter(selector, elem) : elem,
5993                    i = 0;
5994
5995                for (; (node = nodes[i]) != null; i++) {
5996                    if (!keepData && node.nodeType === 1) {
5997                        jQuery.cleanData(getAll(node));
5998                    }
5999
6000                    if (node.parentNode) {
6001                        if (keepData && isAttached(node)) {
6002                            setGlobalEval(getAll(node, "script"));
6003                        }
6004                        node.parentNode.removeChild(node);
6005                    }
6006                }
6007
6008                return elem;
6009            }
6010
6011            jQuery.extend({
6012                htmlPrefilter: function (html) {
6013                    return html;
6014                },
6015
6016                clone: function (elem, dataAndEvents, deepDataAndEvents) {
6017                    var i, l, srcElements, destElements,
6018                        clone = elem.cloneNode(true),
6019                        inPage = isAttached(elem);
6020
6021                    // Fix IE cloning issues
6022                    if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) &&
6023                        !jQuery.isXMLDoc(elem)) {
6024
6025                        // We eschew jQuery#find here for performance reasons:
6026                        // https://jsperf.com/getall-vs-sizzle/2
6027                        destElements = getAll(clone);
6028                        srcElements = getAll(elem);
6029
6030                        for (i = 0, l = srcElements.length; i < l; i++) {
6031                            fixInput(srcElements[i], destElements[i]);
6032                        }
6033                    }
6034
6035                    // Copy the events from the original to the clone
6036                    if (dataAndEvents) {
6037                        if (deepDataAndEvents) {
6038                            srcElements = srcElements || getAll(elem);
6039                            destElements = destElements || getAll(clone);
6040
6041                            for (i = 0, l = srcElements.length; i < l; i++) {
6042                                cloneCopyEvent(srcElements[i], destElements[i]);
6043                            }
6044                        } else {
6045                            cloneCopyEvent(elem, clone);
6046                        }
6047                    }
6048
6049                    // Preserve script evaluation history
6050                    destElements = getAll(clone, "script");
6051                    if (destElements.length > 0) {
6052                        setGlobalEval(destElements, !inPage && getAll(elem, "script"));
6053                    }
6054
6055                    // Return the cloned set
6056                    return clone;
6057                },
6058
6059                cleanData: function (elems) {
6060                    var data, elem, type,
6061                        special = jQuery.event.special,
6062                        i = 0;
6063
6064                    for (; (elem = elems[i]) !== undefined; i++) {
6065                        if (acceptData(elem)) {
6066                            if ((data = elem[dataPriv.expando])) {
6067                                if (data.events) {
6068                                    for (type in data.events) {
6069                                        if (special[type]) {
6070                                            jQuery.event.remove(elem, type);
6071
6072                                            // This is a shortcut to avoid jQuery.event.remove's overhead
6073                                        } else {
6074                                            jQuery.removeEvent(elem, type, data.handle);
6075                                        }
6076                                    }
6077                                }
6078
6079                                // Support: Chrome <=35 - 45+
6080                                // Assign undefined instead of using delete, see Data#remove
6081                                elem[dataPriv.expando] = undefined;
6082                            }
6083                            if (elem[dataUser.expando]) {
6084
6085                                // Support: Chrome <=35 - 45+
6086                                // Assign undefined instead of using delete, see Data#remove
6087                                elem[dataUser.expando] = undefined;
6088                            }
6089                        }
6090                    }
6091                }
6092            });
6093
6094            jQuery.fn.extend({
6095                detach: function (selector) {
6096                    return remove(this, selector, true);
6097                },
6098
6099                remove: function (selector) {
6100                    return remove(this, selector);
6101                },
6102
6103                text: function (value) {
6104                    return access(this, function (value) {
6105                        return value === undefined ?
6106                            jQuery.text(this) :
6107                            this.empty().each(function () {
6108                                if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
6109                                    this.textContent = value;
6110                                }
6111                            });
6112                    }, null, value, arguments.length);
6113                },
6114
6115                append: function () {
6116                    return domManip(this, arguments, function (elem) {
6117                        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
6118                            var target = manipulationTarget(this, elem);
6119                            target.appendChild(elem);
6120                        }
6121                    });
6122                },
6123
6124                prepend: function () {
6125                    return domManip(this, arguments, function (elem) {
6126                        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
6127                            var target = manipulationTarget(this, elem);
6128                            target.insertBefore(elem, target.firstChild);
6129                        }
6130                    });
6131                },
6132
6133                before: function () {
6134                    return domManip(this, arguments, function (elem) {
6135                        if (this.parentNode) {
6136                            this.parentNode.insertBefore(elem, this);
6137                        }
6138                    });
6139                },
6140
6141                after: function () {
6142                    return domManip(this, arguments, function (elem) {
6143                        if (this.parentNode) {
6144                            this.parentNode.insertBefore(elem, this.nextSibling);
6145                        }
6146                    });
6147                },
6148
6149                empty: function () {
6150                    var elem,
6151                        i = 0;
6152
6153                    for (; (elem = this[i]) != null; i++) {
6154                        if (elem.nodeType === 1) {
6155
6156                            // Prevent memory leaks
6157                            jQuery.cleanData(getAll(elem, false));
6158
6159                            // Remove any remaining nodes
6160                            elem.textContent = "";
6161                        }
6162                    }
6163
6164                    return this;
6165                },
6166
6167                clone: function (dataAndEvents, deepDataAndEvents) {
6168                    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6169                    deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6170
6171                    return this.map(function () {
6172                        return jQuery.clone(this, dataAndEvents, deepDataAndEvents);
6173                    });
6174                },
6175
6176                html: function (value) {
6177                    return access(this, function (value) {
6178                        var elem = this[0] || {},
6179                            i = 0,
6180                            l = this.length;
6181
6182                        if (value === undefined && elem.nodeType === 1) {
6183                            return elem.innerHTML;
6184                        }
6185
6186                        // See if we can take a shortcut and just use innerHTML
6187                        if (typeof value === "string" && !rnoInnerhtml.test(value) &&
6188                            !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {
6189
6190                            value = jQuery.htmlPrefilter(value);
6191
6192                            try {
6193                                for (; i < l; i++) {
6194                                    elem = this[i] || {};
6195
6196                                    // Remove element nodes and prevent memory leaks
6197                                    if (elem.nodeType === 1) {
6198                                        jQuery.cleanData(getAll(elem, false));
6199                                        elem.innerHTML = value;
6200                                    }
6201                                }
6202
6203                                elem = 0;
6204
6205                                // If using innerHTML throws an exception, use the fallback method
6206                            } catch (e) {
6207                            }
6208                        }
6209
6210                        if (elem) {
6211                            this.empty().append(value);
6212                        }
6213                    }, null, value, arguments.length);
6214                },
6215
6216                replaceWith: function () {
6217                    var ignored = [];
6218
6219                    // Make the changes, replacing each non-ignored context element with the new content
6220                    return domManip(this, arguments, function (elem) {
6221                        var parent = this.parentNode;
6222
6223                        if (jQuery.inArray(this, ignored) < 0) {
6224                            jQuery.cleanData(getAll(this));
6225                            if (parent) {
6226                                parent.replaceChild(elem, this);
6227                            }
6228                        }
6229
6230                        // Force callback invocation
6231                    }, ignored);
6232                }
6233            });
6234
6235            jQuery.each({
6236                appendTo: "append",
6237                prependTo: "prepend",
6238                insertBefore: "before",
6239                insertAfter: "after",
6240                replaceAll: "replaceWith"
6241            }, function (name, original) {
6242                jQuery.fn[name] = function (selector) {
6243                    var elems,
6244                        ret = [],
6245                        insert = jQuery(selector),
6246                        last = insert.length - 1,
6247                        i = 0;
6248
6249                    for (; i <= last; i++) {
6250                        elems = i === last ? this : this.clone(true);
6251                        jQuery(insert[i])[original](elems);
6252
6253                        // Support: Android <=4.0 only, PhantomJS 1 only
6254                        // .get() because push.apply(_, arraylike) throws on ancient WebKit
6255                        push.apply(ret, elems.get());
6256                    }
6257
6258                    return this.pushStack(ret);
6259                };
6260            });
6261            var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i");
6262
6263            var rcustomProp = /^--/;
6264
6265
6266            var getStyles = function (elem) {
6267
6268                // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150)
6269                // IE throws on elements created in popups
6270                // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6271                var view = elem.ownerDocument.defaultView;
6272
6273                if (!view || !view.opener) {
6274                    view = window;
6275                }
6276
6277                return view.getComputedStyle(elem);
6278            };
6279
6280            var swap = function (elem, options, callback) {
6281                var ret, name,
6282                    old = {};
6283
6284                // Remember the old values, and insert the new ones
6285                for (name in options) {
6286                    old[name] = elem.style[name];
6287                    elem.style[name] = options[name];
6288                }
6289
6290                ret = callback.call(elem);
6291
6292                // Revert the old values
6293                for (name in options) {
6294                    elem.style[name] = old[name];
6295                }
6296
6297                return ret;
6298            };
6299
6300
6301            var rboxStyle = new RegExp(cssExpand.join("|"), "i");
6302
6303
6304            (function () {
6305
6306                // Executing both pixelPosition & boxSizingReliable tests require only one layout
6307                // so they're executed at the same time to save the second computation.
6308                function computeStyleTests() {
6309
6310                    // This is a singleton, we need to execute it only once
6311                    if (!div) {
6312                        return;
6313                    }
6314
6315                    container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
6316                        "margin-top:1px;padding:0;border:0";
6317                    div.style.cssText =
6318                        "position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
6319                        "margin:auto;border:1px;padding:1px;" +
6320                        "width:60%;top:1%";
6321                    documentElement.appendChild(container).appendChild(div);
6322
6323                    var divStyle = window.getComputedStyle(div);
6324                    pixelPositionVal = divStyle.top !== "1%";
6325
6326                    // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
6327                    reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12;
6328
6329                    // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
6330                    // Some styles come back with percentage values, even though they shouldn't
6331                    div.style.right = "60%";
6332                    pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36;
6333
6334                    // Support: IE 9 - 11 only
6335                    // Detect misreporting of content dimensions for box-sizing:border-box elements
6336                    boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36;
6337
6338                    // Support: IE 9 only
6339                    // Detect overflow:scroll screwiness (gh-3699)
6340                    // Support: Chrome <=64
6341                    // Don't get tricked when zoom affects offsetWidth (gh-4029)
6342                    div.style.position = "absolute";
6343                    scrollboxSizeVal = roundPixelMeasures(div.offsetWidth / 3) === 12;
6344
6345                    documentElement.removeChild(container);
6346
6347                    // Nullify the div so it wouldn't be stored in the memory and
6348                    // it will also be a sign that checks already performed
6349                    div = null;
6350                }
6351
6352                function roundPixelMeasures(measure) {
6353                    return Math.round(parseFloat(measure));
6354                }
6355
6356                var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
6357                    reliableTrDimensionsVal, reliableMarginLeftVal,
6358                    container = document.createElement("div"),
6359                    div = document.createElement("div");
6360
6361                // Finish early in limited (non-browser) environments
6362                if (!div.style) {
6363                    return;
6364                }
6365
6366                // Support: IE <=9 - 11 only
6367                // Style of cloned element affects source element cloned (trac-8908)
6368                div.style.backgroundClip = "content-box";
6369                div.cloneNode(true).style.backgroundClip = "";
6370                support.clearCloneStyle = div.style.backgroundClip === "content-box";
6371
6372                jQuery.extend(support, {
6373                    boxSizingReliable: function () {
6374                        computeStyleTests();
6375                        return boxSizingReliableVal;
6376                    },
6377                    pixelBoxStyles: function () {
6378                        computeStyleTests();
6379                        return pixelBoxStylesVal;
6380                    },
6381                    pixelPosition: function () {
6382                        computeStyleTests();
6383                        return pixelPositionVal;
6384                    },
6385                    reliableMarginLeft: function () {
6386                        computeStyleTests();
6387                        return reliableMarginLeftVal;
6388                    },
6389                    scrollboxSize: function () {
6390                        computeStyleTests();
6391                        return scrollboxSizeVal;
6392                    },
6393
6394                    // Support: IE 9 - 11+, Edge 15 - 18+
6395                    // IE/Edge misreport `getComputedStyle` of table rows with width/height
6396                    // set in CSS while `offset*` properties report correct values.
6397                    // Behavior in IE 9 is more subtle than in newer versions & it passes
6398                    // some versions of this test; make sure not to make it pass there!
6399                    //
6400                    // Support: Firefox 70+
6401                    // Only Firefox includes border widths
6402                    // in computed dimensions. (gh-4529)
6403                    reliableTrDimensions: function () {
6404                        var table, tr, trChild, trStyle;
6405                        if (reliableTrDimensionsVal == null) {
6406                            table = document.createElement("table");
6407                            tr = document.createElement("tr");
6408                            trChild = document.createElement("div");
6409
6410                            table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate";
6411                            tr.style.cssText = "box-sizing:content-box;border:1px solid";
6412
6413                            // Support: Chrome 86+
6414                            // Height set through cssText does not get applied.
6415                            // Computed height then comes back as 0.
6416                            tr.style.height = "1px";
6417                            trChild.style.height = "9px";
6418
6419                            // Support: Android 8 Chrome 86+
6420                            // In our bodyBackground.html iframe,
6421                            // display for all div elements is set to "inline",
6422                            // which causes a problem only in Android 8 Chrome 86.
6423                            // Ensuring the div is `display: block`
6424                            // gets around this issue.
6425                            trChild.style.display = "block";
6426
6427                            documentElement
6428                                .appendChild(table)
6429                                .appendChild(tr)
6430                                .appendChild(trChild);
6431
6432                            trStyle = window.getComputedStyle(tr);
6433                            reliableTrDimensionsVal = (parseInt(trStyle.height, 10) +
6434                                parseInt(trStyle.borderTopWidth, 10) +
6435                                parseInt(trStyle.borderBottomWidth, 10)) === tr.offsetHeight;
6436
6437                            documentElement.removeChild(table);
6438                        }
6439                        return reliableTrDimensionsVal;
6440                    }
6441                });
6442            })();
6443
6444
6445            function curCSS(elem, name, computed) {
6446                var width, minWidth, maxWidth, ret,
6447                    isCustomProp = rcustomProp.test(name),
6448
6449                    // Support: Firefox 51+
6450                    // Retrieving style before computed somehow
6451                    // fixes an issue with getting wrong values
6452                    // on detached elements
6453                    style = elem.style;
6454
6455                computed = computed || getStyles(elem);
6456
6457                // getPropertyValue is needed for:
6458                //   .css('filter') (IE 9 only, trac-12537)
6459                //   .css('--customProperty) (gh-3144)
6460                if (computed) {
6461
6462                    // Support: IE <=9 - 11+
6463                    // IE only supports `"float"` in `getPropertyValue`; in computed styles
6464                    // it's only available as `"cssFloat"`. We no longer modify properties
6465                    // sent to `.css()` apart from camelCasing, so we need to check both.
6466                    // Normally, this would create difference in behavior: if
6467                    // `getPropertyValue` returns an empty string, the value returned
6468                    // by `.css()` would be `undefined`. This is usually the case for
6469                    // disconnected elements. However, in IE even disconnected elements
6470                    // with no styles return `"none"` for `getPropertyValue( "float" )`
6471                    ret = computed.getPropertyValue(name) || computed[name];
6472
6473                    if (isCustomProp && ret) {
6474
6475                        // Support: Firefox 105+, Chrome <=105+
6476                        // Spec requires trimming whitespace for custom properties (gh-4926).
6477                        // Firefox only trims leading whitespace. Chrome just collapses
6478                        // both leading & trailing whitespace to a single space.
6479                        //
6480                        // Fall back to `undefined` if empty string returned.
6481                        // This collapses a missing definition with property defined
6482                        // and set to an empty string but there's no standard API
6483                        // allowing us to differentiate them without a performance penalty
6484                        // and returning `undefined` aligns with older jQuery.
6485                        //
6486                        // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED
6487                        // as whitespace while CSS does not, but this is not a problem
6488                        // because CSS preprocessing replaces them with U+000A LINE FEED
6489                        // (which *is* CSS whitespace)
6490                        // https://www.w3.org/TR/css-syntax-3/#input-preprocessing
6491                        ret = ret.replace(rtrimCSS, "$1") || undefined;
6492                    }
6493
6494                    if (ret === "" && !isAttached(elem)) {
6495                        ret = jQuery.style(elem, name);
6496                    }
6497
6498                    // A tribute to the "awesome hack by Dean Edwards"
6499                    // Android Browser returns percentage for some values,
6500                    // but width seems to be reliably pixels.
6501                    // This is against the CSSOM draft spec:
6502                    // https://drafts.csswg.org/cssom/#resolved-values
6503                    if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) {
6504
6505                        // Remember the original values
6506                        width = style.width;
6507                        minWidth = style.minWidth;
6508                        maxWidth = style.maxWidth;
6509
6510                        // Put in the new values to get a computed value out
6511                        style.minWidth = style.maxWidth = style.width = ret;
6512                        ret = computed.width;
6513
6514                        // Revert the changed values
6515                        style.width = width;
6516                        style.minWidth = minWidth;
6517                        style.maxWidth = maxWidth;
6518                    }
6519                }
6520
6521                return ret !== undefined ?
6522
6523                    // Support: IE <=9 - 11 only
6524                    // IE returns zIndex value as an integer.
6525                    ret + "" :
6526                    ret;
6527            }
6528
6529
6530            function addGetHookIf(conditionFn, hookFn) {
6531
6532                // Define the hook, we'll check on the first run if it's really needed.
6533                return {
6534                    get: function () {
6535                        if (conditionFn()) {
6536
6537                            // Hook not needed (or it's not possible to use it due
6538                            // to missing dependency), remove it.
6539                            delete this.get;
6540                            return;
6541                        }
6542
6543                        // Hook needed; redefine it so that the support test is not executed again.
6544                        return (this.get = hookFn).apply(this, arguments);
6545                    }
6546                };
6547            }
6548
6549
6550            var cssPrefixes = ["Webkit", "Moz", "ms"],
6551                emptyStyle = document.createElement("div").style,
6552                vendorProps = {};
6553
6554            // Return a vendor-prefixed property or undefined
6555            function vendorPropName(name) {
6556
6557                // Check for vendor prefixed names
6558                var capName = name[0].toUpperCase() + name.slice(1),
6559                    i = cssPrefixes.length;
6560
6561                while (i--) {
6562                    name = cssPrefixes[i] + capName;
6563                    if (name in emptyStyle) {
6564                        return name;
6565                    }
6566                }
6567            }
6568
6569            // Return a potentially-mapped jQuery.cssProps or vendor prefixed property
6570            function finalPropName(name) {
6571                var final = jQuery.cssProps[name] || vendorProps[name];
6572
6573                if (final) {
6574                    return final;
6575                }
6576                if (name in emptyStyle) {
6577                    return name;
6578                }
6579                return vendorProps[name] = vendorPropName(name) || name;
6580            }
6581
6582
6583            var
6584
6585                // Swappable if display is none or starts with table
6586                // except "table", "table-cell", or "table-caption"
6587                // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6588                rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6589                cssShow = {position: "absolute", visibility: "hidden", display: "block"},
6590                cssNormalTransform = {
6591                    letterSpacing: "0",
6592                    fontWeight: "400"
6593                };
6594
6595            function setPositiveNumber(_elem, value, subtract) {
6596
6597                // Any relative (+/-) values have already been
6598                // normalized at this point
6599                var matches = rcssNum.exec(value);
6600                return matches ?
6601
6602                    // Guard against undefined "subtract", e.g., when used as in cssHooks
6603                    Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") :
6604                    value;
6605            }
6606
6607            function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) {
6608                var i = dimension === "width" ? 1 : 0,
6609                    extra = 0,
6610                    delta = 0,
6611                    marginDelta = 0;
6612
6613                // Adjustment may not be necessary
6614                if (box === (isBorderBox ? "border" : "content")) {
6615                    return 0;
6616                }
6617
6618                for (; i < 4; i += 2) {
6619
6620                    // Both box models exclude margin
6621                    // Count margin delta separately to only add it after scroll gutter adjustment.
6622                    // This is needed to make negative margins work with `outerHeight( true )` (gh-3982).
6623                    if (box === "margin") {
6624                        marginDelta += jQuery.css(elem, box + cssExpand[i], true, styles);
6625                    }
6626
6627                    // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
6628                    if (!isBorderBox) {
6629
6630                        // Add padding
6631                        delta += jQuery.css(elem, "padding" + cssExpand[i], true, styles);
6632
6633                        // For "border" or "margin", add border
6634                        if (box !== "padding") {
6635                            delta += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
6636
6637                            // But still keep track of it otherwise
6638                        } else {
6639                            extra += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
6640                        }
6641
6642                        // If we get here with a border-box (content + padding + border), we're seeking "content" or
6643                        // "padding" or "margin"
6644                    } else {
6645
6646                        // For "content", subtract padding
6647                        if (box === "content") {
6648                            delta -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
6649                        }
6650
6651                        // For "content" or "padding", subtract border
6652                        if (box !== "margin") {
6653                            delta -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
6654                        }
6655                    }
6656                }
6657
6658                // Account for positive content-box scroll gutter when requested by providing computedVal
6659                if (!isBorderBox && computedVal >= 0) {
6660
6661                    // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
6662                    // Assuming integer scroll gutter, subtract the rest and round down
6663                    delta += Math.max(0, Math.ceil(
6664                        elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] -
6665                        computedVal -
6666                        delta -
6667                        extra -
6668                        0.5
6669
6670                        // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
6671                        // Use an explicit zero to avoid NaN (gh-3964)
6672                    )) || 0;
6673                }
6674
6675                return delta + marginDelta;
6676            }
6677
6678            function getWidthOrHeight(elem, dimension, extra) {
6679
6680                // Start with computed style
6681                var styles = getStyles(elem),
6682
6683                    // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
6684                    // Fake content-box until we know it's needed to know the true value.
6685                    boxSizingNeeded = !support.boxSizingReliable() || extra,
6686                    isBorderBox = boxSizingNeeded &&
6687                        jQuery.css(elem, "boxSizing", false, styles) === "border-box",
6688                    valueIsBorderBox = isBorderBox,
6689
6690                    val = curCSS(elem, dimension, styles),
6691                    offsetProp = "offset" + dimension[0].toUpperCase() + dimension.slice(1);
6692
6693                // Support: Firefox <=54
6694                // Return a confounding non-pixel value or feign ignorance, as appropriate.
6695                if (rnumnonpx.test(val)) {
6696                    if (!extra) {
6697                        return val;
6698                    }
6699                    val = "auto";
6700                }
6701
6702
6703                // Support: IE 9 - 11 only
6704                // Use offsetWidth/offsetHeight for when box sizing is unreliable.
6705                // In those cases, the computed value can be trusted to be border-box.
6706                if ((!support.boxSizingReliable() && isBorderBox ||
6707
6708                        // Support: IE 10 - 11+, Edge 15 - 18+
6709                        // IE/Edge misreport `getComputedStyle` of table rows with width/height
6710                        // set in CSS while `offset*` properties report correct values.
6711                        // Interestingly, in some cases IE 9 doesn't suffer from this issue.
6712                        !support.reliableTrDimensions() && nodeName(elem, "tr") ||
6713
6714                        // Fall back to offsetWidth/offsetHeight when value is "auto"
6715                        // This happens for inline elements with no explicit setting (gh-3571)
6716                        val === "auto" ||
6717
6718                        // Support: Android <=4.1 - 4.3 only
6719                        // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
6720                        !parseFloat(val) && jQuery.css(elem, "display", false, styles) === "inline") &&
6721
6722                    // Make sure the element is visible & connected
6723                    elem.getClientRects().length) {
6724
6725                    isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box";
6726
6727                    // Where available, offsetWidth/offsetHeight approximate border box dimensions.
6728                    // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
6729                    // retrieved value as a content box dimension.
6730                    valueIsBorderBox = offsetProp in elem;
6731                    if (valueIsBorderBox) {
6732                        val = elem[offsetProp];
6733                    }
6734                }
6735
6736                // Normalize "" and auto
6737                val = parseFloat(val) || 0;
6738
6739                // Adjust for the element's box model
6740                return (val +
6741                    boxModelAdjustment(
6742                        elem,
6743                        dimension,
6744                        extra || (isBorderBox ? "border" : "content"),
6745                        valueIsBorderBox,
6746                        styles,
6747
6748                        // Provide the current computed size to request scroll gutter calculation (gh-3589)
6749                        val
6750                    )
6751                ) + "px";
6752            }
6753
6754            jQuery.extend({
6755
6756                // Add in style property hooks for overriding the default
6757                // behavior of getting and setting a style property
6758                cssHooks: {
6759                    opacity: {
6760                        get: function (elem, computed) {
6761                            if (computed) {
6762
6763                                // We should always get a number back from opacity
6764                                var ret = curCSS(elem, "opacity");
6765                                return ret === "" ? "1" : ret;
6766                            }
6767                        }
6768                    }
6769                },
6770
6771                // Don't automatically add "px" to these possibly-unitless properties
6772                cssNumber: {
6773                    animationIterationCount: true,
6774                    aspectRatio: true,
6775                    borderImageSlice: true,
6776                    columnCount: true,
6777                    flexGrow: true,
6778                    flexShrink: true,
6779                    fontWeight: true,
6780                    gridArea: true,
6781                    gridColumn: true,
6782                    gridColumnEnd: true,
6783                    gridColumnStart: true,
6784                    gridRow: true,
6785                    gridRowEnd: true,
6786                    gridRowStart: true,
6787                    lineHeight: true,
6788                    opacity: true,
6789                    order: true,
6790                    orphans: true,
6791                    scale: true,
6792                    widows: true,
6793                    zIndex: true,
6794                    zoom: true,
6795
6796                    // SVG-related
6797                    fillOpacity: true,
6798                    floodOpacity: true,
6799                    stopOpacity: true,
6800                    strokeMiterlimit: true,
6801                    strokeOpacity: true
6802                },
6803
6804                // Add in properties whose names you wish to fix before
6805                // setting or getting the value
6806                cssProps: {},
6807
6808                // Get and set the style property on a DOM Node
6809                style: function (elem, name, value, extra) {
6810
6811                    // Don't set styles on text and comment nodes
6812                    if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
6813                        return;
6814                    }
6815
6816                    // Make sure that we're working with the right name
6817                    var ret, type, hooks,
6818                        origName = camelCase(name),
6819                        isCustomProp = rcustomProp.test(name),
6820                        style = elem.style;
6821
6822                    // Make sure that we're working with the right name. We don't
6823                    // want to query the value if it is a CSS custom property
6824                    // since they are user-defined.
6825                    if (!isCustomProp) {
6826                        name = finalPropName(origName);
6827                    }
6828
6829                    // Gets hook for the prefixed version, then unprefixed version
6830                    hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
6831
6832                    // Check if we're setting a value
6833                    if (value !== undefined) {
6834                        type = typeof value;
6835
6836                        // Convert "+=" or "-=" to relative numbers (trac-7345)
6837                        if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) {
6838                            value = adjustCSS(elem, name, ret);
6839
6840                            // Fixes bug trac-9237
6841                            type = "number";
6842                        }
6843
6844                        // Make sure that null and NaN values aren't set (trac-7116)
6845                        if (value == null || value !== value) {
6846                            return;
6847                        }
6848
6849                        // If a number was passed in, add the unit (except for certain CSS properties)
6850                        // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
6851                        // "px" to a few hardcoded values.
6852                        if (type === "number" && !isCustomProp) {
6853                            value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px");
6854                        }
6855
6856                        // background-* props affect original clone's values
6857                        if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
6858                            style[name] = "inherit";
6859                        }
6860
6861                        // If a hook was provided, use that value, otherwise just set the specified value
6862                        if (!hooks || !("set" in hooks) ||
6863                            (value = hooks.set(elem, value, extra)) !== undefined) {
6864
6865                            if (isCustomProp) {
6866                                style.setProperty(name, value);
6867                            } else {
6868                                style[name] = value;
6869                            }
6870                        }
6871
6872                    } else {
6873
6874                        // If a hook was provided get the non-computed value from there
6875                        if (hooks && "get" in hooks &&
6876                            (ret = hooks.get(elem, false, extra)) !== undefined) {
6877
6878                            return ret;
6879                        }
6880
6881                        // Otherwise just get the value from the style object
6882                        return style[name];
6883                    }
6884                },
6885
6886                css: function (elem, name, extra, styles) {
6887                    var val, num, hooks,
6888                        origName = camelCase(name),
6889                        isCustomProp = rcustomProp.test(name);
6890
6891                    // Make sure that we're working with the right name. We don't
6892                    // want to modify the value if it is a CSS custom property
6893                    // since they are user-defined.
6894                    if (!isCustomProp) {
6895                        name = finalPropName(origName);
6896                    }
6897
6898                    // Try prefixed name followed by the unprefixed name
6899                    hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
6900
6901                    // If a hook was provided get the computed value from there
6902                    if (hooks && "get" in hooks) {
6903                        val = hooks.get(elem, true, extra);
6904                    }
6905
6906                    // Otherwise, if a way to get the computed value exists, use that
6907                    if (val === undefined) {
6908                        val = curCSS(elem, name, styles);
6909                    }
6910
6911                    // Convert "normal" to computed value
6912                    if (val === "normal" && name in cssNormalTransform) {
6913                        val = cssNormalTransform[name];
6914                    }
6915
6916                    // Make numeric if forced or a qualifier was provided and val looks numeric
6917                    if (extra === "" || extra) {
6918                        num = parseFloat(val);
6919                        return extra === true || isFinite(num) ? num || 0 : val;
6920                    }
6921
6922                    return val;
6923                }
6924            });
6925
6926            jQuery.each(["height", "width"], function (_i, dimension) {
6927                jQuery.cssHooks[dimension] = {
6928                    get: function (elem, computed, extra) {
6929                        if (computed) {
6930
6931                            // Certain elements can have dimension info if we invisibly show them
6932                            // but it must have a current display style that would benefit
6933                            return rdisplayswap.test(jQuery.css(elem, "display")) &&
6934
6935                            // Support: Safari 8+
6936                            // Table columns in Safari have non-zero offsetWidth & zero
6937                            // getBoundingClientRect().width unless display is changed.
6938                            // Support: IE <=11 only
6939                            // Running getBoundingClientRect on a disconnected node
6940                            // in IE throws an error.
6941                            (!elem.getClientRects().length || !elem.getBoundingClientRect().width) ?
6942                                swap(elem, cssShow, function () {
6943                                    return getWidthOrHeight(elem, dimension, extra);
6944                                }) :
6945                                getWidthOrHeight(elem, dimension, extra);
6946                        }
6947                    },
6948
6949                    set: function (elem, value, extra) {
6950                        var matches,
6951                            styles = getStyles(elem),
6952
6953                            // Only read styles.position if the test has a chance to fail
6954                            // to avoid forcing a reflow.
6955                            scrollboxSizeBuggy = !support.scrollboxSize() &&
6956                                styles.position === "absolute",
6957
6958                            // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
6959                            boxSizingNeeded = scrollboxSizeBuggy || extra,
6960                            isBorderBox = boxSizingNeeded &&
6961                                jQuery.css(elem, "boxSizing", false, styles) === "border-box",
6962                            subtract = extra ?
6963                                boxModelAdjustment(
6964                                    elem,
6965                                    dimension,
6966                                    extra,
6967                                    isBorderBox,
6968                                    styles
6969                                ) :
6970                                0;
6971
6972                        // Account for unreliable border-box dimensions by comparing offset* to computed and
6973                        // faking a content-box to get border and padding (gh-3699)
6974                        if (isBorderBox && scrollboxSizeBuggy) {
6975                            subtract -= Math.ceil(
6976                                elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] -
6977                                parseFloat(styles[dimension]) -
6978                                boxModelAdjustment(elem, dimension, "border", false, styles) -
6979                                0.5
6980                            );
6981                        }
6982
6983                        // Convert to pixels if value adjustment is needed
6984                        if (subtract && (matches = rcssNum.exec(value)) &&
6985                            (matches[3] || "px") !== "px") {
6986
6987                            elem.style[dimension] = value;
6988                            value = jQuery.css(elem, dimension);
6989                        }
6990
6991                        return setPositiveNumber(elem, value, subtract);
6992                    }
6993                };
6994            });
6995
6996            jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft,
6997                function (elem, computed) {
6998                    if (computed) {
6999                        return (parseFloat(curCSS(elem, "marginLeft")) ||
7000                            elem.getBoundingClientRect().left -
7001                            swap(elem, {marginLeft: 0}, function () {
7002                                return elem.getBoundingClientRect().left;
7003                            })
7004                        ) + "px";
7005                    }
7006                }
7007            );
7008
7009            // These hooks are used by animate to expand properties
7010            jQuery.each({
7011                margin: "",
7012                padding: "",
7013                border: "Width"
7014            }, function (prefix, suffix) {
7015                jQuery.cssHooks[prefix + suffix] = {
7016                    expand: function (value) {
7017                        var i = 0,
7018                            expanded = {},
7019
7020                            // Assumes a single number if not a string
7021                            parts = typeof value === "string" ? value.split(" ") : [value];
7022
7023                        for (; i < 4; i++) {
7024                            expanded[prefix + cssExpand[i] + suffix] =
7025                                parts[i] || parts[i - 2] || parts[0];
7026                        }
7027
7028                        return expanded;
7029                    }
7030                };
7031
7032                if (prefix !== "margin") {
7033                    jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
7034                }
7035            });
7036
7037            jQuery.fn.extend({
7038                css: function (name, value) {
7039                    return access(this, function (elem, name, value) {
7040                        var styles, len,
7041                            map = {},
7042                            i = 0;
7043
7044                        if (Array.isArray(name)) {
7045                            styles = getStyles(elem);
7046                            len = name.length;
7047
7048                            for (; i < len; i++) {
7049                                map[name[i]] = jQuery.css(elem, name[i], false, styles);
7050                            }
7051
7052                            return map;
7053                        }
7054
7055                        return value !== undefined ?
7056                            jQuery.style(elem, name, value) :
7057                            jQuery.css(elem, name);
7058                    }, name, value, arguments.length > 1);
7059                }
7060            });
7061
7062
7063            function Tween(elem, options, prop, end, easing) {
7064                return new Tween.prototype.init(elem, options, prop, end, easing);
7065            }
7066
7067            jQuery.Tween = Tween;
7068
7069            Tween.prototype = {
7070                constructor: Tween,
7071                init: function (elem, options, prop, end, easing, unit) {
7072                    this.elem = elem;
7073                    this.prop = prop;
7074                    this.easing = easing || jQuery.easing._default;
7075                    this.options = options;
7076                    this.start = this.now = this.cur();
7077                    this.end = end;
7078                    this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px");
7079                },
7080                cur: function () {
7081                    var hooks = Tween.propHooks[this.prop];
7082
7083                    return hooks && hooks.get ?
7084                        hooks.get(this) :
7085                        Tween.propHooks._default.get(this);
7086                },
7087                run: function (percent) {
7088                    var eased,
7089                        hooks = Tween.propHooks[this.prop];
7090
7091                    if (this.options.duration) {
7092                        this.pos = eased = jQuery.easing[this.easing](
7093                            percent, this.options.duration * percent, 0, 1, this.options.duration
7094                        );
7095                    } else {
7096                        this.pos = eased = percent;
7097                    }
7098                    this.now = (this.end - this.start) * eased + this.start;
7099
7100                    if (this.options.step) {
7101                        this.options.step.call(this.elem, this.now, this);
7102                    }
7103
7104                    if (hooks && hooks.set) {
7105                        hooks.set(this);
7106                    } else {
7107                        Tween.propHooks._default.set(this);
7108                    }
7109                    return this;
7110                }
7111            };
7112
7113            Tween.prototype.init.prototype = Tween.prototype;
7114
7115            Tween.propHooks = {
7116                _default: {
7117                    get: function (tween) {
7118                        var result;
7119
7120                        // Use a property on the element directly when it is not a DOM element,
7121                        // or when there is no matching style property that exists.
7122                        if (tween.elem.nodeType !== 1 ||
7123                            tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) {
7124                            return tween.elem[tween.prop];
7125                        }
7126
7127                        // Passing an empty string as a 3rd parameter to .css will automatically
7128                        // attempt a parseFloat and fallback to a string if the parse fails.
7129                        // Simple values such as "10px" are parsed to Float;
7130                        // complex values such as "rotate(1rad)" are returned as-is.
7131                        result = jQuery.css(tween.elem, tween.prop, "");
7132
7133                        // Empty strings, null, undefined and "auto" are converted to 0.
7134                        return !result || result === "auto" ? 0 : result;
7135                    },
7136                    set: function (tween) {
7137
7138                        // Use step hook for back compat.
7139                        // Use cssHook if its there.
7140                        // Use .style if available and use plain properties where available.
7141                        if (jQuery.fx.step[tween.prop]) {
7142                            jQuery.fx.step[tween.prop](tween);
7143                        } else if (tween.elem.nodeType === 1 && (
7144                            jQuery.cssHooks[tween.prop] ||
7145                            tween.elem.style[finalPropName(tween.prop)] != null)) {
7146                            jQuery.style(tween.elem, tween.prop, tween.now + tween.unit);
7147                        } else {
7148                            tween.elem[tween.prop] = tween.now;
7149                        }
7150                    }
7151                }
7152            };
7153
7154            // Support: IE <=9 only
7155            // Panic based approach to setting things on disconnected nodes
7156            Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7157                set: function (tween) {
7158                    if (tween.elem.nodeType && tween.elem.parentNode) {
7159                        tween.elem[tween.prop] = tween.now;
7160                    }
7161                }
7162            };
7163
7164            jQuery.easing = {
7165                linear: function (p) {
7166                    return p;
7167                },
7168                swing: function (p) {
7169                    return 0.5 - Math.cos(p * Math.PI) / 2;
7170                },
7171                _default: "swing"
7172            };
7173
7174            jQuery.fx = Tween.prototype.init;
7175
7176            // Back compat <1.8 extension point
7177            jQuery.fx.step = {};
7178
7179
7180            var
7181                fxNow, inProgress,
7182                rfxtypes = /^(?:toggle|show|hide)$/,
7183                rrun = /queueHooks$/;
7184
7185            function schedule() {
7186                if (inProgress) {
7187                    if (document.hidden === false && window.requestAnimationFrame) {
7188                        window.requestAnimationFrame(schedule);
7189                    } else {
7190                        window.setTimeout(schedule, jQuery.fx.interval);
7191                    }
7192
7193                    jQuery.fx.tick();
7194                }
7195            }
7196
7197            // Animations created synchronously will run synchronously
7198            function createFxNow() {
7199                window.setTimeout(function () {
7200                    fxNow = undefined;
7201                });
7202                return (fxNow = Date.now());
7203            }
7204
7205            // Generate parameters to create a standard animation
7206            function genFx(type, includeWidth) {
7207                var which,
7208                    i = 0,
7209                    attrs = {height: type};
7210
7211                // If we include width, step value is 1 to do all cssExpand values,
7212                // otherwise step value is 2 to skip over Left and Right
7213                includeWidth = includeWidth ? 1 : 0;
7214                for (; i < 4; i += 2 - includeWidth) {
7215                    which = cssExpand[i];
7216                    attrs["margin" + which] = attrs["padding" + which] = type;
7217                }
7218
7219                if (includeWidth) {
7220                    attrs.opacity = attrs.width = type;
7221                }
7222
7223                return attrs;
7224            }
7225
7226            function createTween(value, prop, animation) {
7227                var tween,
7228                    collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]),
7229                    index = 0,
7230                    length = collection.length;
7231                for (; index < length; index++) {
7232                    if ((tween = collection[index].call(animation, prop, value))) {
7233
7234                        // We're done with this property
7235                        return tween;
7236                    }
7237                }
7238            }
7239
7240            function defaultPrefilter(elem, props, opts) {
7241                var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
7242                    isBox = "width" in props || "height" in props,
7243                    anim = this,
7244                    orig = {},
7245                    style = elem.style,
7246                    hidden = elem.nodeType && isHiddenWithinTree(elem),
7247                    dataShow = dataPriv.get(elem, "fxshow");
7248
7249                // Queue-skipping animations hijack the fx hooks
7250                if (!opts.queue) {
7251                    hooks = jQuery._queueHooks(elem, "fx");
7252                    if (hooks.unqueued == null) {
7253                        hooks.unqueued = 0;
7254                        oldfire = hooks.empty.fire;
7255                        hooks.empty.fire = function () {
7256                            if (!hooks.unqueued) {
7257                                oldfire();
7258                            }
7259                        };
7260                    }
7261                    hooks.unqueued++;
7262
7263                    anim.always(function () {
7264
7265                        // Ensure the complete handler is called before this completes
7266                        anim.always(function () {
7267                            hooks.unqueued--;
7268                            if (!jQuery.queue(elem, "fx").length) {
7269                                hooks.empty.fire();
7270                            }
7271                        });
7272                    });
7273                }
7274
7275                // Detect show/hide animations
7276                for (prop in props) {
7277                    value = props[prop];
7278                    if (rfxtypes.test(value)) {
7279                        delete props[prop];
7280                        toggle = toggle || value === "toggle";
7281                        if (value === (hidden ? "hide" : "show")) {
7282
7283                            // Pretend to be hidden if this is a "show" and
7284                            // there is still data from a stopped show/hide
7285                            if (value === "show" && dataShow && dataShow[prop] !== undefined) {
7286                                hidden = true;
7287
7288                                // Ignore all other no-op show/hide data
7289                            } else {
7290                                continue;
7291                            }
7292                        }
7293                        orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);
7294                    }
7295                }
7296
7297                // Bail out if this is a no-op like .hide().hide()
7298                propTween = !jQuery.isEmptyObject(props);
7299                if (!propTween && jQuery.isEmptyObject(orig)) {
7300                    return;
7301                }
7302
7303                // Restrict "overflow" and "display" styles during box animations
7304                if (isBox && elem.nodeType === 1) {
7305
vendor: 6,061 bytes, lines 7306-7443
7306                    // Support: IE <=9 - 11, Edge 12 - 15
7307                    // Record all 3 overflow attributes because IE does not infer the shorthand
7308                    // from identically-valued overflowX and overflowY and Edge just mirrors
7309                    // the overflowX value there.
7310                    opts.overflow = [style.overflow, style.overflowX, style.overflowY];
7311
7312                    // Identify a display type, preferring old show/hide data over the CSS cascade
7313                    restoreDisplay = dataShow && dataShow.display;
7314                    if (restoreDisplay == null) {
7315                        restoreDisplay = dataPriv.get(elem, "display");
7316                    }
7317                    display = jQuery.css(elem, "display");
7318                    if (display === "none") {
7319                        if (restoreDisplay) {
7320                            display = restoreDisplay;
7321                        } else {
7322
7323                            // Get nonempty value(s) by temporarily forcing visibility
7324                            showHide([elem], true);
7325                            restoreDisplay = elem.style.display || restoreDisplay;
7326                            display = jQuery.css(elem, "display");
7327                            showHide([elem]);
7328                        }
7329                    }
7330
7331                    // Animate inline elements as inline-block
7332                    if (display === "inline" || display === "inline-block" && restoreDisplay != null) {
7333                        if (jQuery.css(elem, "float") === "none") {
7334
7335                            // Restore the original display value at the end of pure show/hide animations
7336                            if (!propTween) {
7337                                anim.done(function () {
7338                                    style.display = restoreDisplay;
7339                                });
7340                                if (restoreDisplay == null) {
7341                                    display = style.display;
7342                                    restoreDisplay = display === "none" ? "" : display;
7343                                }
7344                            }
7345                            style.display = "inline-block";
7346                        }
7347                    }
7348                }
7349
7350                if (opts.overflow) {
7351                    style.overflow = "hidden";
7352                    anim.always(function () {
7353                        style.overflow = opts.overflow[0];
7354                        style.overflowX = opts.overflow[1];
7355                        style.overflowY = opts.overflow[2];
7356                    });
7357                }
7358
7359                // Implement show/hide animations
7360                propTween = false;
7361                for (prop in orig) {
7362
7363                    // General show/hide setup for this element animation
7364                    if (!propTween) {
7365                        if (dataShow) {
7366                            if ("hidden" in dataShow) {
7367                                hidden = dataShow.hidden;
7368                            }
7369                        } else {
7370                            dataShow = dataPriv.access(elem, "fxshow", {display: restoreDisplay});
7371                        }
7372
7373                        // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
7374                        if (toggle) {
7375                            dataShow.hidden = !hidden;
7376                        }
7377
7378                        // Show elements before animating them
7379                        if (hidden) {
7380                            showHide([elem], true);
7381                        }
7382
7383                        /* eslint-disable no-loop-func */
7384
7385                        anim.done(function () {
7386
7387                            /* eslint-enable no-loop-func */
7388
7389                            // The final step of a "hide" animation is actually hiding the element
7390                            if (!hidden) {
7391                                showHide([elem]);
7392                            }
7393                            dataPriv.remove(elem, "fxshow");
7394                            for (prop in orig) {
7395                                jQuery.style(elem, prop, orig[prop]);
7396                            }
7397                        });
7398                    }
7399
7400                    // Per-property setup
7401                    propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim);
7402                    if (!(prop in dataShow)) {
7403                        dataShow[prop] = propTween.start;
7404                        if (hidden) {
7405                            propTween.end = propTween.start;
7406                            propTween.start = 0;
7407                        }
7408                    }
7409                }
7410            }
7411
7412            function propFilter(props, specialEasing) {
7413                var index, name, easing, value, hooks;
7414
7415                // camelCase, specialEasing and expand cssHook pass
7416                for (index in props) {
7417                    name = camelCase(index);
7418                    easing = specialEasing[name];
7419                    value = props[index];
7420                    if (Array.isArray(value)) {
7421                        easing = value[1];
7422                        value = props[index] = value[0];
7423                    }
7424
7425                    if (index !== name) {
7426                        props[name] = value;
7427                        delete props[index];
7428                    }
7429
7430                    hooks = jQuery.cssHooks[name];
7431                    if (hooks && "expand" in hooks) {
7432                        value = hooks.expand(value);
7433                        delete props[name];
7434
7435                        // Not quite $.extend, this won't overwrite existing keys.
7436                        // Reusing 'index' because we have the correct "name"
7437                        for (index in value) {
7438                            if (!(index in props)) {
7439                                props[index] = value[index];
7440                                specialEasing[index] = easing;
7441                            }
7442                        }
7443                    } else {
vendor: 59,192 bytes, lines 7444-8938
7444                        specialEasing[name] = easing;
7445                    }
7446                }
7447            }
7448
7449            function Animation(elem, properties, options) {
7450                var result,
7451                    stopped,
7452                    index = 0,
7453                    length = Animation.prefilters.length,
7454                    deferred = jQuery.Deferred().always(function () {
7455
7456                        // Don't match elem in the :animated selector
7457                        delete tick.elem;
7458                    }),
7459                    tick = function () {
7460                        if (stopped) {
7461                            return false;
7462                        }
7463                        var currentTime = fxNow || createFxNow(),
7464                            remaining = Math.max(0, animation.startTime + animation.duration - currentTime),
7465
7466                            // Support: Android 2.3 only
7467                            // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497)
7468                            temp = remaining / animation.duration || 0,
7469                            percent = 1 - temp,
7470                            index = 0,
7471                            length = animation.tweens.length;
7472
7473                        for (; index < length; index++) {
7474                            animation.tweens[index].run(percent);
7475                        }
7476
7477                        deferred.notifyWith(elem, [animation, percent, remaining]);
7478
7479                        // If there's more to do, yield
7480                        if (percent < 1 && length) {
7481                            return remaining;
7482                        }
7483
7484                        // If this was an empty animation, synthesize a final progress notification
7485                        if (!length) {
7486                            deferred.notifyWith(elem, [animation, 1, 0]);
7487                        }
7488
7489                        // Resolve the animation and report its conclusion
7490                        deferred.resolveWith(elem, [animation]);
7491                        return false;
7492                    },
7493                    animation = deferred.promise({
7494                        elem: elem,
7495                        props: jQuery.extend({}, properties),
7496                        opts: jQuery.extend(true, {
7497                            specialEasing: {},
7498                            easing: jQuery.easing._default
7499                        }, options),
7500                        originalProperties: properties,
7501                        originalOptions: options,
7502                        startTime: fxNow || createFxNow(),
7503                        duration: options.duration,
7504                        tweens: [],
7505                        createTween: function (prop, end) {
7506                            var tween = jQuery.Tween(elem, animation.opts, prop, end,
7507                                animation.opts.specialEasing[prop] || animation.opts.easing);
7508                            animation.tweens.push(tween);
7509                            return tween;
7510                        },
7511                        stop: function (gotoEnd) {
7512                            var index = 0,
7513
7514                                // If we are going to the end, we want to run all the tweens
7515                                // otherwise we skip this part
7516                                length = gotoEnd ? animation.tweens.length : 0;
7517                            if (stopped) {
7518                                return this;
7519                            }
7520                            stopped = true;
7521                            for (; index < length; index++) {
7522                                animation.tweens[index].run(1);
7523                            }
7524
7525                            // Resolve when we played the last frame; otherwise, reject
7526                            if (gotoEnd) {
7527                                deferred.notifyWith(elem, [animation, 1, 0]);
7528                                deferred.resolveWith(elem, [animation, gotoEnd]);
7529                            } else {
7530                                deferred.rejectWith(elem, [animation, gotoEnd]);
7531                            }
7532                            return this;
7533                        }
7534                    }),
7535                    props = animation.props;
7536
7537                propFilter(props, animation.opts.specialEasing);
7538
7539                for (; index < length; index++) {
7540                    result = Animation.prefilters[index].call(animation, elem, props, animation.opts);
7541                    if (result) {
7542                        if (isFunction(result.stop)) {
7543                            jQuery._queueHooks(animation.elem, animation.opts.queue).stop =
7544                                result.stop.bind(result);
7545                        }
7546                        return result;
7547                    }
7548                }
7549
7550                jQuery.map(props, createTween, animation);
7551
7552                if (isFunction(animation.opts.start)) {
7553                    animation.opts.start.call(elem, animation);
7554                }
7555
7556                // Attach callbacks from options
7557                animation
7558                    .progress(animation.opts.progress)
7559                    .done(animation.opts.done, animation.opts.complete)
7560                    .fail(animation.opts.fail)
7561                    .always(animation.opts.always);
7562
7563                jQuery.fx.timer(
7564                    jQuery.extend(tick, {
7565                        elem: elem,
7566                        anim: animation,
7567                        queue: animation.opts.queue
7568                    })
7569                );
7570
7571                return animation;
7572            }
7573
7574            jQuery.Animation = jQuery.extend(Animation, {
7575
7576                tweeners: {
7577                    "*": [function (prop, value) {
7578                        var tween = this.createTween(prop, value);
7579                        adjustCSS(tween.elem, prop, rcssNum.exec(value), tween);
7580                        return tween;
7581                    }]
7582                },
7583
7584                tweener: function (props, callback) {
7585                    if (isFunction(props)) {
7586                        callback = props;
7587                        props = ["*"];
7588                    } else {
7589                        props = props.match(rnothtmlwhite);
7590                    }
7591
7592                    var prop,
7593                        index = 0,
7594                        length = props.length;
7595
7596                    for (; index < length; index++) {
7597                        prop = props[index];
7598                        Animation.tweeners[prop] = Animation.tweeners[prop] || [];
7599                        Animation.tweeners[prop].unshift(callback);
7600                    }
7601                },
7602
7603                prefilters: [defaultPrefilter],
7604
7605                prefilter: function (callback, prepend) {
7606                    if (prepend) {
7607                        Animation.prefilters.unshift(callback);
7608                    } else {
7609                        Animation.prefilters.push(callback);
7610                    }
7611                }
7612            });
7613
7614            jQuery.speed = function (speed, easing, fn) {
7615                var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
7616                    complete: fn || !fn && easing ||
7617                        isFunction(speed) && speed,
7618                    duration: speed,
7619                    easing: fn && easing || easing && !isFunction(easing) && easing
7620                };
7621
7622                // Go to the end state if fx are off
7623                if (jQuery.fx.off) {
7624                    opt.duration = 0;
7625
7626                } else {
7627                    if (typeof opt.duration !== "number") {
7628                        if (opt.duration in jQuery.fx.speeds) {
7629                            opt.duration = jQuery.fx.speeds[opt.duration];
7630
7631                        } else {
7632                            opt.duration = jQuery.fx.speeds._default;
7633                        }
7634                    }
7635                }
7636
7637                // Normalize opt.queue - true/undefined/null -> "fx"
7638                if (opt.queue == null || opt.queue === true) {
7639                    opt.queue = "fx";
7640                }
7641
7642                // Queueing
7643                opt.old = opt.complete;
7644
7645                opt.complete = function () {
7646                    if (isFunction(opt.old)) {
7647                        opt.old.call(this);
7648                    }
7649
7650                    if (opt.queue) {
7651                        jQuery.dequeue(this, opt.queue);
7652                    }
7653                };
7654
7655                return opt;
7656            };
7657
7658            jQuery.fn.extend({
7659                fadeTo: function (speed, to, easing, callback) {
7660
7661                    // Show any hidden elements after setting opacity to 0
7662                    return this.filter(isHiddenWithinTree).css("opacity", 0).show()
7663
7664                        // Animate to the value specified
7665                        .end().animate({opacity: to}, speed, easing, callback);
7666                },
7667                animate: function (prop, speed, easing, callback) {
7668                    var empty = jQuery.isEmptyObject(prop),
7669                        optall = jQuery.speed(speed, easing, callback),
7670                        doAnimation = function () {
7671
7672                            // Operate on a copy of prop so per-property easing won't be lost
7673                            var anim = Animation(this, jQuery.extend({}, prop), optall);
7674
7675                            // Empty animations, or finishing resolves immediately
7676                            if (empty || dataPriv.get(this, "finish")) {
7677                                anim.stop(true);
7678                            }
7679                        };
7680
7681                    doAnimation.finish = doAnimation;
7682
7683                    return empty || optall.queue === false ?
7684                        this.each(doAnimation) :
7685                        this.queue(optall.queue, doAnimation);
7686                },
7687                stop: function (type, clearQueue, gotoEnd) {
7688                    var stopQueue = function (hooks) {
7689                        var stop = hooks.stop;
7690                        delete hooks.stop;
7691                        stop(gotoEnd);
7692                    };
7693
7694                    if (typeof type !== "string") {
7695                        gotoEnd = clearQueue;
7696                        clearQueue = type;
7697                        type = undefined;
7698                    }
7699                    if (clearQueue) {
7700                        this.queue(type || "fx", []);
7701                    }
7702
7703                    return this.each(function () {
7704                        var dequeue = true,
7705                            index = type != null && type + "queueHooks",
7706                            timers = jQuery.timers,
7707                            data = dataPriv.get(this);
7708
7709                        if (index) {
7710                            if (data[index] && data[index].stop) {
7711                                stopQueue(data[index]);
7712                            }
7713                        } else {
7714                            for (index in data) {
7715                                if (data[index] && data[index].stop && rrun.test(index)) {
7716                                    stopQueue(data[index]);
7717                                }
7718                            }
7719                        }
7720
7721                        for (index = timers.length; index--;) {
7722                            if (timers[index].elem === this &&
7723                                (type == null || timers[index].queue === type)) {
7724
7725                                timers[index].anim.stop(gotoEnd);
7726                                dequeue = false;
7727                                timers.splice(index, 1);
7728                            }
7729                        }
7730
7731                        // Start the next in the queue if the last step wasn't forced.
7732                        // Timers currently will call their complete callbacks, which
7733                        // will dequeue but only if they were gotoEnd.
7734                        if (dequeue || !gotoEnd) {
7735                            jQuery.dequeue(this, type);
7736                        }
7737                    });
7738                },
7739                finish: function (type) {
7740                    if (type !== false) {
7741                        type = type || "fx";
7742                    }
7743                    return this.each(function () {
7744                        var index,
7745                            data = dataPriv.get(this),
7746                            queue = data[type + "queue"],
7747                            hooks = data[type + "queueHooks"],
7748                            timers = jQuery.timers,
7749                            length = queue ? queue.length : 0;
7750
7751                        // Enable finishing flag on private data
7752                        data.finish = true;
7753
7754                        // Empty the queue first
7755                        jQuery.queue(this, type, []);
7756
7757                        if (hooks && hooks.stop) {
7758                            hooks.stop.call(this, true);
7759                        }
7760
7761                        // Look for any active animations, and finish them
7762                        for (index = timers.length; index--;) {
7763                            if (timers[index].elem === this && timers[index].queue === type) {
7764                                timers[index].anim.stop(true);
7765                                timers.splice(index, 1);
7766                            }
7767                        }
7768
7769                        // Look for any animations in the old queue and finish them
7770                        for (index = 0; index < length; index++) {
7771                            if (queue[index] && queue[index].finish) {
7772                                queue[index].finish.call(this);
7773                            }
7774                        }
7775
7776                        // Turn off finishing flag
7777                        delete data.finish;
7778                    });
7779                }
7780            });
7781
7782            jQuery.each(["toggle", "show", "hide"], function (_i, name) {
7783                var cssFn = jQuery.fn[name];
7784                jQuery.fn[name] = function (speed, easing, callback) {
7785                    return speed == null || typeof speed === "boolean" ?
7786                        cssFn.apply(this, arguments) :
7787                        this.animate(genFx(name, true), speed, easing, callback);
7788                };
7789            });
7790
7791            // Generate shortcuts for custom animations
7792            jQuery.each({
7793                slideDown: genFx("show"),
7794                slideUp: genFx("hide"),
7795                slideToggle: genFx("toggle"),
7796                fadeIn: {opacity: "show"},
7797                fadeOut: {opacity: "hide"},
7798                fadeToggle: {opacity: "toggle"}
7799            }, function (name, props) {
7800                jQuery.fn[name] = function (speed, easing, callback) {
7801                    return this.animate(props, speed, easing, callback);
7802                };
7803            });
7804
7805            jQuery.timers = [];
7806            jQuery.fx.tick = function () {
7807                var timer,
7808                    i = 0,
7809                    timers = jQuery.timers;
7810
7811                fxNow = Date.now();
7812
7813                for (; i < timers.length; i++) {
7814                    timer = timers[i];
7815
7816                    // Run the timer and safely remove it when done (allowing for external removal)
7817                    if (!timer() && timers[i] === timer) {
7818                        timers.splice(i--, 1);
7819                    }
7820                }
7821
7822                if (!timers.length) {
7823                    jQuery.fx.stop();
7824                }
7825                fxNow = undefined;
7826            };
7827
7828            jQuery.fx.timer = function (timer) {
7829                jQuery.timers.push(timer);
7830                jQuery.fx.start();
7831            };
7832
7833            jQuery.fx.interval = 13;
7834            jQuery.fx.start = function () {
7835                if (inProgress) {
7836                    return;
7837                }
7838
7839                inProgress = true;
7840                schedule();
7841            };
7842
7843            jQuery.fx.stop = function () {
7844                inProgress = null;
7845            };
7846
7847            jQuery.fx.speeds = {
7848                slow: 600,
7849                fast: 200,
7850
7851                // Default speed
7852                _default: 400
7853            };
7854
7855
7856            // Based off of the plugin by Clint Helfers, with permission.
7857            jQuery.fn.delay = function (time, type) {
7858                time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
7859                type = type || "fx";
7860
7861                return this.queue(type, function (next, hooks) {
7862                    var timeout = window.setTimeout(next, time);
7863                    hooks.stop = function () {
7864                        window.clearTimeout(timeout);
7865                    };
7866                });
7867            };
7868
7869
7870            (function () {
7871                var input = document.createElement("input"),
7872                    select = document.createElement("select"),
7873                    opt = select.appendChild(document.createElement("option"));
7874
7875                input.type = "checkbox";
7876
7877                // Support: Android <=4.3 only
7878                // Default value for a checkbox should be "on"
7879                support.checkOn = input.value !== "";
7880
7881                // Support: IE <=11 only
7882                // Must access selectedIndex to make default options select
7883                support.optSelected = opt.selected;
7884
7885                // Support: IE <=11 only
7886                // An input loses its value after becoming a radio
7887                input = document.createElement("input");
7888                input.value = "t";
7889                input.type = "radio";
7890                support.radioValue = input.value === "t";
7891            })();
7892
7893
7894            var boolHook,
7895                attrHandle = jQuery.expr.attrHandle;
7896
7897            jQuery.fn.extend({
7898                attr: function (name, value) {
7899                    return access(this, jQuery.attr, name, value, arguments.length > 1);
7900                },
7901
7902                removeAttr: function (name) {
7903                    return this.each(function () {
7904                        jQuery.removeAttr(this, name);
7905                    });
7906                }
7907            });
7908
7909            jQuery.extend({
7910                attr: function (elem, name, value) {
7911                    var ret, hooks,
7912                        nType = elem.nodeType;
7913
7914                    // Don't get/set attributes on text, comment and attribute nodes
7915                    if (nType === 3 || nType === 8 || nType === 2) {
7916                        return;
7917                    }
7918
7919                    // Fallback to prop when attributes are not supported
7920                    if (typeof elem.getAttribute === "undefined") {
7921                        return jQuery.prop(elem, name, value);
7922                    }
7923
7924                    // Attribute hooks are determined by the lowercase version
7925                    // Grab necessary hook if one is defined
7926                    if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
7927                        hooks = jQuery.attrHooks[name.toLowerCase()] ||
7928                            (jQuery.expr.match.bool.test(name) ? boolHook : undefined);
7929                    }
7930
7931                    if (value !== undefined) {
7932                        if (value === null) {
7933                            jQuery.removeAttr(elem, name);
7934                            return;
7935                        }
7936
7937                        if (hooks && "set" in hooks &&
7938                            (ret = hooks.set(elem, value, name)) !== undefined) {
7939                            return ret;
7940                        }
7941
7942                        elem.setAttribute(name, value + "");
7943                        return value;
7944                    }
7945
7946                    if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
7947                        return ret;
7948                    }
7949
7950                    ret = jQuery.find.attr(elem, name);
7951
7952                    // Non-existent attributes return null, we normalize to undefined
7953                    return ret == null ? undefined : ret;
7954                },
7955
7956                attrHooks: {
7957                    type: {
7958                        set: function (elem, value) {
7959                            if (!support.radioValue && value === "radio" &&
7960                                nodeName(elem, "input")) {
7961                                var val = elem.value;
7962                                elem.setAttribute("type", value);
7963                                if (val) {
7964                                    elem.value = val;
7965                                }
7966                                return value;
7967                            }
7968                        }
7969                    }
7970                },
7971
7972                removeAttr: function (elem, value) {
7973                    var name,
7974                        i = 0,
7975
7976                        // Attribute names can contain non-HTML whitespace characters
7977                        // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
7978                        attrNames = value && value.match(rnothtmlwhite);
7979
7980                    if (attrNames && elem.nodeType === 1) {
7981                        while ((name = attrNames[i++])) {
7982                            elem.removeAttribute(name);
7983                        }
7984                    }
7985                }
7986            });
7987
7988            // Hooks for boolean attributes
7989            boolHook = {
7990                set: function (elem, value, name) {
7991                    if (value === false) {
7992
7993                        // Remove boolean attributes when set to false
7994                        jQuery.removeAttr(elem, name);
7995                    } else {
7996                        elem.setAttribute(name, name);
7997                    }
7998                    return name;
7999                }
8000            };
8001
8002            jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (_i, name) {
8003                var getter = attrHandle[name] || jQuery.find.attr;
8004
8005                attrHandle[name] = function (elem, name, isXML) {
8006                    var ret, handle,
8007                        lowercaseName = name.toLowerCase();
8008
8009                    if (!isXML) {
8010
8011                        // Avoid an infinite loop by temporarily removing this function from the getter
8012                        handle = attrHandle[lowercaseName];
8013                        attrHandle[lowercaseName] = ret;
8014                        ret = getter(elem, name, isXML) != null ?
8015                            lowercaseName :
8016                            null;
8017                        attrHandle[lowercaseName] = handle;
8018                    }
8019                    return ret;
8020                };
8021            });
8022
8023
8024            var rfocusable = /^(?:input|select|textarea|button)$/i,
8025                rclickable = /^(?:a|area)$/i;
8026
8027            jQuery.fn.extend({
8028                prop: function (name, value) {
8029                    return access(this, jQuery.prop, name, value, arguments.length > 1);
8030                },
8031
8032                removeProp: function (name) {
8033                    return this.each(function () {
8034                        delete this[jQuery.propFix[name] || name];
8035                    });
8036                }
8037            });
8038
8039            jQuery.extend({
8040                prop: function (elem, name, value) {
8041                    var ret, hooks,
8042                        nType = elem.nodeType;
8043
8044                    // Don't get/set properties on text, comment and attribute nodes
8045                    if (nType === 3 || nType === 8 || nType === 2) {
8046                        return;
8047                    }
8048
8049                    if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
8050
8051                        // Fix name and attach hooks
8052                        name = jQuery.propFix[name] || name;
8053                        hooks = jQuery.propHooks[name];
8054                    }
8055
8056                    if (value !== undefined) {
8057                        if (hooks && "set" in hooks &&
8058                            (ret = hooks.set(elem, value, name)) !== undefined) {
8059                            return ret;
8060                        }
8061
8062                        return (elem[name] = value);
8063                    }
8064
8065                    if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
8066                        return ret;
8067                    }
8068
8069                    return elem[name];
8070                },
8071
8072                propHooks: {
8073                    tabIndex: {
8074                        get: function (elem) {
8075
8076                            // Support: IE <=9 - 11 only
8077                            // elem.tabIndex doesn't always return the
8078                            // correct value when it hasn't been explicitly set
8079                            // Use proper attribute retrieval (trac-12072)
8080                            var tabindex = jQuery.find.attr(elem, "tabindex");
8081
8082                            if (tabindex) {
8083                                return parseInt(tabindex, 10);
8084                            }
8085
8086                            if (
8087                                rfocusable.test(elem.nodeName) ||
8088                                rclickable.test(elem.nodeName) &&
8089                                elem.href
8090                            ) {
8091                                return 0;
8092                            }
8093
8094                            return -1;
8095                        }
8096                    }
8097                },
8098
8099                propFix: {
8100                    "for": "htmlFor",
8101                    "class": "className"
8102                }
8103            });
8104
8105            // Support: IE <=11 only
8106            // Accessing the selectedIndex property
8107            // forces the browser to respect setting selected
8108            // on the option
8109            // The getter ensures a default option is selected
8110            // when in an optgroup
8111            // eslint rule "no-unused-expressions" is disabled for this code
8112            // since it considers such accessions noop
8113            if (!support.optSelected) {
8114                jQuery.propHooks.selected = {
8115                    get: function (elem) {
8116
8117                        /* eslint no-unused-expressions: "off" */
8118
8119                        var parent = elem.parentNode;
8120                        if (parent && parent.parentNode) {
8121                            parent.parentNode.selectedIndex;
8122                        }
8123                        return null;
8124                    },
8125                    set: function (elem) {
8126
8127                        /* eslint no-unused-expressions: "off" */
8128
8129                        var parent = elem.parentNode;
8130                        if (parent) {
8131                            parent.selectedIndex;
8132
8133                            if (parent.parentNode) {
8134                                parent.parentNode.selectedIndex;
8135                            }
8136                        }
8137                    }
8138                };
8139            }
8140
8141            jQuery.each([
8142                "tabIndex",
8143                "readOnly",
8144                "maxLength",
8145                "cellSpacing",
8146                "cellPadding",
8147                "rowSpan",
8148                "colSpan",
8149                "useMap",
8150                "frameBorder",
8151                "contentEditable"
8152            ], function () {
8153                jQuery.propFix[this.toLowerCase()] = this;
8154            });
8155
8156
8157            // Strip and collapse whitespace according to HTML spec
8158            // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
8159            function stripAndCollapse(value) {
8160                var tokens = value.match(rnothtmlwhite) || [];
8161                return tokens.join(" ");
8162            }
8163
8164
8165            function getClass(elem) {
8166                return elem.getAttribute && elem.getAttribute("class") || "";
8167            }
8168
8169            function classesToArray(value) {
8170                if (Array.isArray(value)) {
8171                    return value;
8172                }
8173                if (typeof value === "string") {
8174                    return value.match(rnothtmlwhite) || [];
8175                }
8176                return [];
8177            }
8178
8179            jQuery.fn.extend({
8180                addClass: function (value) {
8181                    var classNames, cur, curValue, className, i, finalValue;
8182
8183                    if (isFunction(value)) {
8184                        return this.each(function (j) {
8185                            jQuery(this).addClass(value.call(this, j, getClass(this)));
8186                        });
8187                    }
8188
8189                    classNames = classesToArray(value);
8190
8191                    if (classNames.length) {
8192                        return this.each(function () {
8193                            curValue = getClass(this);
8194                            cur = this.nodeType === 1 && (" " + stripAndCollapse(curValue) + " ");
8195
8196                            if (cur) {
8197                                for (i = 0; i < classNames.length; i++) {
8198                                    className = classNames[i];
8199                                    if (cur.indexOf(" " + className + " ") < 0) {
8200                                        cur += className + " ";
8201                                    }
8202                                }
8203
8204                                // Only assign if different to avoid unneeded rendering.
8205                                finalValue = stripAndCollapse(cur);
8206                                if (curValue !== finalValue) {
8207                                    this.setAttribute("class", finalValue);
8208                                }
8209                            }
8210                        });
8211                    }
8212
8213                    return this;
8214                },
8215
8216                removeClass: function (value) {
8217                    var classNames, cur, curValue, className, i, finalValue;
8218
8219                    if (isFunction(value)) {
8220                        return this.each(function (j) {
8221                            jQuery(this).removeClass(value.call(this, j, getClass(this)));
8222                        });
8223                    }
8224
8225                    if (!arguments.length) {
8226                        return this.attr("class", "");
8227                    }
8228
8229                    classNames = classesToArray(value);
8230
8231                    if (classNames.length) {
8232                        return this.each(function () {
8233                            curValue = getClass(this);
8234
8235                            // This expression is here for better compressibility (see addClass)
8236                            cur = this.nodeType === 1 && (" " + stripAndCollapse(curValue) + " ");
8237
8238                            if (cur) {
8239                                for (i = 0; i < classNames.length; i++) {
8240                                    className = classNames[i];
8241
8242                                    // Remove *all* instances
8243                                    while (cur.indexOf(" " + className + " ") > -1) {
8244                                        cur = cur.replace(" " + className + " ", " ");
8245                                    }
8246                                }
8247
8248                                // Only assign if different to avoid unneeded rendering.
8249                                finalValue = stripAndCollapse(cur);
8250                                if (curValue !== finalValue) {
8251                                    this.setAttribute("class", finalValue);
8252                                }
8253                            }
8254                        });
8255                    }
8256
8257                    return this;
8258                },
8259
8260                toggleClass: function (value, stateVal) {
8261                    var classNames, className, i, self,
8262                        type = typeof value,
8263                        isValidValue = type === "string" || Array.isArray(value);
8264
8265                    if (isFunction(value)) {
8266                        return this.each(function (i) {
8267                            jQuery(this).toggleClass(
8268                                value.call(this, i, getClass(this), stateVal),
8269                                stateVal
8270                            );
8271                        });
8272                    }
8273
8274                    if (typeof stateVal === "boolean" && isValidValue) {
8275                        return stateVal ? this.addClass(value) : this.removeClass(value);
8276                    }
8277
8278                    classNames = classesToArray(value);
8279
8280                    return this.each(function () {
8281                        if (isValidValue) {
8282
8283                            // Toggle individual class names
8284                            self = jQuery(this);
8285
8286                            for (i = 0; i < classNames.length; i++) {
8287                                className = classNames[i];
8288
8289                                // Check each className given, space separated list
8290                                if (self.hasClass(className)) {
8291                                    self.removeClass(className);
8292                                } else {
8293                                    self.addClass(className);
8294                                }
8295                            }
8296
8297                            // Toggle whole class name
8298                        } else if (value === undefined || type === "boolean") {
8299                            className = getClass(this);
8300                            if (className) {
8301
8302                                // Store className if set
8303                                dataPriv.set(this, "__className__", className);
8304                            }
8305
8306                            // If the element has a class name or if we're passed `false`,
8307                            // then remove the whole classname (if there was one, the above saved it).
8308                            // Otherwise bring back whatever was previously saved (if anything),
8309                            // falling back to the empty string if nothing was stored.
8310                            if (this.setAttribute) {
8311                                this.setAttribute("class",
8312                                    className || value === false ?
8313                                        "" :
8314                                        dataPriv.get(this, "__className__") || ""
8315                                );
8316                            }
8317                        }
8318                    });
8319                },
8320
8321                hasClass: function (selector) {
8322                    var className, elem,
8323                        i = 0;
8324
8325                    className = " " + selector + " ";
8326                    while ((elem = this[i++])) {
8327                        if (elem.nodeType === 1 &&
8328                            (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) {
8329                            return true;
8330                        }
8331                    }
8332
8333                    return false;
8334                }
8335            });
8336
8337
8338            var rreturn = /\r/g;
8339
8340            jQuery.fn.extend({
8341                val: function (value) {
8342                    var hooks, ret, valueIsFunction,
8343                        elem = this[0];
8344
8345                    if (!arguments.length) {
8346                        if (elem) {
8347                            hooks = jQuery.valHooks[elem.type] ||
8348                                jQuery.valHooks[elem.nodeName.toLowerCase()];
8349
8350                            if (hooks &&
8351                                "get" in hooks &&
8352                                (ret = hooks.get(elem, "value")) !== undefined
8353                            ) {
8354                                return ret;
8355                            }
8356
8357                            ret = elem.value;
8358
8359                            // Handle most common string cases
8360                            if (typeof ret === "string") {
8361                                return ret.replace(rreturn, "");
8362                            }
8363
8364                            // Handle cases where value is null/undef or number
8365                            return ret == null ? "" : ret;
8366                        }
8367
8368                        return;
8369                    }
8370
8371                    valueIsFunction = isFunction(value);
8372
8373                    return this.each(function (i) {
8374                        var val;
8375
8376                        if (this.nodeType !== 1) {
8377                            return;
8378                        }
8379
8380                        if (valueIsFunction) {
8381                            val = value.call(this, i, jQuery(this).val());
8382                        } else {
8383                            val = value;
8384                        }
8385
8386                        // Treat null/undefined as ""; convert numbers to string
8387                        if (val == null) {
8388                            val = "";
8389
8390                        } else if (typeof val === "number") {
8391                            val += "";
8392
8393                        } else if (Array.isArray(val)) {
8394                            val = jQuery.map(val, function (value) {
8395                                return value == null ? "" : value + "";
8396                            });
8397                        }
8398
8399                        hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];
8400
8401                        // If set returns undefined, fall back to normal setting
8402                        if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
8403                            this.value = val;
8404                        }
8405                    });
8406                }
8407            });
8408
8409            jQuery.extend({
8410                valHooks: {
8411                    option: {
8412                        get: function (elem) {
8413
8414                            var val = jQuery.find.attr(elem, "value");
8415                            return val != null ?
8416                                val :
8417
8418                                // Support: IE <=10 - 11 only
8419                                // option.text throws exceptions (trac-14686, trac-14858)
8420                                // Strip and collapse whitespace
8421                                // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8422                                stripAndCollapse(jQuery.text(elem));
8423                        }
8424                    },
8425                    select: {
8426                        get: function (elem) {
8427                            var value, option, i,
8428                                options = elem.options,
8429                                index = elem.selectedIndex,
8430                                one = elem.type === "select-one",
8431                                values = one ? null : [],
8432                                max = one ? index + 1 : options.length;
8433
8434                            if (index < 0) {
8435                                i = max;
8436
8437                            } else {
8438                                i = one ? index : 0;
8439                            }
8440
8441                            // Loop through all the selected options
8442                            for (; i < max; i++) {
8443                                option = options[i];
8444
8445                                // Support: IE <=9 only
8446                                // IE8-9 doesn't update selected after form reset (trac-2551)
8447                                if ((option.selected || i === index) &&
8448
8449                                    // Don't return options that are disabled or in a disabled optgroup
8450                                    !option.disabled &&
8451                                    (!option.parentNode.disabled ||
8452                                        !nodeName(option.parentNode, "optgroup"))) {
8453
8454                                    // Get the specific value for the option
8455                                    value = jQuery(option).val();
8456
8457                                    // We don't need an array for one selects
8458                                    if (one) {
8459                                        return value;
8460                                    }
8461
8462                                    // Multi-Selects return an array
8463                                    values.push(value);
8464                                }
8465                            }
8466
8467                            return values;
8468                        },
8469
8470                        set: function (elem, value) {
8471                            var optionSet, option,
8472                                options = elem.options,
8473                                values = jQuery.makeArray(value),
8474                                i = options.length;
8475
8476                            while (i--) {
8477                                option = options[i];
8478
8479                                /* eslint-disable no-cond-assign */
8480
8481                                if (option.selected =
8482                                    jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1
8483                                ) {
8484                                    optionSet = true;
8485                                }
8486
8487                                /* eslint-enable no-cond-assign */
8488                            }
8489
8490                            // Force browsers to behave consistently when non-matching value is set
8491                            if (!optionSet) {
8492                                elem.selectedIndex = -1;
8493                            }
8494                            return values;
8495                        }
8496                    }
8497                }
8498            });
8499
8500            // Radios and checkboxes getter/setter
8501            jQuery.each(["radio", "checkbox"], function () {
8502                jQuery.valHooks[this] = {
8503                    set: function (elem, value) {
8504                        if (Array.isArray(value)) {
8505                            return (elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1);
8506                        }
8507                    }
8508                };
8509                if (!support.checkOn) {
8510                    jQuery.valHooks[this].get = function (elem) {
8511                        return elem.getAttribute("value") === null ? "on" : elem.value;
8512                    };
8513                }
8514            });
8515
8516
8517            // Return jQuery for attributes-only inclusion
8518            var location = window.location;
8519
8520            var nonce = {guid: Date.now()};
8521
8522            var rquery = (/\?/);
8523
8524
8525            // Cross-browser xml parsing
8526            jQuery.parseXML = function (data) {
8527                var xml, parserErrorElem;
8528                if (!data || typeof data !== "string") {
8529                    return null;
8530                }
8531
8532                // Support: IE 9 - 11 only
8533                // IE throws on parseFromString with invalid input.
8534                try {
8535                    xml = (new window.DOMParser()).parseFromString(data, "text/xml");
8536                } catch (e) {
8537                }
8538
8539                parserErrorElem = xml && xml.getElementsByTagName("parsererror")[0];
8540                if (!xml || parserErrorElem) {
8541                    jQuery.error("Invalid XML: " + (
8542                        parserErrorElem ?
8543                            jQuery.map(parserErrorElem.childNodes, function (el) {
8544                                return el.textContent;
8545                            }).join("\n") :
8546                            data
8547                    ));
8548                }
8549                return xml;
8550            };
8551
8552
8553            var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
8554                stopPropagationCallback = function (e) {
8555                    e.stopPropagation();
8556                };
8557
8558            jQuery.extend(jQuery.event, {
8559
8560                trigger: function (event, data, elem, onlyHandlers) {
8561
8562                    var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
8563                        eventPath = [elem || document],
8564                        type = hasOwn.call(event, "type") ? event.type : event,
8565                        namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
8566
8567                    cur = lastElement = tmp = elem = elem || document;
8568
8569                    // Don't do events on text and comment nodes
8570                    if (elem.nodeType === 3 || elem.nodeType === 8) {
8571                        return;
8572                    }
8573
8574                    // focus/blur morphs to focusin/out; ensure we're not firing them right now
8575                    if (rfocusMorph.test(type + jQuery.event.triggered)) {
8576                        return;
8577                    }
8578
8579                    if (type.indexOf(".") > -1) {
8580
8581                        // Namespaced trigger; create a regexp to match event type in handle()
8582                        namespaces = type.split(".");
8583                        type = namespaces.shift();
8584                        namespaces.sort();
8585                    }
8586                    ontype = type.indexOf(":") < 0 && "on" + type;
8587
8588                    // Caller can pass in a jQuery.Event object, Object, or just an event type string
8589                    event = event[jQuery.expando] ?
8590                        event :
8591                        new jQuery.Event(type, typeof event === "object" && event);
8592
8593                    // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
8594                    event.isTrigger = onlyHandlers ? 2 : 3;
8595                    event.namespace = namespaces.join(".");
8596                    event.rnamespace = event.namespace ?
8597                        new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") :
8598                        null;
8599
8600                    // Clean up the event in case it is being reused
8601                    event.result = undefined;
8602                    if (!event.target) {
8603                        event.target = elem;
8604                    }
8605
8606                    // Clone any incoming data and prepend the event, creating the handler arg list
8607                    data = data == null ?
8608                        [event] :
8609                        jQuery.makeArray(data, [event]);
8610
8611                    // Allow special events to draw outside the lines
8612                    special = jQuery.event.special[type] || {};
8613                    if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
8614                        return;
8615                    }
8616
8617                    // Determine event propagation path in advance, per W3C events spec (trac-9951)
8618                    // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724)
8619                    if (!onlyHandlers && !special.noBubble && !isWindow(elem)) {
8620
8621                        bubbleType = special.delegateType || type;
8622                        if (!rfocusMorph.test(bubbleType + type)) {
8623                            cur = cur.parentNode;
8624                        }
8625                        for (; cur; cur = cur.parentNode) {
8626                            eventPath.push(cur);
8627                            tmp = cur;
8628                        }
8629
8630                        // Only add window if we got to document (e.g., not plain obj or detached DOM)
8631                        if (tmp === (elem.ownerDocument || document)) {
8632                            eventPath.push(tmp.defaultView || tmp.parentWindow || window);
8633                        }
8634                    }
8635
8636                    // Fire handlers on the event path
8637                    i = 0;
8638                    while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
8639                        lastElement = cur;
8640                        event.type = i > 1 ?
8641                            bubbleType :
8642                            special.bindType || type;
8643
8644                        // jQuery handler
8645                        handle = (dataPriv.get(cur, "events") || Object.create(null))[event.type] &&
8646                            dataPriv.get(cur, "handle");
8647                        if (handle) {
8648                            handle.apply(cur, data);
8649                        }
8650
8651                        // Native handler
8652                        handle = ontype && cur[ontype];
8653                        if (handle && handle.apply && acceptData(cur)) {
8654                            event.result = handle.apply(cur, data);
8655                            if (event.result === false) {
8656                                event.preventDefault();
8657                            }
8658                        }
8659                    }
8660                    event.type = type;
8661
8662                    // If nobody prevented the default action, do it now
8663                    if (!onlyHandlers && !event.isDefaultPrevented()) {
8664
8665                        if ((!special._default ||
8666                                special._default.apply(eventPath.pop(), data) === false) &&
8667                            acceptData(elem)) {
8668
8669                            // Call a native DOM method on the target with the same name as the event.
8670                            // Don't do default actions on window, that's where global variables be (trac-6170)
8671                            if (ontype && isFunction(elem[type]) && !isWindow(elem)) {
8672
8673                                // Don't re-trigger an onFOO event when we call its FOO() method
8674                                tmp = elem[ontype];
8675
8676                                if (tmp) {
8677                                    elem[ontype] = null;
8678                                }
8679
8680                                // Prevent re-triggering of the same event, since we already bubbled it above
8681                                jQuery.event.triggered = type;
8682
8683                                if (event.isPropagationStopped()) {
8684                                    lastElement.addEventListener(type, stopPropagationCallback);
8685                                }
8686
8687                                elem[type]();
8688
8689                                if (event.isPropagationStopped()) {
8690                                    lastElement.removeEventListener(type, stopPropagationCallback);
8691                                }
8692
8693                                jQuery.event.triggered = undefined;
8694
8695                                if (tmp) {
8696                                    elem[ontype] = tmp;
8697                                }
8698                            }
8699                        }
8700                    }
8701
8702                    return event.result;
8703                },
8704
8705                // Piggyback on a donor event to simulate a different one
8706                // Used only for `focus(in | out)` events
8707                simulate: function (type, elem, event) {
8708                    var e = jQuery.extend(
8709                        new jQuery.Event(),
8710                        event,
8711                        {
8712                            type: type,
8713                            isSimulated: true
8714                        }
8715                    );
8716
8717                    jQuery.event.trigger(e, null, elem);
8718                }
8719
8720            });
8721
8722            jQuery.fn.extend({
8723
8724                trigger: function (type, data) {
8725                    return this.each(function () {
8726                        jQuery.event.trigger(type, data, this);
8727                    });
8728                },
8729                triggerHandler: function (type, data) {
8730                    var elem = this[0];
8731                    if (elem) {
8732                        return jQuery.event.trigger(type, data, elem, true);
8733                    }
8734                }
8735            });
8736
8737
8738            var
8739                rbracket = /\[\]$/,
8740                rCRLF = /\r?\n/g,
8741                rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8742                rsubmittable = /^(?:input|select|textarea|keygen)/i;
8743
8744            function buildParams(prefix, obj, traditional, add) {
8745                var name;
8746
8747                if (Array.isArray(obj)) {
8748
8749                    // Serialize array item.
8750                    jQuery.each(obj, function (i, v) {
8751                        if (traditional || rbracket.test(prefix)) {
8752
8753                            // Treat each array item as a scalar.
8754                            add(prefix, v);
8755
8756                        } else {
8757
8758                            // Item is non-scalar (array or object), encode its numeric index.
8759                            buildParams(
8760                                prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]",
8761                                v,
8762                                traditional,
8763                                add
8764                            );
8765                        }
8766                    });
8767
8768                } else if (!traditional && toType(obj) === "object") {
8769
8770                    // Serialize object item.
8771                    for (name in obj) {
8772                        buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
8773                    }
8774
8775                } else {
8776
8777                    // Serialize scalar item.
8778                    add(prefix, obj);
8779                }
8780            }
8781
8782            // Serialize an array of form elements or a set of
8783            // key/values into a query string
8784            jQuery.param = function (a, traditional) {
8785                var prefix,
8786                    s = [],
8787                    add = function (key, valueOrFunction) {
8788
8789                        // If value is a function, invoke it and use its return value
8790                        var value = isFunction(valueOrFunction) ?
8791                            valueOrFunction() :
8792                            valueOrFunction;
8793
8794                        s[s.length] = encodeURIComponent(key) + "=" +
8795                            encodeURIComponent(value == null ? "" : value);
8796                    };
8797
8798                if (a == null) {
8799                    return "";
8800                }
8801
8802                // If an array was passed in, assume that it is an array of form elements.
8803                if (Array.isArray(a) || (a.jquery && !jQuery.isPlainObject(a))) {
8804
8805                    // Serialize the form elements
8806                    jQuery.each(a, function () {
8807                        add(this.name, this.value);
8808                    });
8809
8810                } else {
8811
8812                    // If traditional, encode the "old" way (the way 1.3.2 or older
8813                    // did it), otherwise encode params recursively.
8814                    for (prefix in a) {
8815                        buildParams(prefix, a[prefix], traditional, add);
8816                    }
8817                }
8818
8819                // Return the resulting serialization
8820                return s.join("&");
8821            };
8822
8823            jQuery.fn.extend({
8824                serialize: function () {
8825                    return jQuery.param(this.serializeArray());
8826                },
8827                serializeArray: function () {
8828                    return this.map(function () {
8829
8830                        // Can add propHook for "elements" to filter or add form elements
8831                        var elements = jQuery.prop(this, "elements");
8832                        return elements ? jQuery.makeArray(elements) : this;
8833                    }).filter(function () {
8834                        var type = this.type;
8835
8836                        // Use .is( ":disabled" ) so that fieldset[disabled] works
8837                        return this.name && !jQuery(this).is(":disabled") &&
8838                            rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) &&
8839                            (this.checked || !rcheckableType.test(type));
8840                    }).map(function (_i, elem) {
8841                        var val = jQuery(this).val();
8842
8843                        if (val == null) {
8844                            return null;
8845                        }
8846
8847                        if (Array.isArray(val)) {
8848                            return jQuery.map(val, function (val) {
8849                                return {name: elem.name, value: val.replace(rCRLF, "\r\n")};
8850                            });
8851                        }
8852
8853                        return {name: elem.name, value: val.replace(rCRLF, "\r\n")};
8854                    }).get();
8855                }
8856            });
8857
8858
8859            var
8860                r20 = /%20/g,
8861                rhash = /#.*$/,
8862                rantiCache = /([?&])_=[^&]*/,
8863                rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
8864
8865                // trac-7653, trac-8125, trac-8152: local protocol detection
8866                rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8867                rnoContent = /^(?:GET|HEAD)$/,
8868                rprotocol = /^\/\//,
8869
8870                /* Prefilters
8871			 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8872			 * 2) These are called:
8873			 *    - BEFORE asking for a transport
8874			 *    - AFTER param serialization (s.data is a string if s.processData is true)
8875			 * 3) key is the dataType
8876			 * 4) the catchall symbol "*" can be used
8877			 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8878			 */
8879                prefilters = {},
8880
8881                /* Transports bindings
8882			 * 1) key is the dataType
8883			 * 2) the catchall symbol "*" can be used
8884			 * 3) selection will start with transport dataType and THEN go to "*" if needed
8885			 */
8886                transports = {},
8887
8888                // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression
8889                allTypes = "*/".concat("*"),
8890
8891                // Anchor tag for parsing the document origin
8892                originAnchor = document.createElement("a");
8893
8894            originAnchor.href = location.href;
8895
8896            // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8897            function addToPrefiltersOrTransports(structure) {
8898
8899                // dataTypeExpression is optional and defaults to "*"
8900                return function (dataTypeExpression, func) {
8901
8902                    if (typeof dataTypeExpression !== "string") {
8903                        func = dataTypeExpression;
8904                        dataTypeExpression = "*";
8905                    }
8906
8907                    var dataType,
8908                        i = 0,
8909                        dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || [];
8910
8911                    if (isFunction(func)) {
8912
8913                        // For each dataType in the dataTypeExpression
8914                        while ((dataType = dataTypes[i++])) {
8915
8916                            // Prepend if requested
8917                            if (dataType[0] === "+") {
8918                                dataType = dataType.slice(1) || "*";
8919                                (structure[dataType] = structure[dataType] || []).unshift(func);
8920
8921                                // Otherwise append
8922                            } else {
8923                                (structure[dataType] = structure[dataType] || []).push(func);
8924                            }
8925                        }
8926                    }
8927                };
8928            }
8929
8930            // Base inspection function for prefilters and transports
8931            function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
8932
8933                var inspected = {},
8934                    seekingTransport = (structure === transports);
8935
8936                function inspect(dataType) {
8937                    var selected;
8938                    inspected[dataType] = true;
vendor: 18,312 bytes, lines 8939-9384
8939                    jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) {
8940                        var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
8941                        if (typeof dataTypeOrTransport === "string" &&
8942                            !seekingTransport && !inspected[dataTypeOrTransport]) {
8943
8944                            options.dataTypes.unshift(dataTypeOrTransport);
8945                            inspect(dataTypeOrTransport);
8946                            return false;
8947                        } else if (seekingTransport) {
8948                            return !(selected = dataTypeOrTransport);
8949                        }
8950                    });
8951                    return selected;
8952                }
8953
8954                return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
8955            }
8956
8957            // A special extend for ajax options
8958            // that takes "flat" options (not to be deep extended)
8959            // Fixes trac-9887
8960            function ajaxExtend(target, src) {
8961                var key, deep,
8962                    flatOptions = jQuery.ajaxSettings.flatOptions || {};
8963
8964                for (key in src) {
8965                    if (src[key] !== undefined) {
8966                        (flatOptions[key] ? target : (deep || (deep = {})))[key] = src[key];
8967                    }
8968                }
8969                if (deep) {
8970                    jQuery.extend(true, target, deep);
8971                }
8972
8973                return target;
8974            }
8975
8976            /* Handles responses to an ajax request:
8977		 * - finds the right dataType (mediates between content-type and expected dataType)
8978		 * - returns the corresponding response
8979		 */
8980            function ajaxHandleResponses(s, jqXHR, responses) {
8981
8982                var ct, type, finalDataType, firstDataType,
8983                    contents = s.contents,
8984                    dataTypes = s.dataTypes;
8985
8986                // Remove auto dataType and get content-type in the process
8987                while (dataTypes[0] === "*") {
8988                    dataTypes.shift();
8989                    if (ct === undefined) {
8990                        ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
8991                    }
8992                }
8993
8994                // Check if we're dealing with a known content-type
8995                if (ct) {
8996                    for (type in contents) {
8997                        if (contents[type] && contents[type].test(ct)) {
8998                            dataTypes.unshift(type);
8999                            break;
9000                        }
9001                    }
9002                }
9003
9004                // Check to see if we have a response for the expected dataType
9005                if (dataTypes[0] in responses) {
9006                    finalDataType = dataTypes[0];
9007                } else {
9008
9009                    // Try convertible dataTypes
9010                    for (type in responses) {
9011                        if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
9012                            finalDataType = type;
9013                            break;
9014                        }
9015                        if (!firstDataType) {
9016                            firstDataType = type;
9017                        }
9018                    }
9019
9020                    // Or just use first one
9021                    finalDataType = finalDataType || firstDataType;
9022                }
9023
9024                // If we found a dataType
9025                // We add the dataType to the list if needed
9026                // and return the corresponding response
9027                if (finalDataType) {
9028                    if (finalDataType !== dataTypes[0]) {
9029                        dataTypes.unshift(finalDataType);
9030                    }
9031                    return responses[finalDataType];
9032                }
9033            }
9034
9035            /* Chain conversions given the request and the original response
9036		 * Also sets the responseXXX fields on the jqXHR instance
9037		 */
9038            function ajaxConvert(s, response, jqXHR, isSuccess) {
9039                var conv2, current, conv, tmp, prev,
9040                    converters = {},
9041
9042                    // Work with a copy of dataTypes in case we need to modify it for conversion
9043                    dataTypes = s.dataTypes.slice();
9044
9045                // Create converters map with lowercased keys
9046                if (dataTypes[1]) {
9047                    for (conv in s.converters) {
9048                        converters[conv.toLowerCase()] = s.converters[conv];
9049                    }
9050                }
9051
9052                current = dataTypes.shift();
9053
9054                // Convert to each sequential dataType
9055                while (current) {
9056
9057                    if (s.responseFields[current]) {
9058                        jqXHR[s.responseFields[current]] = response;
9059                    }
9060
9061                    // Apply the dataFilter if provided
9062                    if (!prev && isSuccess && s.dataFilter) {
9063                        response = s.dataFilter(response, s.dataType);
9064                    }
9065
9066                    prev = current;
9067                    current = dataTypes.shift();
9068
9069                    if (current) {
9070
9071                        // There's only work to do if current dataType is non-auto
9072                        if (current === "*") {
9073
9074                            current = prev;
9075
9076                            // Convert response if prev dataType is non-auto and differs from current
9077                        } else if (prev !== "*" && prev !== current) {
9078
9079                            // Seek a direct converter
9080                            conv = converters[prev + " " + current] || converters["* " + current];
9081
9082                            // If none found, seek a pair
9083                            if (!conv) {
9084                                for (conv2 in converters) {
9085
9086                                    // If conv2 outputs current
9087                                    tmp = conv2.split(" ");
9088                                    if (tmp[1] === current) {
9089
9090                                        // If prev can be converted to accepted input
9091                                        conv = converters[prev + " " + tmp[0]] ||
9092                                            converters["* " + tmp[0]];
9093                                        if (conv) {
9094
9095                                            // Condense equivalence converters
9096                                            if (conv === true) {
9097                                                conv = converters[conv2];
9098
9099                                                // Otherwise, insert the intermediate dataType
9100                                            } else if (converters[conv2] !== true) {
9101                                                current = tmp[0];
9102                                                dataTypes.unshift(tmp[1]);
9103                                            }
9104                                            break;
9105                                        }
9106                                    }
9107                                }
9108                            }
9109
9110                            // Apply converter (if not an equivalence)
9111                            if (conv !== true) {
9112
9113                                // Unless errors are allowed to bubble, catch and return them
9114                                if (conv && s.throws) {
9115                                    response = conv(response);
9116                                } else {
9117                                    try {
9118                                        response = conv(response);
9119                                    } catch (e) {
9120                                        return {
9121                                            state: "parsererror",
9122                                            error: conv ? e : "No conversion from " + prev + " to " + current
9123                                        };
9124                                    }
9125                                }
9126                            }
9127                        }
9128                    }
9129                }
9130
9131                return {state: "success", data: response};
9132            }
9133
9134            jQuery.extend({
9135
9136                // Counter for holding the number of active queries
9137                active: 0,
9138
9139                // Last-Modified header cache for next request
9140                lastModified: {},
9141                etag: {},
9142
9143                ajaxSettings: {
9144                    url: location.href,
9145                    type: "GET",
9146                    isLocal: rlocalProtocol.test(location.protocol),
9147                    global: true,
9148                    processData: true,
9149                    async: true,
9150                    contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9151
9152                    /*
9153				timeout: 0,
9154				data: null,
9155				dataType: null,
9156				username: null,
9157				password: null,
9158				cache: null,
9159				throws: false,
9160				traditional: false,
9161				headers: {},
9162				*/
9163
9164                    accepts: {
9165                        "*": allTypes,
9166                        text: "text/plain",
9167                        html: "text/html",
9168                        xml: "application/xml, text/xml",
9169                        json: "application/json, text/javascript"
9170                    },
9171
9172                    contents: {
9173                        xml: /\bxml\b/,
9174                        html: /\bhtml/,
9175                        json: /\bjson\b/
9176                    },
9177
9178                    responseFields: {
9179                        xml: "responseXML",
9180                        text: "responseText",
9181                        json: "responseJSON"
9182                    },
9183
9184                    // Data converters
9185                    // Keys separate source (or catchall "*") and destination types with a single space
9186                    converters: {
9187
9188                        // Convert anything to text
9189                        "* text": String,
9190
9191                        // Text to html (true = no transformation)
9192                        "text html": true,
9193
9194                        // Evaluate text as a json expression
9195                        "text json": JSON.parse,
9196
9197                        // Parse text as xml
9198                        "text xml": jQuery.parseXML
9199                    },
9200
9201                    // For options that shouldn't be deep extended:
9202                    // you can add your own custom options here if
9203                    // and when you create one that shouldn't be
9204                    // deep extended (see ajaxExtend)
9205                    flatOptions: {
9206                        url: true,
9207                        context: true
9208                    }
9209                },
9210
9211                // Creates a full fledged settings object into target
9212                // with both ajaxSettings and settings fields.
9213                // If target is omitted, writes into ajaxSettings.
9214                ajaxSetup: function (target, settings) {
9215                    return settings ?
9216
9217                        // Building a settings object
9218                        ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) :
9219
9220                        // Extending ajaxSettings
9221                        ajaxExtend(jQuery.ajaxSettings, target);
9222                },
9223
9224                ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
9225                ajaxTransport: addToPrefiltersOrTransports(transports),
9226
9227                // Main method
9228                ajax: function (url, options) {
9229
9230                    // If url is an object, simulate pre-1.5 signature
9231                    if (typeof url === "object") {
9232                        options = url;
9233                        url = undefined;
9234                    }
9235
9236                    // Force options to be an object
9237                    options = options || {};
9238
9239                    var transport,
9240
9241                        // URL without anti-cache param
9242                        cacheURL,
9243
9244                        // Response headers
9245                        responseHeadersString,
9246                        responseHeaders,
9247
9248                        // timeout handle
9249                        timeoutTimer,
9250
9251                        // Url cleanup var
9252                        urlAnchor,
9253
9254                        // Request state (becomes false upon send and true upon completion)
9255                        completed,
9256
9257                        // To know if global events are to be dispatched
9258                        fireGlobals,
9259
9260                        // Loop variable
9261                        i,
9262
9263                        // uncached part of the url
9264                        uncached,
9265
9266                        // Create the final options object
9267                        s = jQuery.ajaxSetup({}, options),
9268
9269                        // Callbacks context
9270                        callbackContext = s.context || s,
9271
9272                        // Context for global events is callbackContext if it is a DOM node or jQuery collection
9273                        globalEventContext = s.context &&
9274                        (callbackContext.nodeType || callbackContext.jquery) ?
9275                            jQuery(callbackContext) :
9276                            jQuery.event,
9277
9278                        // Deferreds
9279                        deferred = jQuery.Deferred(),
9280                        completeDeferred = jQuery.Callbacks("once memory"),
9281
9282                        // Status-dependent callbacks
9283                        statusCode = s.statusCode || {},
9284
9285                        // Headers (they are sent all at once)
9286                        requestHeaders = {},
9287                        requestHeadersNames = {},
9288
9289                        // Default abort message
9290                        strAbort = "canceled",
9291
9292                        // Fake xhr
9293                        jqXHR = {
9294                            readyState: 0,
9295
9296                            // Builds headers hashtable if needed
9297                            getResponseHeader: function (key) {
9298                                var match;
9299                                if (completed) {
9300                                    if (!responseHeaders) {
9301                                        responseHeaders = {};
9302                                        while ((match = rheaders.exec(responseHeadersString))) {
9303                                            responseHeaders[match[1].toLowerCase() + " "] =
9304                                                (responseHeaders[match[1].toLowerCase() + " "] || [])
9305                                                    .concat(match[2]);
9306                                        }
9307                                    }
9308                                    match = responseHeaders[key.toLowerCase() + " "];
9309                                }
9310                                return match == null ? null : match.join(", ");
9311                            },
9312
9313                            // Raw string
9314                            getAllResponseHeaders: function () {
9315                                return completed ? responseHeadersString : null;
9316                            },
9317
9318                            // Caches the header
9319                            setRequestHeader: function (name, value) {
9320                                if (completed == null) {
9321                                    name = requestHeadersNames[name.toLowerCase()] =
9322                                        requestHeadersNames[name.toLowerCase()] || name;
9323                                    requestHeaders[name] = value;
9324                                }
9325                                return this;
9326                            },
9327
9328                            // Overrides response content-type header
9329                            overrideMimeType: function (type) {
9330                                if (completed == null) {
9331                                    s.mimeType = type;
9332                                }
9333                                return this;
9334                            },
9335
9336                            // Status-dependent callbacks
9337                            statusCode: function (map) {
9338                                var code;
9339                                if (map) {
9340                                    if (completed) {
9341
9342                                        // Execute the appropriate callbacks
9343                                        jqXHR.always(map[jqXHR.status]);
9344                                    } else {
9345
9346                                        // Lazy-add the new callbacks in a way that preserves old ones
9347                                        for (code in map) {
9348                                            statusCode[code] = [statusCode[code], map[code]];
9349                                        }
9350                                    }
9351                                }
9352                                return this;
9353                            },
9354
9355                            // Cancel the request
9356                            abort: function (statusText) {
9357                                var finalText = statusText || strAbort;
9358                                if (transport) {
9359                                    transport.abort(finalText);
9360                                }
9361                                done(0, finalText);
9362                                return this;
9363                            }
9364                        };
9365
9366                    // Attach deferreds
9367                    deferred.promise(jqXHR);
9368
9369                    // Add protocol if not provided (prefilters might expect it)
9370                    // Handle falsy url in the settings object (trac-10093: consistency with old signature)
9371                    // We also use the url parameter if available
9372                    s.url = ((url || s.url || location.href) + "")
9373                        .replace(rprotocol, location.protocol + "//");
9374
9375                    // Alias method option to type as per ticket trac-12004
9376                    s.type = options.method || options.type || s.method || s.type;
9377
9378                    // Extract dataTypes list
9379                    s.dataTypes = (s.dataType || "*").toLowerCase().match(rnothtmlwhite) || [""];
9380
9381                    // A cross-domain request is in order when the origin doesn't match the current origin.
9382                    if (s.crossDomain == null) {
9383                        urlAnchor = document.createElement("a");
9384
vendor: 47,446 bytes, lines 9385-10487
9385                        // Support: IE <=8 - 11, Edge 12 - 15
9386                        // IE throws exception on accessing the href property if url is malformed,
9387                        // e.g. http://example.com:80x/
9388                        try {
9389                            urlAnchor.href = s.url;
9390
9391                            // Support: IE <=8 - 11 only
9392                            // Anchor's host property isn't correctly set when s.url is relative
9393                            urlAnchor.href = urlAnchor.href;
9394                            s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
9395                                urlAnchor.protocol + "//" + urlAnchor.host;
9396                        } catch (e) {
9397
9398                            // If there is an error parsing the URL, assume it is crossDomain,
9399                            // it can be rejected by the transport if it is invalid
9400                            s.crossDomain = true;
9401                        }
9402                    }
9403
9404                    // Convert data if not already a string
9405                    if (s.data && s.processData && typeof s.data !== "string") {
9406                        s.data = jQuery.param(s.data, s.traditional);
9407                    }
9408
9409                    // Apply prefilters
9410                    inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);
9411
9412                    // If request was aborted inside a prefilter, stop there
9413                    if (completed) {
9414                        return jqXHR;
9415                    }
9416
9417                    // We can fire global events as of now if asked to
9418                    // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118)
9419                    fireGlobals = jQuery.event && s.global;
9420
9421                    // Watch for a new set of requests
9422                    if (fireGlobals && jQuery.active++ === 0) {
9423                        jQuery.event.trigger("ajaxStart");
9424                    }
9425
9426                    // Uppercase the type
9427                    s.type = s.type.toUpperCase();
9428
9429                    // Determine if request has content
9430                    s.hasContent = !rnoContent.test(s.type);
9431
9432                    // Save the URL in case we're toying with the If-Modified-Since
9433                    // and/or If-None-Match header later on
9434                    // Remove hash to simplify url manipulation
9435                    cacheURL = s.url.replace(rhash, "");
9436
9437                    // More options handling for requests with no content
9438                    if (!s.hasContent) {
9439
9440                        // Remember the hash so we can put it back
9441                        uncached = s.url.slice(cacheURL.length);
9442
9443                        // If data is available and should be processed, append data to url
9444                        if (s.data && (s.processData || typeof s.data === "string")) {
9445                            cacheURL += (rquery.test(cacheURL) ? "&" : "?") + s.data;
9446
9447                            // trac-9682: remove data so that it's not used in an eventual retry
9448                            delete s.data;
9449                        }
9450
9451                        // Add or update anti-cache param if needed
9452                        if (s.cache === false) {
9453                            cacheURL = cacheURL.replace(rantiCache, "$1");
9454                            uncached = (rquery.test(cacheURL) ? "&" : "?") + "_=" + (nonce.guid++) +
9455                                uncached;
9456                        }
9457
9458                        // Put hash and anti-cache on the URL that will be requested (gh-1732)
9459                        s.url = cacheURL + uncached;
9460
9461                        // Change '%20' to '+' if this is encoded form body content (gh-2658)
9462                    } else if (s.data && s.processData &&
9463                        (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0) {
9464                        s.data = s.data.replace(r20, "+");
9465                    }
9466
9467                    // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9468                    if (s.ifModified) {
9469                        if (jQuery.lastModified[cacheURL]) {
9470                            jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]);
9471                        }
9472                        if (jQuery.etag[cacheURL]) {
9473                            jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]);
9474                        }
9475                    }
9476
9477                    // Set the correct header, if data is being sent
9478                    if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
9479                        jqXHR.setRequestHeader("Content-Type", s.contentType);
9480                    }
9481
9482                    // Set the Accepts header for the server, depending on the dataType
9483                    jqXHR.setRequestHeader(
9484                        "Accept",
9485                        s.dataTypes[0] && s.accepts[s.dataTypes[0]] ?
9486                            s.accepts[s.dataTypes[0]] +
9487                            (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") :
9488                            s.accepts["*"]
9489                    );
9490
9491                    // Check for headers option
9492                    for (i in s.headers) {
9493                        jqXHR.setRequestHeader(i, s.headers[i]);
9494                    }
9495
9496                    // Allow custom headers/mimetypes and early abort
9497                    if (s.beforeSend &&
9498                        (s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) {
9499
9500                        // Abort if not done already and return
9501                        return jqXHR.abort();
9502                    }
9503
9504                    // Aborting is no longer a cancellation
9505                    strAbort = "abort";
9506
9507                    // Install callbacks on deferreds
9508                    completeDeferred.add(s.complete);
9509                    jqXHR.done(s.success);
9510                    jqXHR.fail(s.error);
9511
9512                    // Get transport
9513                    transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);
9514
9515                    // If no transport, we auto-abort
9516                    if (!transport) {
9517                        done(-1, "No Transport");
9518                    } else {
9519                        jqXHR.readyState = 1;
9520
9521                        // Send global event
9522                        if (fireGlobals) {
9523                            globalEventContext.trigger("ajaxSend", [jqXHR, s]);
9524                        }
9525
9526                        // If request was aborted inside ajaxSend, stop there
9527                        if (completed) {
9528                            return jqXHR;
9529                        }
9530
9531                        // Timeout
9532                        if (s.async && s.timeout > 0) {
9533                            timeoutTimer = window.setTimeout(function () {
9534                                jqXHR.abort("timeout");
9535                            }, s.timeout);
9536                        }
9537
9538                        try {
9539                            completed = false;
9540                            transport.send(requestHeaders, done);
9541                        } catch (e) {
9542
9543                            // Rethrow post-completion exceptions
9544                            if (completed) {
9545                                throw e;
9546                            }
9547
9548                            // Propagate others as results
9549                            done(-1, e);
9550                        }
9551                    }
9552
9553                    // Callback for when everything is done
9554                    function done(status, nativeStatusText, responses, headers) {
9555                        var isSuccess, success, error, response, modified,
9556                            statusText = nativeStatusText;
9557
9558                        // Ignore repeat invocations
9559                        if (completed) {
9560                            return;
9561                        }
9562
9563                        completed = true;
9564
9565                        // Clear timeout if it exists
9566                        if (timeoutTimer) {
9567                            window.clearTimeout(timeoutTimer);
9568                        }
9569
9570                        // Dereference transport for early garbage collection
9571                        // (no matter how long the jqXHR object will be used)
9572                        transport = undefined;
9573
9574                        // Cache response headers
9575                        responseHeadersString = headers || "";
9576
9577                        // Set readyState
9578                        jqXHR.readyState = status > 0 ? 4 : 0;
9579
9580                        // Determine if successful
9581                        isSuccess = status >= 200 && status < 300 || status === 304;
9582
9583                        // Get response data
9584                        if (responses) {
9585                            response = ajaxHandleResponses(s, jqXHR, responses);
9586                        }
9587
9588                        // Use a noop converter for missing script but not if jsonp
9589                        if (!isSuccess &&
9590                            jQuery.inArray("script", s.dataTypes) > -1 &&
9591                            jQuery.inArray("json", s.dataTypes) < 0) {
9592                            s.converters["text script"] = function () {
9593                            };
9594                        }
9595
9596                        // Convert no matter what (that way responseXXX fields are always set)
9597                        response = ajaxConvert(s, response, jqXHR, isSuccess);
9598
9599                        // If successful, handle type chaining
9600                        if (isSuccess) {
9601
9602                            // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9603                            if (s.ifModified) {
9604                                modified = jqXHR.getResponseHeader("Last-Modified");
9605                                if (modified) {
9606                                    jQuery.lastModified[cacheURL] = modified;
9607                                }
9608                                modified = jqXHR.getResponseHeader("etag");
9609                                if (modified) {
9610                                    jQuery.etag[cacheURL] = modified;
9611                                }
9612                            }
9613
9614                            // if no content
9615                            if (status === 204 || s.type === "HEAD") {
9616                                statusText = "nocontent";
9617
9618                                // if not modified
9619                            } else if (status === 304) {
9620                                statusText = "notmodified";
9621
9622                                // If we have data, let's convert it
9623                            } else {
9624                                statusText = response.state;
9625                                success = response.data;
9626                                error = response.error;
9627                                isSuccess = !error;
9628                            }
9629                        } else {
9630
9631                            // Extract error from statusText and normalize for non-aborts
9632                            error = statusText;
9633                            if (status || !statusText) {
9634                                statusText = "error";
9635                                if (status < 0) {
9636                                    status = 0;
9637                                }
9638                            }
9639                        }
9640
9641                        // Set data for the fake xhr object
9642                        jqXHR.status = status;
9643                        jqXHR.statusText = (nativeStatusText || statusText) + "";
9644
9645                        // Success/Error
9646                        if (isSuccess) {
9647                            deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);
9648                        } else {
9649                            deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);
9650                        }
9651
9652                        // Status-dependent callbacks
9653                        jqXHR.statusCode(statusCode);
9654                        statusCode = undefined;
9655
9656                        if (fireGlobals) {
9657                            globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError",
9658                                [jqXHR, s, isSuccess ? success : error]);
9659                        }
9660
9661                        // Complete
9662                        completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);
9663
9664                        if (fireGlobals) {
9665                            globalEventContext.trigger("ajaxComplete", [jqXHR, s]);
9666
9667                            // Handle the global AJAX counter
9668                            if (!(--jQuery.active)) {
9669                                jQuery.event.trigger("ajaxStop");
9670                            }
9671                        }
9672                    }
9673
9674                    return jqXHR;
9675                },
9676
9677                getJSON: function (url, data, callback) {
9678                    return jQuery.get(url, data, callback, "json");
9679                },
9680
9681                getScript: function (url, callback) {
9682                    return jQuery.get(url, undefined, callback, "script");
9683                }
9684            });
9685
9686            jQuery.each(["get", "post"], function (_i, method) {
9687                jQuery[method] = function (url, data, callback, type) {
9688
9689                    // Shift arguments if data argument was omitted
9690                    if (isFunction(data)) {
9691                        type = type || callback;
9692                        callback = data;
9693                        data = undefined;
9694                    }
9695
9696                    // The url can be an options object (which then must have .url)
9697                    return jQuery.ajax(jQuery.extend({
9698                        url: url,
9699                        type: method,
9700                        dataType: type,
9701                        data: data,
9702                        success: callback
9703                    }, jQuery.isPlainObject(url) && url));
9704                };
9705            });
9706
9707            jQuery.ajaxPrefilter(function (s) {
9708                var i;
9709                for (i in s.headers) {
9710                    if (i.toLowerCase() === "content-type") {
9711                        s.contentType = s.headers[i] || "";
9712                    }
9713                }
9714            });
9715
9716
9717            jQuery._evalUrl = function (url, options, doc) {
9718                return jQuery.ajax({
9719                    url: url,
9720
9721                    // Make this explicit, since user can override this through ajaxSetup (trac-11264)
9722                    type: "GET",
9723                    dataType: "script",
9724                    cache: true,
9725                    async: false,
9726                    global: false,
9727
9728                    // Only evaluate the response if it is successful (gh-4126)
9729                    // dataFilter is not invoked for failure responses, so using it instead
9730                    // of the default converter is kludgy but it works.
9731                    converters: {
9732                        "text script": function () {
9733                        }
9734                    },
9735                    dataFilter: function (response) {
9736                        jQuery.globalEval(response, options, doc);
9737                    }
9738                });
9739            };
9740
9741
9742            jQuery.fn.extend({
9743                wrapAll: function (html) {
9744                    var wrap;
9745
9746                    if (this[0]) {
9747                        if (isFunction(html)) {
9748                            html = html.call(this[0]);
9749                        }
9750
9751                        // The elements to wrap the target around
9752                        wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);
9753
9754                        if (this[0].parentNode) {
9755                            wrap.insertBefore(this[0]);
9756                        }
9757
9758                        wrap.map(function () {
9759                            var elem = this;
9760
9761                            while (elem.firstElementChild) {
9762                                elem = elem.firstElementChild;
9763                            }
9764
9765                            return elem;
9766                        }).append(this);
9767                    }
9768
9769                    return this;
9770                },
9771
9772                wrapInner: function (html) {
9773                    if (isFunction(html)) {
9774                        return this.each(function (i) {
9775                            jQuery(this).wrapInner(html.call(this, i));
9776                        });
9777                    }
9778
9779                    return this.each(function () {
9780                        var self = jQuery(this),
9781                            contents = self.contents();
9782
9783                        if (contents.length) {
9784                            contents.wrapAll(html);
9785
9786                        } else {
9787                            self.append(html);
9788                        }
9789                    });
9790                },
9791
9792                wrap: function (html) {
9793                    var htmlIsFunction = isFunction(html);
9794
9795                    return this.each(function (i) {
9796                        jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html);
9797                    });
9798                },
9799
9800                unwrap: function (selector) {
9801                    this.parent(selector).not("body").each(function () {
9802                        jQuery(this).replaceWith(this.childNodes);
9803                    });
9804                    return this;
9805                }
9806            });
9807
9808
9809            jQuery.expr.pseudos.hidden = function (elem) {
9810                return !jQuery.expr.pseudos.visible(elem);
9811            };
9812            jQuery.expr.pseudos.visible = function (elem) {
9813                return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
9814            };
9815
9816
9817            jQuery.ajaxSettings.xhr = function () {
9818                try {
9819                    return new window.XMLHttpRequest();
9820                } catch (e) {
9821                }
9822            };
9823
9824            var xhrSuccessStatus = {
9825
9826                    // File protocol always yields status code 0, assume 200
9827                    0: 200,
9828
9829                    // Support: IE <=9 only
9830                    // trac-1450: sometimes IE returns 1223 when it should be 204
9831                    1223: 204
9832                },
9833                xhrSupported = jQuery.ajaxSettings.xhr();
9834
9835            support.cors = !!xhrSupported && ("withCredentials" in xhrSupported);
9836            support.ajax = xhrSupported = !!xhrSupported;
9837
9838            jQuery.ajaxTransport(function (options) {
9839                var callback, errorCallback;
9840
9841                // Cross domain only allowed if supported through XMLHttpRequest
9842                if (support.cors || xhrSupported && !options.crossDomain) {
9843                    return {
9844                        send: function (headers, complete) {
9845                            var i,
9846                                xhr = options.xhr();
9847
9848                            xhr.open(
9849                                options.type,
9850                                options.url,
9851                                options.async,
9852                                options.username,
9853                                options.password
9854                            );
9855
9856                            // Apply custom fields if provided
9857                            if (options.xhrFields) {
9858                                for (i in options.xhrFields) {
9859                                    xhr[i] = options.xhrFields[i];
9860                                }
9861                            }
9862
9863                            // Override mime type if needed
9864                            if (options.mimeType && xhr.overrideMimeType) {
9865                                xhr.overrideMimeType(options.mimeType);
9866                            }
9867
9868                            // X-Requested-With header
9869                            // For cross-domain requests, seeing as conditions for a preflight are
9870                            // akin to a jigsaw puzzle, we simply never set it to be sure.
9871                            // (it can always be set on a per-request basis or even using ajaxSetup)
9872                            // For same-domain requests, won't change header if already provided.
9873                            if (!options.crossDomain && !headers["X-Requested-With"]) {
9874                                headers["X-Requested-With"] = "XMLHttpRequest";
9875                            }
9876
9877                            // Set headers
9878                            for (i in headers) {
9879                                xhr.setRequestHeader(i, headers[i]);
9880                            }
9881
9882                            // Callback
9883                            callback = function (type) {
9884                                return function () {
9885                                    if (callback) {
9886                                        callback = errorCallback = xhr.onload =
9887                                            xhr.onerror = xhr.onabort = xhr.ontimeout =
9888                                                xhr.onreadystatechange = null;
9889
9890                                        if (type === "abort") {
9891                                            xhr.abort();
9892                                        } else if (type === "error") {
9893
9894                                            // Support: IE <=9 only
9895                                            // On a manual native abort, IE9 throws
9896                                            // errors on any property access that is not readyState
9897                                            if (typeof xhr.status !== "number") {
9898                                                complete(0, "error");
9899                                            } else {
9900                                                complete(
9901                                                    // File: protocol always yields status 0; see trac-8605, trac-14207
9902                                                    xhr.status,
9903                                                    xhr.statusText
9904                                                );
9905                                            }
9906                                        } else {
9907                                            complete(
9908                                                xhrSuccessStatus[xhr.status] || xhr.status,
9909                                                xhr.statusText,
9910
9911                                                // Support: IE <=9 only
9912                                                // IE9 has no XHR2 but throws on binary (trac-11426)
9913                                                // For XHR2 non-text, let the caller handle it (gh-2498)
9914                                                (xhr.responseType || "text") !== "text" ||
9915                                                typeof xhr.responseText !== "string" ?
9916                                                    {binary: xhr.response} :
9917                                                    {text: xhr.responseText},
9918                                                xhr.getAllResponseHeaders()
9919                                            );
9920                                        }
9921                                    }
9922                                };
9923                            };
9924
9925                            // Listen to events
9926                            xhr.onload = callback();
9927                            errorCallback = xhr.onerror = xhr.ontimeout = callback("error");
9928
9929                            // Support: IE 9 only
9930                            // Use onreadystatechange to replace onabort
9931                            // to handle uncaught aborts
9932                            if (xhr.onabort !== undefined) {
9933                                xhr.onabort = errorCallback;
9934                            } else {
9935                                xhr.onreadystatechange = function () {
9936
9937                                    // Check readyState before timeout as it changes
9938                                    if (xhr.readyState === 4) {
9939
9940                                        // Allow onerror to be called first,
9941                                        // but that will not handle a native abort
9942                                        // Also, save errorCallback to a variable
9943                                        // as xhr.onerror cannot be accessed
9944                                        window.setTimeout(function () {
9945                                            if (callback) {
9946                                                errorCallback();
9947                                            }
9948                                        });
9949                                    }
9950                                };
9951                            }
9952
9953                            // Create the abort callback
9954                            callback = callback("abort");
9955
9956                            try {
9957
9958                                // Do send the request (this may raise an exception)
9959                                xhr.send(options.hasContent && options.data || null);
9960                            } catch (e) {
9961
9962                                // trac-14683: Only rethrow if this hasn't been notified as an error yet
9963                                if (callback) {
9964                                    throw e;
9965                                }
9966                            }
9967                        },
9968
9969                        abort: function () {
9970                            if (callback) {
9971                                callback();
9972                            }
9973                        }
9974                    };
9975                }
9976            });
9977
9978
9979            // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
9980            jQuery.ajaxPrefilter(function (s) {
9981                if (s.crossDomain) {
9982                    s.contents.script = false;
9983                }
9984            });
9985
9986            // Install script dataType
9987            jQuery.ajaxSetup({
9988                accepts: {
9989                    script: "text/javascript, application/javascript, " +
9990                        "application/ecmascript, application/x-ecmascript"
9991                },
9992                contents: {
9993                    script: /\b(?:java|ecma)script\b/
9994                },
9995                converters: {
9996                    "text script": function (text) {
9997                        jQuery.globalEval(text);
9998                        return text;
9999                    }
10000                }
10001            });
10002
10003            // Handle cache's special case and crossDomain
10004            jQuery.ajaxPrefilter("script", function (s) {
10005                if (s.cache === undefined) {
10006                    s.cache = false;
10007                }
10008                if (s.crossDomain) {
10009                    s.type = "GET";
10010                }
10011            });
10012
10013            // Bind script tag hack transport
10014            jQuery.ajaxTransport("script", function (s) {
10015
10016                // This transport only deals with cross domain or forced-by-attrs requests
10017                if (s.crossDomain || s.scriptAttrs) {
10018                    var script, callback;
10019                    return {
10020                        send: function (_, complete) {
10021                            script = jQuery("<script>")
10022                                .attr(s.scriptAttrs || {})
10023                                .prop({charset: s.scriptCharset, src: s.url})
10024                                .on("load error", callback = function (evt) {
10025                                    script.remove();
10026                                    callback = null;
10027                                    if (evt) {
10028                                        complete(evt.type === "error" ? 404 : 200, evt.type);
10029                                    }
10030                                });
10031
10032                            // Use native DOM manipulation to avoid our domManip AJAX trickery
10033                            document.head.appendChild(script[0]);
10034                        },
10035                        abort: function () {
10036                            if (callback) {
10037                                callback();
10038                            }
10039                        }
10040                    };
10041                }
10042            });
10043
10044
10045            var oldCallbacks = [],
10046                rjsonp = /(=)\?(?=&|$)|\?\?/;
10047
10048            // Default jsonp settings
10049            jQuery.ajaxSetup({
10050                jsonp: "callback",
10051                jsonpCallback: function () {
10052                    var callback = oldCallbacks.pop() || (jQuery.expando + "_" + (nonce.guid++));
10053                    this[callback] = true;
10054                    return callback;
10055                }
10056            });
10057
10058            // Detect, normalize options and install callbacks for jsonp requests
10059            jQuery.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) {
10060
10061                var callbackName, overwritten, responseContainer,
10062                    jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ?
10063                            "url" :
10064                            typeof s.data === "string" &&
10065                            (s.contentType || "")
10066                                .indexOf("application/x-www-form-urlencoded") === 0 &&
10067                            rjsonp.test(s.data) && "data"
10068                    );
10069
10070                // Handle iff the expected data type is "jsonp" or we have a parameter to set
10071                if (jsonProp || s.dataTypes[0] === "jsonp") {
10072
10073                    // Get callback name, remembering preexisting value associated with it
10074                    callbackName = s.jsonpCallback = isFunction(s.jsonpCallback) ?
10075                        s.jsonpCallback() :
10076                        s.jsonpCallback;
10077
10078                    // Insert callback into url or form data
10079                    if (jsonProp) {
10080                        s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
10081                    } else if (s.jsonp !== false) {
10082                        s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
10083                    }
10084
10085                    // Use data converter to retrieve json after script execution
10086                    s.converters["script json"] = function () {
10087                        if (!responseContainer) {
10088                            jQuery.error(callbackName + " was not called");
10089                        }
10090                        return responseContainer[0];
10091                    };
10092
10093                    // Force json dataType
10094                    s.dataTypes[0] = "json";
10095
10096                    // Install callback
10097                    overwritten = window[callbackName];
10098                    window[callbackName] = function () {
10099                        responseContainer = arguments;
10100                    };
10101
10102                    // Clean-up function (fires after converters)
10103                    jqXHR.always(function () {
10104
10105                        // If previous value didn't exist - remove it
10106                        if (overwritten === undefined) {
10107                            jQuery(window).removeProp(callbackName);
10108
10109                            // Otherwise restore preexisting value
10110                        } else {
10111                            window[callbackName] = overwritten;
10112                        }
10113
10114                        // Save back as free
10115                        if (s[callbackName]) {
10116
10117                            // Make sure that re-using the options doesn't screw things around
10118                            s.jsonpCallback = originalSettings.jsonpCallback;
10119
10120                            // Save the callback name for future use
10121                            oldCallbacks.push(callbackName);
10122                        }
10123
10124                        // Call if it was a function and we have a response
10125                        if (responseContainer && isFunction(overwritten)) {
10126                            overwritten(responseContainer[0]);
10127                        }
10128
10129                        responseContainer = overwritten = undefined;
10130                    });
10131
10132                    // Delegate to script
10133                    return "script";
10134                }
10135            });
10136
10137
10138            // Support: Safari 8 only
10139            // In Safari 8 documents created via document.implementation.createHTMLDocument
10140            // collapse sibling forms: the second one becomes a child of the first one.
10141            // Because of that, this security measure has to be disabled in Safari 8.
10142            // https://bugs.webkit.org/show_bug.cgi?id=137337
10143            support.createHTMLDocument = (function () {
10144                var body = document.implementation.createHTMLDocument("").body;
10145                body.innerHTML = "<form></form><form></form>";
10146                return body.childNodes.length === 2;
10147            })();
10148
10149
10150            // Argument "data" should be string of html
10151            // context (optional): If specified, the fragment will be created in this context,
10152            // defaults to document
10153            // keepScripts (optional): If true, will include scripts passed in the html string
10154            jQuery.parseHTML = function (data, context, keepScripts) {
10155                if (typeof data !== "string") {
10156                    return [];
10157                }
10158                if (typeof context === "boolean") {
10159                    keepScripts = context;
10160                    context = false;
10161                }
10162
10163                var base, parsed, scripts;
10164
10165                if (!context) {
10166
10167                    // Stop scripts or inline event handlers from being executed immediately
10168                    // by using document.implementation
10169                    if (support.createHTMLDocument) {
10170                        context = document.implementation.createHTMLDocument("");
10171
10172                        // Set the base href for the created document
10173                        // so any parsed elements with URLs
10174                        // are based on the document's URL (gh-2965)
10175                        base = context.createElement("base");
10176                        base.href = document.location.href;
10177                        context.head.appendChild(base);
10178                    } else {
10179                        context = document;
10180                    }
10181                }
10182
10183                parsed = rsingleTag.exec(data);
10184                scripts = !keepScripts && [];
10185
10186                // Single tag
10187                if (parsed) {
10188                    return [context.createElement(parsed[1])];
10189                }
10190
10191                parsed = buildFragment([data], context, scripts);
10192
10193                if (scripts && scripts.length) {
10194                    jQuery(scripts).remove();
10195                }
10196
10197                return jQuery.merge([], parsed.childNodes);
10198            };
10199
10200
10201            /**
10202             * Load a url into a page
10203             */
10204            jQuery.fn.load = function (url, params, callback) {
10205                var selector, type, response,
10206                    self = this,
10207                    off = url.indexOf(" ");
10208
10209                if (off > -1) {
10210                    selector = stripAndCollapse(url.slice(off));
10211                    url = url.slice(0, off);
10212                }
10213
10214                // If it's a function
10215                if (isFunction(params)) {
10216
10217                    // We assume that it's the callback
10218                    callback = params;
10219                    params = undefined;
10220
10221                    // Otherwise, build a param string
10222                } else if (params && typeof params === "object") {
10223                    type = "POST";
10224                }
10225
10226                // If we have elements to modify, make the request
10227                if (self.length > 0) {
10228                    jQuery.ajax({
10229                        url: url,
10230
10231                        // If "type" variable is undefined, then "GET" method will be used.
10232                        // Make value of this field explicit since
10233                        // user can override it through ajaxSetup method
10234                        type: type || "GET",
10235                        dataType: "html",
10236                        data: params
10237                    }).done(function (responseText) {
10238
10239                        // Save response for use in complete callback
10240                        response = arguments;
10241
10242                        self.html(selector ?
10243
10244                            // If a selector was specified, locate the right elements in a dummy div
10245                            // Exclude scripts to avoid IE 'Permission Denied' errors
10246                            jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :
10247
10248                            // Otherwise use the full result
10249                            responseText);
10250
10251                        // If the request succeeds, this function gets "data", "status", "jqXHR"
10252                        // but they are ignored because response was set above.
10253                        // If it fails, this function gets "jqXHR", "status", "error"
10254                    }).always(callback && function (jqXHR, status) {
10255                        self.each(function () {
10256                            callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);
10257                        });
10258                    });
10259                }
10260
10261                return this;
10262            };
10263
10264
10265            jQuery.expr.pseudos.animated = function (elem) {
10266                return jQuery.grep(jQuery.timers, function (fn) {
10267                    return elem === fn.elem;
10268                }).length;
10269            };
10270
10271
10272            jQuery.offset = {
10273                setOffset: function (elem, options, i) {
10274                    var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10275                        position = jQuery.css(elem, "position"),
10276                        curElem = jQuery(elem),
10277                        props = {};
10278
10279                    // Set position first, in-case top/left are set even on static elem
10280                    if (position === "static") {
10281                        elem.style.position = "relative";
10282                    }
10283
10284                    curOffset = curElem.offset();
10285                    curCSSTop = jQuery.css(elem, "top");
10286                    curCSSLeft = jQuery.css(elem, "left");
10287                    calculatePosition = (position === "absolute" || position === "fixed") &&
10288                        (curCSSTop + curCSSLeft).indexOf("auto") > -1;
10289
10290                    // Need to be able to calculate position if either
10291                    // top or left is auto and position is either absolute or fixed
10292                    if (calculatePosition) {
10293                        curPosition = curElem.position();
10294                        curTop = curPosition.top;
10295                        curLeft = curPosition.left;
10296
10297                    } else {
10298                        curTop = parseFloat(curCSSTop) || 0;
10299                        curLeft = parseFloat(curCSSLeft) || 0;
10300                    }
10301
10302                    if (isFunction(options)) {
10303
10304                        // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10305                        options = options.call(elem, i, jQuery.extend({}, curOffset));
10306                    }
10307
10308                    if (options.top != null) {
10309                        props.top = (options.top - curOffset.top) + curTop;
10310                    }
10311                    if (options.left != null) {
10312                        props.left = (options.left - curOffset.left) + curLeft;
10313                    }
10314
10315                    if ("using" in options) {
10316                        options.using.call(elem, props);
10317
10318                    } else {
10319                        curElem.css(props);
10320                    }
10321                }
10322            };
10323
10324            jQuery.fn.extend({
10325
10326                // offset() relates an element's border box to the document origin
10327                offset: function (options) {
10328
10329                    // Preserve chaining for setter
10330                    if (arguments.length) {
10331                        return options === undefined ?
10332                            this :
10333                            this.each(function (i) {
10334                                jQuery.offset.setOffset(this, options, i);
10335                            });
10336                    }
10337
10338                    var rect, win,
10339                        elem = this[0];
10340
10341                    if (!elem) {
10342                        return;
10343                    }
10344
10345                    // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
10346                    // Support: IE <=11 only
10347                    // Running getBoundingClientRect on a
10348                    // disconnected node in IE throws an error
10349                    if (!elem.getClientRects().length) {
10350                        return {top: 0, left: 0};
10351                    }
10352
10353                    // Get document-relative position by adding viewport scroll to viewport-relative gBCR
10354                    rect = elem.getBoundingClientRect();
10355                    win = elem.ownerDocument.defaultView;
10356                    return {
10357                        top: rect.top + win.pageYOffset,
10358                        left: rect.left + win.pageXOffset
10359                    };
10360                },
10361
10362                // position() relates an element's margin box to its offset parent's padding box
10363                // This corresponds to the behavior of CSS absolute positioning
10364                position: function () {
10365                    if (!this[0]) {
10366                        return;
10367                    }
10368
10369                    var offsetParent, offset, doc,
10370                        elem = this[0],
10371                        parentOffset = {top: 0, left: 0};
10372
10373                    // position:fixed elements are offset from the viewport, which itself always has zero offset
10374                    if (jQuery.css(elem, "position") === "fixed") {
10375
10376                        // Assume position:fixed implies availability of getBoundingClientRect
10377                        offset = elem.getBoundingClientRect();
10378
10379                    } else {
10380                        offset = this.offset();
10381
10382                        // Account for the *real* offset parent, which can be the document or its root element
10383                        // when a statically positioned element is identified
10384                        doc = elem.ownerDocument;
10385                        offsetParent = elem.offsetParent || doc.documentElement;
10386                        while (offsetParent &&
10387                        (offsetParent === doc.body || offsetParent === doc.documentElement) &&
10388                        jQuery.css(offsetParent, "position") === "static") {
10389
10390                            offsetParent = offsetParent.parentNode;
10391                        }
10392                        if (offsetParent && offsetParent !== elem && offsetParent.nodeType === 1) {
10393
10394                            // Incorporate borders into its offset, since they are outside its content origin
10395                            parentOffset = jQuery(offsetParent).offset();
10396                            parentOffset.top += jQuery.css(offsetParent, "borderTopWidth", true);
10397                            parentOffset.left += jQuery.css(offsetParent, "borderLeftWidth", true);
10398                        }
10399                    }
10400
10401                    // Subtract parent offsets and element margins
10402                    return {
10403                        top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
10404                        left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
10405                    };
10406                },
10407
10408                // This method will return documentElement in the following cases:
10409                // 1) For the element inside the iframe without offsetParent, this method will return
10410                //    documentElement of the parent window
10411                // 2) For the hidden or detached element
10412                // 3) For body or html element, i.e. in case of the html node - it will return itself
10413                //
10414                // but those exceptions were never presented as a real life use-cases
10415                // and might be considered as more preferable results.
10416                //
10417                // This logic, however, is not guaranteed and can change at any point in the future
10418                offsetParent: function () {
10419                    return this.map(function () {
10420                        var offsetParent = this.offsetParent;
10421
10422                        while (offsetParent && jQuery.css(offsetParent, "position") === "static") {
10423                            offsetParent = offsetParent.offsetParent;
10424                        }
10425
10426                        return offsetParent || documentElement;
10427                    });
10428                }
10429            });
10430
10431            // Create scrollLeft and scrollTop methods
10432            jQuery.each({scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function (method, prop) {
10433                var top = "pageYOffset" === prop;
10434
10435                jQuery.fn[method] = function (val) {
10436                    return access(this, function (elem, method, val) {
10437
10438                        // Coalesce documents and windows
10439                        var win;
10440                        if (isWindow(elem)) {
10441                            win = elem;
10442                        } else if (elem.nodeType === 9) {
10443                            win = elem.defaultView;
10444                        }
10445
10446                        if (val === undefined) {
10447                            return win ? win[prop] : elem[method];
10448                        }
10449
10450                        if (win) {
10451                            win.scrollTo(
10452                                !top ? val : win.pageXOffset,
10453                                top ? val : win.pageYOffset
10454                            );
10455
10456                        } else {
10457                            elem[method] = val;
10458                        }
10459                    }, method, val, arguments.length);
10460                };
10461            });
10462
10463            // Support: Safari <=7 - 9.1, Chrome <=37 - 49
10464            // Add the top/left cssHooks using jQuery.fn.position
10465            // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10466            // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
10467            // getComputedStyle returns percent when specified for top/left/bottom/right;
10468            // rather than make the css module depend on the offset module, just check for it here
10469            jQuery.each(["top", "left"], function (_i, prop) {
10470                jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition,
10471                    function (elem, computed) {
10472                        if (computed) {
10473                            computed = curCSS(elem, prop);
10474
10475                            // If curCSS returns percentage, fallback to offset
10476                            return rnumnonpx.test(computed) ?
10477                                jQuery(elem).position()[prop] + "px" :
10478                                computed;
10479                        }
10480                    }
10481                );
10482            });
10483
10484
10485            // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10486            jQuery.each({Height: "height", Width: "width"}, function (name, type) {
10487                jQuery.each({
vendor: 4,243 bytes, lines 10488-10591
10488                    padding: "inner" + name,
10489                    content: type,
10490                    "": "outer" + name
10491                }, function (defaultExtra, funcName) {
10492
10493                    // Margin is only for outerHeight, outerWidth
10494                    jQuery.fn[funcName] = function (margin, value) {
10495                        var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
10496                            extra = defaultExtra || (margin === true || value === true ? "margin" : "border");
10497
10498                        return access(this, function (elem, type, value) {
10499                            var doc;
10500
10501                            if (isWindow(elem)) {
10502
10503                                // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
10504                                return funcName.indexOf("outer") === 0 ?
10505                                    elem["inner" + name] :
10506                                    elem.document.documentElement["client" + name];
10507                            }
10508
10509                            // Get document width or height
10510                            if (elem.nodeType === 9) {
10511                                doc = elem.documentElement;
10512
10513                                // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10514                                // whichever is greatest
10515                                return Math.max(
10516                                    elem.body["scroll" + name], doc["scroll" + name],
10517                                    elem.body["offset" + name], doc["offset" + name],
10518                                    doc["client" + name]
10519                                );
10520                            }
10521
10522                            return value === undefined ?
10523
10524                                // Get width or height on the element, requesting but not forcing parseFloat
10525                                jQuery.css(elem, type, extra) :
10526
10527                                // Set width or height on the element
10528                                jQuery.style(elem, type, value, extra);
10529                        }, type, chainable ? margin : undefined, chainable);
10530                    };
10531                });
10532            });
10533
10534
10535            jQuery.each([
10536                "ajaxStart",
10537                "ajaxStop",
10538                "ajaxComplete",
10539                "ajaxError",
10540                "ajaxSuccess",
10541                "ajaxSend"
10542            ], function (_i, type) {
10543                jQuery.fn[type] = function (fn) {
10544                    return this.on(type, fn);
10545                };
10546            });
10547
10548
10549            jQuery.fn.extend({
10550
10551                bind: function (types, data, fn) {
10552                    return this.on(types, null, data, fn);
10553                },
10554                unbind: function (types, fn) {
10555                    return this.off(types, null, fn);
10556                },
10557
10558                delegate: function (selector, types, data, fn) {
10559                    return this.on(types, selector, data, fn);
10560                },
10561                undelegate: function (selector, types, fn) {
10562
10563                    // ( namespace ) or ( selector, types [, fn] )
10564                    return arguments.length === 1 ?
10565                        this.off(selector, "**") :
10566                        this.off(types, selector || "**", fn);
10567                },
10568
10569                hover: function (fnOver, fnOut) {
10570                    return this
10571                        .on("mouseenter", fnOver)
10572                        .on("mouseleave", fnOut || fnOver);
10573                }
10574            });
10575
10576            jQuery.each(
10577                ("blur focus focusin focusout resize scroll click dblclick " +
10578                    "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
10579                    "change select submit keydown keypress keyup contextmenu").split(" "),
10580                function (_i, name) {
10581
10582                    // Handle event binding
10583                    jQuery.fn[name] = function (data, fn) {
10584                        return arguments.length > 0 ?
10585                            this.on(name, null, data, fn) :
10586                            this.trigger(name);
10587                    };
10588                }
10589            );
10590
10591
10592            // Support: Android <=4.0 only
10593            // Make sure we trim BOM and NBSP
10594            // Require that the "whitespace run" starts from a non-whitespace
10595            // to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position.
10596            var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;
10597
10598            // Bind a function to a context, optionally partially applying any
10599            // arguments.
10600            // jQuery.proxy is deprecated to promote standards (specifically Function#bind)
10601            // However, it is not slated for removal any time soon
10602            jQuery.proxy = function (fn, context) {
10603                var tmp, args, proxy;
10604
10605                if (typeof context === "string") {
10606                    tmp = fn[context];
10607                    context = fn;
10608                    fn = tmp;
10609                }
10610
10611                // Quick check to determine if target is callable, in the spec
10612                // this throws a TypeError, but we will just return undefined.
10613                if (!isFunction(fn)) {
10614                    return undefined;
10615                }
10616
10617                // Simulated bind
10618                args = slice.call(arguments, 2);
10619                proxy = function () {
10620                    return fn.apply(context || this, args.concat(slice.call(arguments)));
10621                };
10622
10623                // Set the guid of unique handler to the same of original handler, so it can be removed
10624                proxy.guid = fn.guid = fn.guid || jQuery.guid++;
10625
10626                return proxy;
10627            };
10628
10629            jQuery.holdReady = function (hold) {
10630                if (hold) {
10631                    jQuery.readyWait++;
10632                } else {
10633                    jQuery.ready(true);
10634                }
10635            };
10636            jQuery.isArray = Array.isArray;
10637            jQuery.parseJSON = JSON.parse;
10638            jQuery.nodeName = nodeName;
10639            jQuery.isFunction = isFunction;
10640            jQuery.isWindow = isWindow;
10641            jQuery.camelCase = camelCase;
10642            jQuery.type = toType;
10643
10644            jQuery.now = Date.now;
10645
10646            jQuery.isNumeric = function (obj) {
10647
10648                // As of jQuery 3.0, isNumeric is limited to
10649                // strings and numbers (primitives or objects)
10650                // that can be coerced to finite numbers (gh-2662)
10651                var type = jQuery.type(obj);
10652                return (type === "number" || type === "string") &&
10653
10654                    // parseFloat NaNs numeric-cast false positives ("")
10655                    // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
10656                    // subtraction forces infinities to NaN
10657                    !isNaN(obj - parseFloat(obj));
10658            };
10659
10660            jQuery.trim = function (text) {
10661                return text == null ?
10662                    "" :
10663                    (text + "").replace(rtrim, "$1");
10664            };
10665
10666
10667            var
10668
10669                // Map over jQuery in case of overwrite
10670                _jQuery = window.jQuery,
10671
10672                // Map over the $ in case of overwrite
10673                _$ = window.$;
10674
10675            jQuery.noConflict = function (deep) {
10676                if (window.$ === jQuery) {
10677                    window.$ = _$;
10678                }
10679
10680                if (deep && window.jQuery === jQuery) {
10681                    window.jQuery = _jQuery;
10682                }
10683
10684                return jQuery;
10685            };
10686
10687            // Expose jQuery and $ identifiers, even in AMD
10688            // (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557)
10689            // and CommonJS for browser emulators (trac-13566)
10690            if (typeof noGlobal === "undefined") {
10691                window.jQuery = window.$ = jQuery;
10692            }
10693
10694
10695            return jQuery;
10696        });
10697    }(jquery$1));
10698    return jquery$1.exports;
10699}
10700
10701var jqueryExports = requireJquery();
10702const $ = /*@__PURE__*/getDefaultExportFromCjs(jqueryExports);
10703
10704$(() => {
10705    if (+$(document.documentElement).width() <= 1024) {
10706        $(".safety .tile_popup").removeClass("tile_popup");
10707    }
10708});
10709
10710$(() => {
10711
10712    function randomInteger(min, max) {
10713        let rand = min + Math.random() * (max + 1 - min);
10714        return Math.floor(rand);
10715    }
10716
10717    function animation(element, speed) {
10718        let left = element.offset().left;
10719        const width = element.width();
10720        const end = (width * -1) - 200;
10721
10722        element.css({
10723            right: "auto",
10724            left: left + "px",
10725            transitionDuration: "0.1s",
10726        });
10727
10728        function animate() {
10729            if (left >= end) {
10730                left -= speed;
10731                element.css({left: left, transitionDuration: "0.1s"});
10732            } else {
10733                left = $(document.documentElement).width();
10734                element.css({left: left, transitionDuration: "0s"});
10735            }
10736            requestAnimationFrame(animate);
10737        }
10738
10739        requestAnimationFrame(animate);
10740    }
10741
10742    $(".payback-item").each(function () {
10743        animation($(this), randomInteger(2, 3));
10744    });
10745
10746});
10747
10748var fslightbox = {exports: {}};
10749
10750var hasRequiredFslightbox;
10751
10752function requireFslightbox() {
10753    if (hasRequiredFslightbox) return fslightbox.exports;
10754    hasRequiredFslightbox = 1;
10755    (function (module, exports) {
10756        !function (e, t) {
10757            module.exports = t();
10758        }(window, (function () {
10759            return function (e) {
10760                var t = {};
10761
10762                function n(o) {
10763                    if (t[o]) return t[o].exports;
10764                    var i = t[o] = {i: o, l: false, exports: {}};
10765                    return e[o].call(i.exports, i, i.exports, n), i.l = true, i.exports
10766                }
10767
10768                return n.m = e, n.c = t, n.d = function (e, t, o) {
10769                    n.o(e, t) || Object.defineProperty(e, t, {enumerable: true, get: o});
10770                }, n.r = function (e) {
10771                    "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {value: "Module"}), Object.defineProperty(e, "__esModule", {value: true});
10772                }, n.t = function (e, t) {
10773                    if (1 & t && (e = n(e)), 8 & t) return e;
10774                    if (4 & t && "object" == typeof e && e && e.__esModule) return e;
10775                    var o = Object.create(null);
10776                    if (n.r(o), Object.defineProperty(o, "default", {
10777                        enumerable: true,
10778                        value: e
10779                    }), 2 & t && "string" != typeof e) for (var i in e) n.d(o, i, function (t) {
10780                        return e[t]
10781                    }.bind(null, i));
10782                    return o
10783                }, n.n = function (e) {
10784                    var t = e && e.__esModule ? function () {
10785                        return e.default
10786                    } : function () {
10787                        return e
10788                    };
10789                    return n.d(t, "a", t), t
10790                }, n.o = function (e, t) {
10791                    return Object.prototype.hasOwnProperty.call(e, t)
10792                }, n.p = "", n(n.s = 0)
10793            }([function (e, t, n) {
10794                n.r(t);
10795                var o, i = "fslightbox-", s = "".concat(i, "styles"), r = "".concat(i, "cursor-grabbing"),
10796                    a = "".concat(i, "full-dimension"), c = "".concat(i, "flex-centered"), l = "".concat(i, "open"),
10797                    u = "".concat(i, "transform-transition"), d = "".concat(i, "absoluted"),
10798                    f = "".concat(i, "slide-btn"), p = "".concat(f, "-container"), h = "".concat(i, "fade-in"),
10799                    g = "".concat(i, "fade-out"), m = h + "-strong", v = g + "-strong", b = "".concat(i, "opacity-"),
10800                    x = "".concat(b, "1"), y = "".concat(i, "source");
10801
10802                function w(e) {
10803                    return (w = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (e) {
10804                        return typeof e
10805                    } : function (e) {
10806                        return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e
10807                    })(e)
10808                }
10809
10810                function S(e) {
10811                    var t = e.stageIndexes, n = e.core.stageManager, o = e.props.sources.length - 1;
10812                    n.getPreviousSlideIndex = function () {
10813                        return 0 === t.current ? o : t.current - 1
10814                    }, n.getNextSlideIndex = function () {
10815                        return t.current === o ? 0 : t.current + 1
10816                    }, n.updateStageIndexes = 0 === o ? function () {
10817                    } : 1 === o ? function () {
10818                        0 === t.current ? (t.next = 1, delete t.previous) : (t.previous = 0, delete t.next);
10819                    } : function () {
10820                        t.previous = n.getPreviousSlideIndex(), t.next = n.getNextSlideIndex();
10821                    }, n.i = o <= 2 ? function () {
10822                        return true
10823                    } : function (e) {
10824                        var n = t.current;
10825                        if (0 === n && e === o || n === o && 0 === e) return true;
10826                        var i = n - e;
10827                        return -1 === i || 0 === i || 1 === i
10828                    };
10829                }
10830
10831                "object" === ("undefined" == typeof document ? "undefined" : w(document)) && ((o = document.createElement("style")).className = s, o.appendChild(document.createTextNode(".fslightbox-absoluted{position:absolute;top:0;left:0}.fslightbox-fade-in{animation:fslightbox-fade-in .3s cubic-bezier(0,0,.7,1)}.fslightbox-fade-out{animation:fslightbox-fade-out .3s ease}.fslightbox-fade-in-strong{animation:fslightbox-fade-in-strong .3s cubic-bezier(0,0,.7,1)}.fslightbox-fade-out-strong{animation:fslightbox-fade-out-strong .3s ease}@keyframes fslightbox-fade-in{from{opacity:.65}to{opacity:1}}@keyframes fslightbox-fade-out{from{opacity:.35}to{opacity:0}
10831}@keyframes fslightbox-fade-in-strong{from{opacity:.3}to{opacity:1}}@keyframes fslightbox-fade-out-strong{from{opacity:1}to{opacity:0}}.fslightbox-cursor-grabbing{cursor:grabbing}.fslightbox-full-dimension{width:100%;height:100%}.fslightbox-open{overflow:hidden;height:100%}.fslightbox-flex-centered{display:flex;justify-content:center;align-items:center}.fslightbox-opacity-0{opacity:0!important}.fslightbox-opacity-1{opacity:1!important}.fslightbox-scrollbarfix{padding-right:17px}.fslightbox-transform-transition{transition:transform .3s}.fslightbox-container{font-family:Arial,sans-serif;position:fixed;top:0;left:0;background:linear-gradient(rgba(30,30,30,.9),#000 1810%);touch-action:pinch-zoom;z-index:1000000000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.fslightbox-container *{box-sizing:border-box}.fslightbox-svg{width:20px;height:20px}.fslightbox-svgp{transition:fill .15s ease;fill:#ddd}.fslightbox-nav{height:45px;width:100%;position:absolute;top:0;left:0}.fslightboxsn{z-index:0;display:flex;align-items:center;margin:14px 0 0 11px;font-size:15px;color:#d7d7d7}.fslightboxsn span{display:inline;vertical-align:middle}.fslightboxsl{display:inline-block!important;margin:0 5px;width:1px;height:12px;transform:rotate(15deg);background:white}.fslightbox-toolbar{position:absolute;z-index:3;right:0;top:0;height:100%;display:flex}.fslightbox-toolbar-button{width:45px;height:100%}.fslightbox-fsx{width:24px;height:24px}.fslightboxb{border:0;background:rgba(35,35,35,.65);cursor:pointer}.fslightboxb:focus{outline:0}.fslightboxb:focus .fslightbox-svgp{fill:#fff}.fslightboxb:hover .fslightbox-svgp{fill:#fff}.fslightbox-slide-btn-container{display:flex;align-items:center;padding:12px 12px 12px 6px;position:absolute;top:50%;cursor:pointer;z-index:3;transform:translateY(-50%)}.fslightbox-slide-btn-container-next{right:0;padding-left:12px;padding-right:3px}@media (min-width:476px){.fslightbox-slide-btn-container{padding:22px 22px 22px 6px}.fslightbox-slide-btn-container-next{padding-right:6px!important;padding-left:22px}}@media (min-width:768px){.fslightbox-slide-btn-container{padding:30px 30px 30px 6px}.fslightbox-slide-btn-container-next{padding-left:30px}.fslightbox-slide-btn{padding:10px}}.fslightbox-slide-btn-container:hover .fslightbox-svgp{fill:#fff}.fslightbox-slide-btn{padding:9px}.fslightbox-slide-btn-container-previous{left:0}@media (max-width:475.99px){.fslightbox-slide-btn-container-previous{padding-left:3px}}.fslightbox-down-event-detector{position:absolute;z-index:1}.fslightbox-slide-swiping-hoverer{z-index:4}.fslightbox-invalid-file-wrapper{font-size:22px;color:#eaebeb;margin:auto}.fslightboxv{object-fit:cover}.fslightbox-youtube-iframe{border:0}.fslightboxl{display:block;margin:auto;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:67px;height:67px}.fslightboxl div{box-sizing:border-box;display:block;position:absolute;width:54px;height:54px;margin:6px;border:5px solid;border-color:#999 transparent transparent transparent;border-radius:50%;animation:fslightboxl 1.2s cubic-bezier(.5,0,.5,1) infinite}.fslightboxl div:nth-child(1){animation-delay:-.45s}.fslightboxl div:nth-child(2){animation-delay:-.3s}.fslightboxl div:nth-child(3){animation-delay:-.15s}@keyframes fslightboxl{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.fslightbox-source{position:relative;z-index:2;opacity:0}@media (min-width:1200px){.fslightboxsn{margin:15px 0 0 12px;font-size:16px;display:block}.fslightboxsl{margin:0 6px 1px 6px;height:14px}.fslightbox-slide-btn{padding:11px}.fslightbox-svg{width:22px;height:22px}.fslightbox-fsx{width:26px;height:26px}.fslightbox-fso{width:22px;height:22px}.fslightboxl div{width:60px;height:60px;border-width:6px;border-color:#999 transparent transparent transparent;border-radius:50%}}@media (min-width:1600px){.fslightbox-nav{height:50px}.fslightboxsn{display:flex;margin:19px 0 0 16px;font-size:20px}.fslightboxsl{margin:0 7px 1px 7px;height:16px;width:2px;background:#d7d7d7}.fslightbox-toolbar-button{width:50px}.fslightbox-slide-btn{padding:12px}.fslightbox-svg{width:24px;height:24px}.fslightbox-fsx{width:28px;height:28px}.fslightbox-fso{width:24px;height:24px}}")), document.head.appendChild(o));
10832
10833                function L(e) {
10834                    var t, n = e.props, o = 0, i = {};
10835                    this.getSourceTypeFromLocalStorageByUrl = function (e) {
10836                        return t[e] ? t[e] : s(e)
10837                    }, this.handleReceivedSourceTypeForUrl = function (e, n) {
10838                        if (false === i[n] && (o--, "invalid" !== e ? i[n] = e : delete i[n], 0 === o)) {
10839                            !function (e, t) {
10840                                for (var n in t) e[n] = t[n];
10841                            }(t, i);
10842                            try {
10843                                localStorage.setItem("fslightbox-types", JSON.stringify(t));
10844                            } catch (e) {
10845                            }
10846                        }
10847                    };
10848                    var s = function (e) {
10849                        o++, i[e] = false;
10850                    };
10851                    if (n.disableLocalStorage) this.getSourceTypeFromLocalStorageByUrl = function () {
10852                    }, this.handleReceivedSourceTypeForUrl = function () {
10853                    }; else {
10854                        try {
10855                            t = JSON.parse(localStorage.getItem("fslightbox-types"));
10856                        } catch (e) {
10857                        }
10858                        t || (t = {}, this.getSourceTypeFromLocalStorageByUrl = s);
10859                    }
10860                }
10861
10862                function A(e, t, n, o) {
10863                    e.data;
10864                    var i = e.elements.sources, s = n / o, r = 0;
10865                    this.adjustSize = function () {
10866                        if ((r = e.mw / s) < e.mh) return n < e.mw && (r = o), a();
10867                        r = o > e.mh ? e.mh : o, a();
10868                    };
10869                    var a = function () {
10870                        i[t].style.width = r * s + "px", i[t].style.height = r + "px";
10871                    };
10872                }
10873
10874                function C(e, t) {
10875                    var n = this, o = e.collections.sourceSizers, i = e.elements, s = i.sourceAnimationWrappers,
10876                        r = i.sources, a = e.isl, c = e.resolve;
10877
10878                    function l(e, n) {
10879                        o[t] = c(A, [t, e, n]), o[t].adjustSize();
10880                    }
10881
10882                    this.runActions = function (e, o) {
10883                        a[t] = true, r[t].classList.add(x), s[t].classList.add(m), s[t].removeChild(s[t].firstChild), l(e, o), n.runActions = l;
10884                    };
10885                }
10886
10887                function E(e, t) {
10888                    var n, o = this, i = e.elements.sources, s = e.props, r = (0, e.resolve)(C, [t]);
10889                    this.handleImageLoad = function (e) {
10890                        var t = e.target, n = t.naturalWidth, o = t.naturalHeight;
10891                        r.runActions(n, o);
10892                    }, this.handleVideoLoad = function (e) {
10893                        var t = e.target, o = t.videoWidth, i = t.videoHeight;
10894                        n = true, r.runActions(o, i);
10895                    }, this.handleNotMetaDatedVideoLoad = function () {
10896                        n || o.handleYoutubeLoad();
10897                    }, this.handleYoutubeLoad = function () {
10898                        var e = 1920, t = 1080;
10899                        s.maxYoutubeDimensions && (e = s.maxYoutubeDimensions.width, t = s.maxYoutubeDimensions.height), r.runActions(e, t);
10900                    }, this.handleCustomLoad = function () {
10901                        var e = i[t], n = e.offsetWidth, s = e.offsetHeight;
10902                        n && s ? r.runActions(n, s) : setTimeout(o.handleCustomLoad);
10903                    };
10904                }
10905
10906                function F(e, t, n) {
10907                    var o = e.elements.sources, i = e.props.customClasses, s = i[t] ? i[t] : "";
10908                    o[t].className = n + " " + s;
10909                }
10910
10911                function I(e, t) {
10912                    var n = e.elements.sources, o = e.props.customAttributes;
10913                    for (var i in o[t]) n[t].setAttribute(i, o[t][i]);
10914                }
10915
10916                function z(e, t) {
10917                    var n = e.collections.sourceLoadHandlers, o = e.elements, i = o.sources,
10918                        s = o.sourceAnimationWrappers, r = e.props.sources;
10919                    i[t] = document.createElement("img"), F(e, t, y), i[t].src = r[t], i[t].onload = n[t].handleImageLoad, I(e, t), s[t].appendChild(i[t]);
10920                }
10921
10922                function T(e, t) {
10923                    var n = e.ap, o = e.collections.sourceLoadHandlers, i = e.elements, s = i.sources,
10924                        r = i.sourceAnimationWrappers, a = e.props, c = a.sources, l = a.videosPosters,
10925                        u = document.createElement("video"), d = document.createElement("source");
10926                    s[t] = u, F(e, t, "".concat(y, " fslightboxv")), u.src = c[t], u.onloadedmetadata = function (e) {
10927                        return o[t].handleVideoLoad(e)
10928                    }, u.controls = true, u.autoplay = n.i(t), I(e, t), l[t] && (s[t].poster = l[t]), d.src = c[t], u.appendChild(d), setTimeout(o[t].handleNotMetaDatedVideoLoad, 3e3), r[t].appendChild(s[t]);
10929                }
10930
10931                function N(e, t) {
10932                    var n = e.ap, o = e.collections.sourceLoadHandlers, s = e.elements, r = s.sources,
10933                        a = s.sourceAnimationWrappers, c = e.props.sources[t], l = c.split("?")[1],
10934                        u = document.createElement("iframe");
10935                    r[t] = u, F(e, t, "".concat(y, " ").concat(i, "youtube-iframe")), u.src = "https://www.youtube.com/embed/".concat(c.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/)[2], "?").concat(l || "").concat(n.i(t) ? "&mute=1&autoplay=1" : "", "&enablejsapi=1"), u.allowFullscreen = true, I(e, t), a[t].appendChild(u), o[t].handleYoutubeLoad();
10936                }
10937
10938                function P(e, t) {
10939                    var n = e.collections.sourceLoadHandlers, o = e.elements, i = o.sources,
10940                        s = o.sourceAnimationWrappers, r = e.props.sources;
10941                    i[t] = r[t], F(e, t, "".concat(i[t].className, " ").concat(y)), s[t].appendChild(i[t]), n[t].handleCustomLoad();
10942                }
10943
10944                function k(e, t) {
10945                    var n = e.elements, o = n.sources, s = n.sourceAnimationWrappers;
10946                    e.props.sources;
10947                    o[t] = document.createElement("div"), o[t].className = "".concat(i, "invalid-file-wrapper ").concat(c), o[t].innerHTML = "Invalid source", s[t].classList.add(m), s[t].removeChild(s[t].firstChild), s[t].appendChild(o[t]);
10948                }
10949
10950                function R(e) {
10951                    var t = e.collections, n = t.sourceLoadHandlers, o = t.sourcesRenderFunctions,
10952                        i = e.core.sourceDisplayFacade, s = e.resolve;
10953                    this.runActionsForSourceTypeAndIndex = function (t, r) {
10954                        var a;
10955                        switch ("invalid" !== t && (n[r] = s(E, [r])), t) {
10956                            case "image":
10957                                a = z;
10958                                break;
10959                            case "video":
10960                                a = T;
10961                                break;
10962                            case "youtube":
10963                                a = N;
10964                                break;
10965                            case "custom":
10966                                a = P;
10967                                break;
10968                            default:
10969                                a = k;
10970                        }
10971                        o[r] = function () {
10972                            return a(e, r)
10973                        }, i.displaySourcesWhichShouldBeDisplayed();
10974                    };
10975                }
10976
10977                function M(e, t, n) {
10978                    var o = e.props, i = o.types, s = o.type, r = o.sources;
10979                    this.getTypeSetByClientForIndex = function (e) {
10980                        var t;
10981                        return i && i[e] ? t = i[e] : s && (t = s), t
10982                    }, this.retrieveTypeWithXhrForIndex = function (e) {
10983                        !function (e, t) {
10984                            var n = document.createElement("a");
10985                            n.href = e;
10986                            var o = n.hostname;
10987                            if ("www.youtube.com" === o || "youtu.be" === o) return t("youtube");
10988                            var i = new XMLHttpRequest;
10989                            i.onreadystatechange = function () {
10990                                if (4 !== i.readyState) {
10991                                    if (2 === i.readyState) {
10992                                        var e, n = i.getResponseHeader("content-type");
10993                                        switch (n.slice(0, n.indexOf("/"))) {
10994                                            case "image":
10995                                                e = "image";
10996                                                break;
10997                                            case "video":
10998                                                e = "video";
10999                                                break;
11000                                            default:
11001                                                e = "invalid";
11002                                        }
11003                                        i.onreadystatechange = null, i.abort(), t(e);
11004                                    }
11005                                } else t("invalid");
11006                            }, i.open("GET", e), i.send();
11007                        }(r[e], (function (o) {
11008                            t.handleReceivedSourceTypeForUrl(o, r[e]), n.runActionsForSourceTypeAndIndex(o, e);
11009                        }));
11010                    };
11011                }
11012
11013                function D(e, t) {
11014                    var n = e.core.stageManager, o = e.elements, i = o.smw, s = o.sourceWrappersContainer, r = e.props,
11015                        l = 0, f = document.createElement("div");
11016
11017                    function p(e) {
11018                        f.style.transform = "translateX(".concat(e + l, "px)"), l = 0;
11019                    }
11020
11021                    function h() {
11022                        return (1 + r.slideDistance) * innerWidth
11023                    }
11024
11025                    f.className = "".concat(d, " ").concat(a, " ").concat(c), f.s = function () {
11026                        f.style.display = "flex";
11027                    }, f.h = function () {
11028                        f.style.display = "none";
11029                    }, f.a = function () {
11030                        f.classList.add(u);
11031                    }, f.d = function () {
11032                        f.classList.remove(u);
11033                    }, f.n = function () {
11034                        f.style.removeProperty("transform");
11035                    }, f.v = function (e) {
11036                        return l = e, f
11037                    }, f.ne = function () {
11038                        p(-h());
11039                    }, f.z = function () {
11040                        p(0);
11041                    }, f.p = function () {
11042                        p(h());
11043                    }, n.i(t) || f.h(), i[t] = f, s.appendChild(f), function (e, t) {
11044                        var n = e.elements, o = n.smw, i = n.sourceAnimationWrappers, s = document.createElement("div"),
11045                            r = document.createElement("div");
11046                        r.className = "fslightboxl";
11047                        for (var a = 0; a < 3; a++) {
11048                            var c = document.createElement("div");
11049                            r.appendChild(c);
11050                        }
11051                        s.appendChild(r), o[t].appendChild(s), i[t] = s;
11052                    }(e, t);
11053                }
11054
11055                function H(e, t, n) {
11056                    var o = document.createElementNS("http://www.w3.org/2000/svg", "svg"), s = "".concat(i, "svg");
11057                    o.setAttributeNS(null, "class", "".concat(s)), o.setAttributeNS(null, "viewBox", t);
11058                    var r = document.createElementNS("http://www.w3.org/2000/svg", "path");
11059                    return r.setAttributeNS(null, "class", "".concat(s, "p")), r.setAttributeNS(null, "d", n), o.appendChild(r), e.appendChild(o), o
11060                }
11061
11062                function W(e, t) {
11063                    var n = document.createElement("button");
11064                    return n.className = "fslightboxb ".concat(i, "toolbar-button ").concat(c), n.title = t, e.appendChild(n), n
11065                }
11066
11067                function O(e, t) {
11068                    var n = document.createElement("div");
11069                    n.className = "".concat(i, "toolbar"), t.appendChild(n), function (e, t) {
11070                        if (!e.hfs) {
11071                            var n = "M4.5 11H3v4h4v-1.5H4.5V11zM3 7h1.5V4.5H7V3H3v4zm10.5 6.5H11V15h4v-4h-1.5v2.5zM11 3v1.5h2.5V7H15V3h-4z",
11072                                o = W(t);
11073                            o.title = "Enter fullscreen";
11074                            var s = H(o, "0 0 18 18", n);
11075                            e.fso = function () {
11076                                e.ifs = 1, o.title = "Exit fullscreen", s.classList.add("".concat(i, "fsx")), s.setAttributeNS(null, "viewBox", "0 0 950 1024"), s.firstChild.setAttributeNS(null, "d", "M682 342h128v84h-212v-212h84v128zM598 810v-212h212v84h-128v128h-84zM342 342v-128h84v212h-212v-84h128zM214 682v-84h212v212h-84v-128h-128z");
11077                            }, e.fsx = function () {
11078                                e.ifs = 0, o.title = "Enter fullscreen", s.classList.remove("".concat(i, "fsx")), s.setAttributeNS(null, "viewBox", "0 0 18 18"), s.firstChild.setAttributeNS(null, "d", n);
11079                            }, o.onclick = e.fs.t;
11080                        }
11081                    }(e, n), function (e, t) {
11082                        var n = W(t, "Close");
11083                        n.onclick = e.core.lightboxCloser.closeLightbox, H(n, "0 0 24 24", "M 4.7070312 3.2929688 L 3.2929688 4.7070312 L 10.585938 12 L 3.2929688 19.292969 L 4.7070312 20.707031 L 12 13.414062 L 19.292969 20.707031 L 20.707031 19.292969 L 13.414062 12 L 20.707031 4.7070312 L 19.292969 3.2929688 L 12 10.585938 L 4.7070312 3.2929688 z");
11084                    }(e, n);
11085                }
11086
11087                function j(e) {
11088                    var t = e.props.sources, n = e.elements.container, o = document.createElement("div");
11089                    o.className = "".concat(i, "nav"), n.appendChild(o), O(e, o), t.length > 1 && function (e, t) {
11090                        var n = e.props.sources, o = (e.stageIndexes, document.createElement("div")),
11091                            i = document.createElement("span"), s = document.createElement("span"),
11092                            r = document.createElement("span");
11093                        o.className = "fslightboxsn", e.sn = function (e) {
11094                            return i.innerHTML = e
11095                        }, s.className = "fslightboxsl", r.innerHTML = n.length, o.appendChild(i), o.appendChild(s), o.appendChild(r), t.appendChild(o);
11096                    }(e, o);
11097                }
11098
11099                function X(e, t, n, o) {
11100                    var i = e.elements.container, s = n.charAt(0).toUpperCase() + n.slice(1),
11101                        r = document.createElement("div");
11102                    r.className = "".concat(p, " ").concat(p, "-").concat(n), r.title = "".concat(s, " slide"), r.onclick = t, function (e, t) {
11103                        var n = document.createElement("button");
11104                        n.className = "fslightboxb ".concat(f, " ").concat(c), H(n, "0 0 20 20", t), e.appendChild(n);
11105                    }(r, o), i.appendChild(r);
11106                }
11107
11108                function q(e) {
11109                    var t = e.core, n = t.lightboxCloser, o = t.slideChangeFacade, i = e.fs;
11110                    this.listener = function (e) {
11111                        switch (e.key) {
11112                            case "Escape":
11113                                n.closeLightbox();
11114                                break;
11115                            case "ArrowLeft":
11116                                o.changeToPrevious();
11117                                break;
11118                            case "ArrowRight":
11119                                o.changeToNext();
11120                                break;
11121                            case "F11":
11122                                e.preventDefault(), i.t();
11123                        }
11124                    };
11125                }
11126
11127                function B(e) {
11128                    var t = e.elements, n = e.sourcePointerProps, o = e.stageIndexes;
11129
11130                    function i(e, o) {
11131                        t.smw[e].v(n.swipedX)[o]();
11132                    }
11133
11134                    this.runActionsForEvent = function (e) {
11135                        var s, a, c;
11136                        t.container.contains(t.slideSwipingHoverer) || t.container.appendChild(t.slideSwipingHoverer), s = t.container, a = r, (c = s.classList).contains(a) || c.add(a), n.swipedX = e.screenX - n.downScreenX;
11137                        var l = o.previous, u = o.next;
11138                        i(o.current, "z"), void 0 !== l && n.swipedX > 0 ? i(l, "ne") : void 0 !== u && n.swipedX < 0 && i(u, "p");
11139                    };
11140                }
11141
11142                function V(e) {
11143                    var t = e.props.sources, n = e.resolve, o = e.sourcePointerProps, i = n(B);
11144                    1 === t.length ? this.listener = function () {
11145                        o.swipedX = 1;
11146                    } : this.listener = function (e) {
11147                        o.isPointering && i.runActionsForEvent(e);
11148                    };
11149                }
11150
11151                function U(e) {
11152                    var t = e.core.slideIndexChanger, n = e.elements.smw, o = e.stageIndexes, i = e.sws;
11153
11154                    function s(e) {
11155                        var t = n[o.current];
11156                        t.a(), t[e]();
11157                    }
11158
11159                    function r(e, t) {
11160                        void 0 !== e && (n[e].s(), n[e][t]());
11161                    }
11162
11163                    this.runPositiveSwipedXActions = function () {
11164                        var e = o.previous;
11165                        if (void 0 === e) s("z"); else {
11166                            s("p");
11167                            var n = o.next;
11168                            t.changeTo(e);
11169                            var a = o.previous;
11170                            i.d(a), i.b(n), s("z"), r(a, "ne");
11171                        }
11172                    }, this.runNegativeSwipedXActions = function () {
11173                        var e = o.next;
11174                        if (void 0 === e) s("z"); else {
11175                            s("ne");
11176                            var n = o.previous;
11177                            t.changeTo(e);
11178                            var a = o.next;
11179                            i.d(a), i.b(n), s("z"), r(a, "p");
11180                        }
11181                    };
11182                }
11183
11184                function _(e, t) {
11185                    e.contains(t) && e.removeChild(t);
11186                }
11187
11188                function Y(e) {
11189                    var t = e.core.lightboxCloser, n = e.elements, o = e.resolve, i = e.sourcePointerProps, s = o(U);
11190                    this.runNoSwipeActions = function () {
11191                        _(n.container, n.slideSwipingHoverer), i.isSourceDownEventTarget || t.closeLightbox(), i.isPointering = false;
11192                    }, this.runActions = function () {
11193                        i.swipedX > 0 ? s.runPositiveSwipedXActions() : s.runNegativeSwipedXActions(), _(n.container, n.slideSwipingHoverer), n.container.classList.remove(r), i.isPointering = false;
11194                    };
11195                }
11196
11197                function J(e) {
11198                    var t = e.resolve, n = e.sourcePointerProps, o = t(Y);
11199                    this.listener = function () {
11200                        n.isPointering && (n.swipedX ? o.runActions() : o.runNoSwipeActions());
11201                    };
11202                }
11203
11204                function G(e) {
11205                    var t = this, n = e.core, o = n.eventsDispatcher, i = n.globalEventsController,
11206                        s = n.scrollbarRecompensor, r = (e.data, e.elements), a = e.fs, c = e.props,
11207                        u = e.sourcePointerProps;
11208                    this.runActions = function () {
11209                        t.i = 1, r.container.classList.add(v), i.removeListeners(), c.exitFullscreenOnClose && e.ifs && a.x(), setTimeout((function () {
11210                            t.i = 0, u.isPointering = false, r.container.classList.remove(v), document.documentElement.classList.remove(l), s.removeRecompense(), document.body.removeChild(r.container), o.dispatch("onClose");
11211                        }), 270);
11212                    };
11213                }
11214
11215                function $(e, t) {
11216                    var n = e.classList;
11217                    n.contains(t) && n.remove(t);
11218                }
11219
11220                function K(e) {
11221                    var t, n, o;
11222                    !function (e) {
11223                        var t = e.ap, n = e.elements.sources, o = e.props, i = o.autoplay, s = o.autoplays;
11224
11225                        function r(e, o) {
11226                            if ("play" != o || t.i(e)) {
11227                                var i = n[e];
11228                                if (i) {
11229                                    var s = i.tagName;
11230                                    if ("VIDEO" == s) i[o](); else if ("IFRAME" == s) {
11231                                        var r = i.contentWindow;
11232                                        r && r.postMessage('{"event":"command","func":"'.concat(o, 'Video","args":""}'), "*");
11233                                    }
11234                                }
11235                            }
11236                        }
11237
11238                        t.i = function (e) {
11239                            return s[e] || i && 0 != s[e]
11240                        }, t.p = function (e) {
11241                            r(e, "play");
11242                        }, t.c = function (e, t) {
11243                            r(e, "pause"), r(t, "play");
11244                        };
11245                    }(e), n = (t = e).core.eventsDispatcher, o = t.props, n.dispatch = function (e) {
11246                        o[e] && o[e]();
11247                    }, function (e) {
11248                        e.data;
11249                        var t = e.fs,
11250                            n = ["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"],
11251                            o = document.documentElement, i = o.requestFullscreen;
11252
11253                        function s(e) {
11254                            for (var t = 0; t < n.length; t++) document[e](n[t], r);
11255                        }
11256
11257                        function r() {
11258                            document.fullscreenElement || document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement ? e.fso() : e.fsx();
11259                        }
11260
11261                        t.i = function () {
11262                            if (i || (i = o.mozRequestFullScreen), i || (i = o.webkitRequestFullscreen), i || (i = o.msRequestFullscreen), !i) return e.hfs = 1, t.o = function () {
11263                            }, t.x = function () {
11264                            }, t.t = function () {
11265                            }, t.l = function () {
11266                            }, void (t.q = function () {
11267                            });
11268                            t.o = function () {
11269                                e.fso();
11270                                var t = document.documentElement;
11271                                t.requestFullscreen ? t.requestFullscreen() : t.mozRequestFullScreen ? t.mozRequestFullScreen() : t.webkitRequestFullscreen ? t.webkitRequestFullscreen() : t.msRequestFullscreen && t.msRequestFullscreen();
11272                            }, t.x = function () {
11273                                e.fsx(), document.exitFullscreen ? document.exitFullscreen() : document.mozCancelFullScreen ? document.mozCancelFullScreen() : document.webkitExitFullscreen ? document.webkitExitFullscreen() : document.msExitFullscreen && document.msExitFullscreen();
11274                            }, t.t = function () {
11275                                e.ifs ? t.x() : t.o();
11276                            }, t.l = function () {
11277                                s("addEventListener");
11278                            }, t.q = function () {
11279                                s("removeEventListener");
11280                            };
11281                        };
11282                    }(e), function (e) {
11283                        var t = e.core, n = t.globalEventsController, o = t.windowResizeActioner, i = e.fs,
11284                            s = e.resolve, r = s(q), a = s(V), c = s(J);
11285                        n.attachListeners = function () {
11286                            document.addEventListener("pointermove", a.listener), document.addEventListener("pointerup", c.listener), addEventListener("resize", o.runActions), document.addEventListener("keydown", r.listener), i.l();
11287                        }, n.removeListeners = function () {
11288                            document.removeEventListener("pointermove", a.listener), document.removeEventListener("pointerup", c.listener), removeEventListener("resize", o.runActions), document.removeEventListener("keydown", r.listener), i.q();
11289                        };
11290                    }(e), function (e) {
11291                        var t = e.core.lightboxCloser, n = (0, e.resolve)(G);
11292                        t.closeLightbox = function () {
11293                            n.isLightboxFadingOut || n.runActions();
11294                        };
11295                    }(e), function (e) {
11296                        var t = e.data, n = e.core.scrollbarRecompensor;
11297
11298                        function o() {
11299                            document.body.offsetHeight >
11299 innerHeight && (document.body.style.marginRight = t.scrollbarWidth + "px");
11300                        }
11301
11302                        n.addRecompense = function () {
11303                            "complete" === document.readyState ? o() : addEventListener("load", (function () {
11304                                o(), n.addRecompense = o;
11305                            }));
11306                        }, n.removeRecompense = function () {
11307                            document.body.style.removeProperty("margin-right");
11308                        };
11309                    }(e), function (e) {
11310                        var t = e.core, n = t.slideChangeFacade, o = t.slideIndexChanger, i = t.stageManager;
11311                        e.props.sources.length > 1 ? (n.changeToPrevious = function () {
11312                            o.jumpTo(i.getPreviousSlideIndex());
11313                        }, n.changeToNext = function () {
11314                            o.jumpTo(i.getNextSlideIndex());
11315                        }) : (n.changeToPrevious = function () {
11316                        }, n.changeToNext = function () {
11317                        });
11318                    }(e), function (e) {
11319                        var t = e.ap, n = (e.componentsServices, e.core), o = n.slideIndexChanger,
11320                            i = n.sourceDisplayFacade, s = n.stageManager, r = e.elements, a = r.smw,
11321                            c = r.sourceAnimationWrappers, l = e.isl, u = e.stageIndexes, d = e.sws;
11322                        o.changeTo = function (n) {
11323                            t.c(u.current, n), u.current = n, s.updateStageIndexes(), e.sn(n + 1), i.displaySourcesWhichShouldBeDisplayed();
11324                        }, o.jumpTo = function (e) {
11325                            var t = u.previous, n = u.current, i = u.next, r = l[n], f = l[e];
11326                            o.changeTo(e);
11327                            for (var p = 0; p < a.length; p++) a[p].d();
11328                            d.d(n), d.c(), requestAnimationFrame((function () {
11329                                requestAnimationFrame((function () {
11330                                    var e = u.previous, o = u.next;
11331
11332                                    function p() {
11333                                        s.i(n) ? n === u.previous ? a[n].ne() : n === u.next && a[n].p() : (a[n].h(), a[n].n());
11334                                    }
11335
11336                                    r && c[n].classList.add(g), f && c[u.current].classList.add(h), d.a(), void 0 !== e && e !== n && a[e].ne(), a[u.current].n(), void 0 !== o && o !== n && a[o].p(), d.b(t), d.b(i), l[n] ? setTimeout(p, 260) : p();
11337                                }));
11338                            }));
11339                        };
11340                    }(e), function (e) {
11341                        var t = e.core.sourcesPointerDown, n = e.elements, o = n.smw, i = n.sources,
11342                            s = e.sourcePointerProps, r = e.stageIndexes;
11343                        t.listener = function (e) {
11344                            "VIDEO" !== e.target.tagName && e.preventDefault(), s.isPointering = true, s.downScreenX = e.screenX, s.swipedX = 0;
11345                            var t = i[r.current];
11346                            t && t.contains(e.target) ? s.isSourceDownEventTarget = true : s.isSourceDownEventTarget = false;
11347                            for (var n = 0; n < o.length; n++) o[n].d();
11348                        };
11349                    }(e), function (e) {
11350                        var t = e.collections.sourcesRenderFunctions, n = e.core.sourceDisplayFacade, o = e.loc,
11351                            i = e.stageIndexes;
11352
11353                        function s(e) {
11354                            t[e] && (t[e](), delete t[e]);
11355                        }
11356
11357                        n.displaySourcesWhichShouldBeDisplayed = function () {
11358                            if (o) s(i.current); else for (var e in i) s(i[e]);
11359                        };
11360                    }(e), function (e) {
11361                        var t = e.core.stageManager, n = e.elements, o = n.smw, i = n.sourceAnimationWrappers,
11362                            s = e.isl, r = e.stageIndexes, a = e.sws;
11363                        a.a = function () {
11364                            for (var e in r) o[r[e]].s();
11365                        }, a.b = function (e) {
11366                            void 0 === e || t.i(e) || (o[e].h(), o[e].n());
11367                        }, a.c = function () {
11368                            for (var e in r) a.d(r[e]);
11369                        }, a.d = function (e) {
11370                            if (s[e]) {
11371                                var t = i[e];
11372                                $(t, m), $(t, h), $(t, g);
11373                            }
11374                        };
11375                    }(e), function (e) {
11376                        var t = e.collections.sourceSizers, n = e.core.windowResizeActioner,
11377                            o = (e.data, e.elements.smw), i = e.props.sourceMargin, s = e.stageIndexes, r = 1 - 2 * i;
11378                        n.runActions = function () {
11379                            innerWidth > 992 ? e.mw = r * innerWidth : e.mw = innerWidth, e.mh = r * innerHeight;
11380                            for (var n = 0; n < o.length; n++) o[n].d(), t[n] && t[n].adjustSize();
11381                            var i = s.previous, a = s.next;
11382                            void 0 !== i && o[i].ne(), void 0 !== a && o[a].p();
11383                        };
11384                    }(e);
11385                }
11386
11387                function Q(e) {
11388                    var t = e.ap, n = (e.componentsServices, e.core), o = n.eventsDispatcher,
11389                        s = n.globalEventsController, r = n.scrollbarRecompensor, c = n.sourceDisplayFacade,
11390                        u = n.stageManager, f = n.windowResizeActioner, p = e.data, h = e.elements,
11391                        g = (e.props, e.stageIndexes), v = e.sws, b = 0;
11392
11393                    function x() {
11394                        var t, n, s = e.props, r = s.autoplay, c = s.autoplays;
11395                        b = true, function (e) {
11396                            var t = e.props, n = t.autoplays;
11397                            e.c = t.sources.length;
11398                            for (var o = 0; o < e.c; o++) "false" === n[o] && (n[o] = 0), "" === n[o] && (n[o] = 1);
11399                            e.loc = t.loadOnlyCurrentSource;
11400                        }(e), p.scrollbarWidth = function () {
11401                            var e = document.createElement("div"), t = e.style, n = document.createElement("div");
11402                            t.visibility = "hidden", t.width = "100px", t.msOverflowStyle = "scrollbar", t.overflow = "scroll", n.style.width = "100%", document.body.appendChild(e);
11403                            var o = e.offsetWidth;
11404                            e.appendChild(n);
11405                            var i = n.offsetWidth;
11406                            return document.body.removeChild(e), o - i
11407                        }(), (r || c.length > 0) && (e.loc = 1), K(e), e.fs.i(), h.container = document.createElement("div"), h.container.className = "".concat(i, "container ").concat(a, " ").concat(m), h.container.setAttribute("tabindex", "0"), function (e) {
11408                            var t = e.elements;
11409                            t.slideSwipingHoverer = document.createElement("div"), t.slideSwipingHoverer.className = "".concat(i, "slide-swiping-hoverer ").concat(a, " ").concat(d);
11410                        }(e), j(e), function (e) {
11411                            var t = e.core.sourcesPointerDown, n = e.elements, o = e.props.sources,
11412                                i = document.createElement("div");
11413                            i.className = "".concat(d, " ").concat(a), n.container.appendChild(i), i.addEventListener("pointerdown", t.listener), n.sourceWrappersContainer = i;
11414                            for (var s = 0; s < o.length; s++) D(e, s);
11415                        }(e), e.props.sources.length > 1 && (n = (t = e).core.slideChangeFacade, X(t, n.changeToPrevious, "previous", "M18.271,9.212H3.615l4.184-4.184c0.306-0.306,0.306-0.801,0-1.107c-0.306-0.306-0.801-0.306-1.107,0L1.21,9.403C1.194,9.417,1.174,9.421,1.158,9.437c-0.181,0.181-0.242,0.425-0.209,0.66c0.005,0.038,0.012,0.071,0.022,0.109c0.028,0.098,0.075,0.188,0.142,0.271c0.021,0.026,0.021,0.061,0.045,0.085c0.015,0.016,0.034,0.02,0.05,0.033l5.484,5.483c0.306,0.307,0.801,0.307,1.107,0c0.306-0.305,0.306-0.801,0-1.105l-4.184
11415-4.185h14.656c0.436,0,0.788-0.353,0.788-0.788S18.707,9.212,18.271,9.212z"), X(t, n.changeToNext, "next", "M1.729,9.212h14.656l-4.184-4.184c-0.307-0.306-0.307-0.801,0-1.107c0.305-0.306,0.801-0.306,1.106,0l5.481,5.482c0.018,0.014,0.037,0.019,0.053,0.034c0.181,0.181,0.242,0.425,0.209,0.66c-0.004,0.038-0.012,0.071-0.021,0.109c-0.028,0.098-0.075,0.188-0.143,0.271c-0.021,0.026-0.021,0.061-0.045,0.085c-0.015,0.016-0.034,0.02-0.051,0.033l-5.483,5.483c-0.306,0.307-0.802,0.307-1.106,0c-0.307-0.305-0.307-0.801,0-1.105l4.184-4.185H1.729c-0.436,0-0.788-0.353-0.788-0.788S1.293,9.212,1.729,9.212z")), function (e) {
11416                            for (var t = e.props.sources, n = e.resolve, o = n(L), i = n(R), s = n(M, [o, i]), r = 0; r < t.length; r++) if ("string" == typeof t[r]) {
11417                                var a = s.getTypeSetByClientForIndex(r);
11418                                if (a) i.runActionsForSourceTypeAndIndex(a, r); else {
11419                                    var c = o.getSourceTypeFromLocalStorageByUrl(t[r]);
11420                                    c ? i.runActionsForSourceTypeAndIndex(c, r) : s.retrieveTypeWithXhrForIndex(r);
11421                                }
11422                            } else i.runActionsForSourceTypeAndIndex("custom", r);
11423                        }(e), o.dispatch("onInit");
11424                    }
11425
11426                    e.open = function () {
11427                        var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 0, i = g.previous,
11428                            a = g.current, d = g.next;
11429                        g.current = n, b || S(e), u.updateStageIndexes(), b ? (v.c(), v.a(), v.b(i), v.b(a), v.b(d), o.dispatch("onShow")) : x(), c.displaySourcesWhichShouldBeDisplayed(), e.sn(n + 1), document.body.appendChild(h.container), h.container.focus(), document.documentElement.classList.add(l), r.addRecompense(), s.attachListeners(), f.runActions(), h.smw[n].n(), t.p(n), o.dispatch("onOpen");
11430                    };
11431                }
11432
11433                function Z(e, t, n) {
11434                    return (Z = ee() ? Reflect.construct.bind() : function (e, t, n) {
11435                        var o = [null];
11436                        o.push.apply(o, t);
11437                        var i = new (Function.bind.apply(e, o));
11438                        return n && te(i, n.prototype), i
11439                    }).apply(null, arguments)
11440                }
11441
11442                function ee() {
11443                    if ("undefined" == typeof Reflect || !Reflect.construct) return false;
11444                    if (Reflect.construct.sham) return false;
11445                    if ("function" == typeof Proxy) return true;
11446                    try {
11447                        return Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], (function () {
11448                        }))), !0
11449                    } catch (e) {
11450                        return false
11451                    }
11452                }
11453
11454                function te(e, t) {
11455                    return (te = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (e, t) {
11456                        return e.__proto__ = t, e
11457                    })(e, t)
11458                }
11459
11460                function ne(e) {
11461                    return function (e) {
11462                        if (Array.isArray(e)) return oe(e)
11463                    }(e) || function (e) {
11464                        if ("undefined" != typeof Symbol && null != e[Symbol.iterator] || null != e["@@iterator"]) return Array.from(e)
11465                    }(e) || function (e, t) {
11466                        if (!e) return;
11467                        if ("string" == typeof e) return oe(e, t);
11468                        var n = Object.prototype.toString.call(e).slice(8, -1);
11469                        "Object" === n && e.constructor && (n = e.constructor.name);
11470                        if ("Map" === n || "Set" === n) return Array.from(e);
11471                        if ("Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return oe(e, t)
11472                    }(e) || function () {
11473                        throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
11474                    }()
11475                }
11476
11477                function oe(e, t) {
11478                    (null == t || t > e.length) && (t = e.length);
11479                    for (var n = 0, o = new Array(t); n < t; n++) o[n] = e[n];
11480                    return o
11481                }
11482
11483                function ie() {
11484                    for (var e = document.getElementsByTagName("a"), t = function (t) {
11485                        if (!e[t].hasAttribute("data-fslightbox")) return "continue";
11486                        var n = e[t].hasAttribute("data-href") ? e[t].getAttribute("data-href") : e[t].getAttribute("href");
11487                        if (!n) return console.warn('The "data-fslightbox" attribute was set without the "href" attribute.'), "continue";
11488                        var o = e[t].getAttribute("data-fslightbox");
11489                        fsLightboxInstances[o] || (fsLightboxInstances[o] = new FsLightbox);
11490                        var i = null;
11491                        "#" === n.charAt(0) ? (i = document.getElementById(n.substring(1)).cloneNode(true)).removeAttribute("id") : i = n, fsLightboxInstances[o].props.sources.push(i), fsLightboxInstances[o].elements.a.push(e[t]);
11492                        var s = fsLightboxInstances[o].props.sources.length - 1;
11493                        e[t].onclick = function (e) {
11494                            e.preventDefault(), fsLightboxInstances[o].open(s);
11495                        }, d("types", "data-type"), d("videosPosters", "data-video-poster"), d("customClasses", "data-class"), d("customClasses", "data-custom-class"), d("autoplays", "data-autoplay");
11496                        for (var r = ["href", "data-fslightbox", "data-href", "data-type", "data-video-poster", "data-class", "data-custom-class", "data-autoplay"], a = e[t].attributes, c = fsLightboxInstances[o].props.customAttributes, l = 0; l < a.length; l++) if (-1 === r.indexOf(a[l].name) && "data-" === a[l].name.substr(0, 5)) {
11497                            c[s] || (c[s] = {});
11498                            var u = a[l].name.substr(5);
11499                            c[s][u] = a[l].value;
11500                        }
11501
11502                        function d(n, i) {
11503                            e[t].hasAttribute(i) && (fsLightboxInstances[o].props[n][s] = e[t].getAttribute(i));
11504                        }
11505                    }, n = 0; n < e.length; n++) t(n);
11506                    var o = Object.keys(fsLightboxInstances);
11507                    window.fsLightbox = fsLightboxInstances[o[o.length - 1]];
11508                }
11509
11510                window.FsLightbox = function () {
11511                    var e = this;
11512                    this.props = {
11513                        sources: [],
11514                        customAttributes: [],
11515                        customClasses: [],
11516                        autoplays: [],
11517                        types: [],
11518                        videosPosters: [],
11519                        exitFullscreenOnClose: 1,
11520                        sourceMargin: .05,
11521                        slideDistance: .3
11522                    }, this.data = {
11523                        isFullscreenOpen: false,
11524                        scrollbarWidth: 0
11525                    }, this.isl = [], this.sourcePointerProps = {
11526                        downScreenX: null,
11527                        isPointering: false,
11528                        isSourceDownEventTarget: false,
11529                        swipedX: 0
11530                    }, this.stageIndexes = {}, this.elements = {
11531                        a: [],
11532                        container: null,
11533                        slideSwipingHoverer: null,
11534                        smw: [],
11535                        sourceWrappersContainer: null,
11536                        sources: [],
11537                        sourceAnimationWrappers: []
11538                    }, this.sn = function () {
11539                    }, this.resolve = function (t) {
11540                        var n = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : [];
11541                        return n.unshift(e), Z(t, ne(n))
11542                    }, this.collections = {
11543                        sourceLoadHandlers: [],
11544                        sourcesRenderFunctions: [],
11545                        sourceSizers: []
11546                    }, this.core = {
11547                        eventsDispatcher: {},
11548                        globalEventsController: {},
11549                        lightboxCloser: {},
11550                        lightboxUpdater: {},
11551                        scrollbarRecompensor: {},
11552                        slideChangeFacade: {},
11553                        slideIndexChanger: {},
11554                        sourcesPointerDown: {},
11555                        sourceDisplayFacade: {},
11556                        stageManager: {},
11557                        windowResizeActioner: {}
11558                    }, this.ap = {}, this.fs = {}, this.sws = {}, Q(this), this.close = function () {
11559                        return e.core.lightboxCloser.closeLightbox()
11560                    };
11561                }, window.fsLightboxInstances = {}, ie(), window.refreshFsLightbox = function () {
11562                    for (var e in fsLightboxInstances) {
11563                        var t = fsLightboxInstances[e].props;
11564                        fsLightboxInstances[e] = new FsLightbox, fsLightboxInstances[e].props = t, fsLightboxInstances[e].props.sources = [], fsLightboxInstances[e].elements.a = [];
11565                    }
11566                    ie();
11567                };
11568            }])
11569        }));
11570    }(fslightbox));
11571    return fslightbox.exports;
11572}
11573
11574requireFslightbox();
11575
11576const img = document.querySelector(".gallery__photo-link");
11577const video = document.querySelector(".gallery__video-link");
11578
11579$(".gallery-item").on("click", (event) => {
11580    const current = $(event.currentTarget);
11581    const src = current.find("img, video").attr("src");
11582
11583    const imgJQ = $(img);
11584    const videoJQ = $(video);
11585
11586    const videoTag = video.querySelector("img");
11587    const imgTag = img.querySelector("img");
11588
11589    if (current.hasClass("gallery-item_video")) {
11590        videoJQ.show();
11591        imgJQ.hide();
11592        videoJQ.attr("href", current.attr("data-video-href"));
11593        videoTag.src = current.attr("data-href");
11594        // videoTag.play();
11595    } else {
11596        videoJQ.hide();
11597        imgJQ.show();
11598        imgJQ.attr("href", src);
11599        imgTag.src = src;
11600        // videoTag.currentTime = 0;
11601        // videoTag.pause();
11602    }
11603
11604    $(".gallery-item").removeClass("active");
11605    current.addClass("active");
11606
11607    refreshFsLightbox();
11608});
11609
11610$(() => {
11611
11612    $(".calendar__date-btn").on("click", (e) => {
11613        const current = $(e.currentTarget);
11614        current.addClass("active");
11615        $(".calendar__date-btn").not(current).removeClass("active");
11616
11617        const swiperEl = current.closest(".swiper")[0];
11618        const swiper = swiperEl && swiperEl.swiper ? swiperEl.swiper : null;
11619        const slideEl = current.closest(".swiper-slide")[0];
11620        const slideIndex = slideEl ? Number(slideEl.getAttribute("data-swiper-slide-index")) : NaN;
11621
11622        if (swiper && typeof swiper.slideTo === "function" && Number.isInteger(slideIndex)) {
11623            swiper.slideTo(slideIndex);
11624            if (swiper.navigation && typeof swiper.navigation.update === "function") {
11625                swiper.navigation.update();
11626            }
11627        }
11628    });
11629
11630});
11631
11632$(() => {
11633    function disableForm(form) {
11634        form.find("button").prop("disabled", true);
11635        form.addClass("invalid");
11636    }
11637
11638    function enableForm(form) {
11639        form.find("button").prop("disabled", false);
11640        form.removeClass("invalid");
11641    }
11642
11643    function validate(form) {
11644        if (form.querySelector(".input_error")) {
11645            disableForm($(form));
11646            $(form).find(".form__message").text("Некоторые поля заполнены неверно");
11647            $(form).find(".form__message").addClass("form__message_warning");
11648            showMessage($(form).find(".form__message"));
11649        } else {
11650            enableForm($(form));
11651        }
11652    }
11653
11654    function validateInput(input) {
11655        if (input.matches("input:valid")) {
11656            input.classList.remove("input_error");
11657
11658            if ($(input).attr("type") === "file") {
11659                $(input).closest(".file").find("label").removeClass("input_error");
11660            }
11661        } else {
11662            input.classList.add("input_error");
11663
11664            if ($(input).attr("type") === "file") {
11665                $(input).closest(".file").find("label").addClass("input_error");
11666            }
11667        }
11668        validate(input.closest("form"));
11669    }
11670
11671    function showMessage(message) {
11672        message.slideDown(300);
11673
11674        setTimeout(() => {
11675            message.slideUp(300);
11676        }, 5000);
11677    }
11678
11679    $("form").on("submit", (event) => {
11680        const form = event.currentTarget;
11681
11682        if (form.id === "donation-form") {
11683            return;
11684        }
11685
11686        if (!form.classList.contains("invalid")) {
11687            const formData = new FormData(form);
11688
11689            fetch(form.getAttribute("action"), {
11690                method: "POST",
11691                body: formData,
11692            }).then(() => {
11693                $(form).find(".form__message").text("Данные успешно отправлены. Мы скоро свяжемся с вами!");
11694                $(form).find(".input").val("");
11695                $(form).find(".form__message").removeClass("form__message_error");
11696                $(form).find(".form__message").removeClass("form__message_warning");
11697                showMessage($(form).find(".form__message"));
11698            }).catch(() => {
11699                $(form).find(".form__message").text("При отправке данных произошла ошибка. Попробуйте позже.");
11700                $(form).find(".form__message").addClass("form__message_error");
11701                showMessage($(form).find(".form__message"));
11702            });
11703
11704            event.preventDefault();
11705        }
11706    });
11707
11708    $("form button[type='submit']").on("click", (e) => {
11709        const form = e.currentTarget.closest("form");
11710
11711        if (form && form.id === "donation-form") {
11712            return;
11713        }
11714
11715        form.querySelectorAll("input").forEach((input) => {
11716            validateInput(input);
11717        });
11718    });
11719
11720    $("input").on("change", (event) => {
11721        const input = event.currentTarget;
11722
11723        if (input.closest("#donation-form")) {
11724            return;
11725        }
11726
11727        validateInput(input);
11728    });
11729});
11730
11731$(() => {
11732    // $(".menu").on("click", (e) => {
11733    //     const current = $(e.currentTarget);
11734
11735    //     if ($(".menu.active").length > 0 && !current.hasClass("active")) {
11736    //         $(".drop-down, .mobile-menu__deep-list").not(current).slide
11736Up(300);
11737    //         $(".drop-down, .mobile-menu__deep-list").not(current).prev().removeClass("active");
11738    //     }
11739
11740    //     current.toggleClass("active");
11741    //     current.next().slideToggle(300);
11742
11743    //     e.preventDefault();
11744    // });
11745
11746
11747    // $(document).on("click", (e) => {
11748    //     if (!e.target.closest(".drop-down, .menu")) {
11749    //         $(".drop-down, .mobile-menu__deep-list").slideUp(300);
11750    //         $(".drop-down, .mobile-menu__deep-list").prev().removeClass("active");
11751    //     }
11752    // });
11753
11754    // $(".header__mobile-btn").on("click", (e) => {
11755    //     $(".mobile-menu").slideToggle(300);
11756    //     $(e.currentTarget).toggleClass("active");
11757    //     $(".mobile-menu-bg").toggleClass("active");
11758    // });
11759
11760    $(document).on("click", ".back-link, .brother-page__back-link, .people-detail__back, .akathist__back, .icon-page__back, .media-detail__back-link", (e) => {
11761        const current = e.currentTarget;
11762        const href = current.getAttribute("href");
11763
11764        if (!href) return;
11765
11766        e.preventDefault();
11767
11768        if (window.history.length > 1) {
11769            window.history.back();
11770            return;
11771        }
11772
11773        window.location.href = href;
11774    });
11775
11776    const initMobileBreadcrumbBackLink = () => {
11777        const detailPrefixes = [
11778            "/podvorya_monastyrya/",
11779            "/svyatyni_monastyrya/",
11780            "/naselniki/",
11781            "/blagotvoriteli/",
11782            "/hramy_monastyrya/",
11783            "/icon/",
11784            "/obshchestvennoe_sluzhenie/",
11785            "/arhitekturnyy_kompleks/",
11786            "/pravedniki/",
11787            "/nekropol/",
11788            "/recipes/",
11789            "/danilovskie_masterskie/"
11790        ];
11791        const path = window.location.pathname;
11792        const segments = path.split("/").filter(Boolean);
11793        const isNewsDetail = path.startsWith("/news/") && !!document.querySelector(".media-detail");
11794
11795        if (segments.length < 2 || !isNewsDetail && !detailPrefixes.some((prefix) => path.startsWith(prefix))) {
11796            return;
11797        }
11798
11799        const breadcrumbs = document.querySelector(".breadcrumbs");
11800        if (!breadcrumbs) {
11801            return;
11802        }
11803
11804        const breadcrumbLinks = breadcrumbs.querySelectorAll("a");
11805        const listLink = breadcrumbLinks[breadcrumbLinks.length - 1];
11806        if (!listLink) {
11807            return;
11808        }
11809
11810        let backLink = isNewsDetail ? document.querySelector(".back-link:not([data-mobile-breadcrumb-back])") : null;
11811
11812        if (backLink) {
11813            backLink.setAttribute("href", listLink.getAttribute("href") || "/");
11814        } else {
11815            backLink = document.querySelector("[data-mobile-breadcrumb-back]");
11816        }
11817
11818        if (!backLink) {
11819            backLink = document.createElement("a");
11820            backLink.className = "back-link";
11821            backLink.setAttribute("data-mobile-breadcrumb-back", "true");
11822            backLink.setAttribute("href", listLink.getAttribute("href") || "/");
11823            backLink.innerHTML = `
11824                <svg width="16" height="8" viewBox="0 0 16 8" fill="none" xmlns="http://www.w3.org/2000/svg">
11825                    <path d="M0.146447 3.32842C-0.0488155 3.52369 -0.0488155 3.84027 0.146447 4.03553L3.32843 7.21751C3.52369 7.41277 3.84027 7.41277 4.03553 7.21751C4.2308 7.02225 4.2308 6.70567 4.03553 6.5104L1.20711 3.68198L4.03553 0.853549C4.2308 0.658287 4.2308 0.341705 4.03553 0.146442C3.84027 -0.0488197 3.52369 -0.0488197 3.32843 0.146442L0.146447 3.32842ZM15.5 3.68198V3.18198L0.5 3.18198V3.68198V4.18198L15.5 4.18198V3.68198Z" fill="#808080"/>
11826                </svg>
11827                ${listLink.textContent.trim()}
11828            `;
11829            breadcrumbs.insertAdjacentElement("afterend", backLink);
11830        }
11831
11832        const toggleMobileBackLink = () => {
11833            const isMobile = window.innerWidth <= 998;
11834
11835            breadcrumbs.style.display = isMobile ? "none" : "";
11836            backLink.style.display = isMobile ? "flex" : "none";
11837            backLink.style.paddingTop = isMobile ? "27px" : "";
11838        };
11839
11840        toggleMobileBackLink();
11841        window.addEventListener("resize", toggleMobileBackLink);
11842    };
11843
11844    initMobileBreadcrumbBackLink();
11845
11846    let isRestoringBodyScroll = false;
11847
11848    const lockBodyScroll = () => {
11849        const scrollY = window.scrollY || window.pageYOffset || 0;
11850
11851        document.documentElement.classList.add("no-scroll");
11852        document.body.classList.add("no-scroll");
11853        document.body.dataset.scrollY = String(scrollY);
11854        document.body.style.top = `-${scrollY}px`;
11855    };
11856
11857    const unlockBodyScroll = () => {
11858        const scrollY = Math.abs(parseInt(document.body.style.top || document.body.dataset.scrollY || "0", 10)) || 0;
11859        const html = document.documentElement;
11860        const previousScrollBehavior = html.style.scrollBehavior;
11861
11862        isRestoringBodyScroll = true;
11863        html.style.scrollBehavior = "auto";
11864        document.documentElement.classList.remove("no-scroll");
11865        document.body.classList.remove("no-scroll");
11866        document.body.style.top = "";
11867        delete document.body.dataset.scrollY;
11868
11869        window.scrollTo(0, scrollY);
11870
11871        window.setTimeout(() => {
11872            prevTop = $(window).scrollTop();
11873            isRestoringBodyScroll = false;
11874            html.style.scrollBehavior = previousScrollBehavior;
11875        }, 350);
11876    };
11877
11878    $(".header__menu-btn").on("click", (e) => {
11879        const headerHeight = $(".header").outerHeight() || 0;
11880        const menuSelector = $("html").width() <= 768 ? ".mobile-menu" : ".menu";
11881        const isOpening = !$("body").hasClass("no-scroll");
11882
11883        $(menuSelector).css({
11884            "top": `${headerHeight}px`,
11885            "bottom": "0",
11886        });
11887
11888        if ($("html").width() <= 768) {
11889            $(".mobile-menu").slideToggle(300);
11890        } else {
11891            $(".menu").slideToggle(300);
11892        }
11893
11894        $(e.currentTarget).toggleClass("active");
11895        if (isOpening) {
11896            lockBodyScroll();
11897        } else {
11898            unlockBodyScroll();
11899        }
11900    });
11901
11902    $(".header__item_drop-down").on("click", (e) => {
11903        if ($(e.target).closest(".drop-down-wrap").length) {
11904            return;
11905        }
11906
11907        const current = $(e.currentTarget);
11908        const dropDown = current.children(".drop-down-wrap");
11909
11910        dropDown.stop(true, true).slideToggle(300);
11911        current.toggleClass("active");
11912
11913        $(".header__item_drop-down").not(current).removeClass("active");
11914        $(".header__item_drop-down").not(current).children(".drop-down-wrap").stop(true, true).slideUp(300);
11915
11916        e.preventDefault();
11917        e.stopPropagation();
11918    });
11919
11920    $(".mobile-menu__link").on("click", (e) => {
11921        const currentData = $(e.currentTarget).attr("data-section");
11922        const mobileMenu = $(e.currentTarget).closest(".mobile-menu");
11923
11924        mobileMenu.addClass("mobile-menu_section-open");
11925        $(".mobile-menu__section").not(`[data-section=${currentData}]`).hide();
11926        $(`.mobile-menu__section[data-section=${currentData}]`).slideDown(300);
11927    });
11928
11929    $(".mobile-menu__section-title").on("click", (e) => {
11930        $(e.currentTarget).closest(".mobile-menu").removeClass("mobile-menu_section-open");
11931        $(".mobile-menu__section").slideUp(300);
11932    });
11933
11934    $(".header .search").on("click", () => {
11935        $(".search-block").slideDown(300, function() {
11936            $(this).find(".search-block__input").trigger("focus");
11937        });
11938        lockBodyScroll();
11939    });
11940
11941    $(".search-block__skip").on("click", () => {
11942        $(".search-block").slideUp(300);
11943        unlockBodyScroll();
11944    });
11945
11946    const closeDropDowns = (except) => {
11947        $(".drop-down-wrap").each((_, element) => {
11948            if (except && element === except) {
11949                return;
11950            }
11951            $(element).stop(true, true).slideUp(300);
11952        });
11953    };
11954
11955    $(".drop-down-btn:not(.calendar-filters__sort-btn)").on("click", (e) => {
11956        const dropDown = $(e.currentTarget).next();
11957
11958        closeDropDowns(dropDown.get(0));
11959
11960        dropDown.stop(true, true).slideToggle(300);
11961        e.preventDefault();
11962        e.stopPropagation();
11963
11964        if (+dropDown.width() + +dropDown.offset().left > +$("html").width()) {
11965            dropDown.css({
11966                "left": "auto",
11967                "right": "0",
11968            });
11969        }
11970    });
11971
11972    $(document).on("click", (e) => {
11973        if ($(e.target).closest(".header__list li").length) {
11974            return;
11975        }
11976
11977        $(".header__item_drop-down").removeClass("active");
11978        $(".header__item_drop-down").children(".drop-down-wrap").stop(true, true).slide
11978Up(300);
11979
11980        if ($(e.target).closest(".nav-list__sort-wrap, .block-header__sort-item").length) {
11981            return;
11982        }
11983
11984        closeDropDowns();
11985    });
11986
11987    $(".main").css("margin-top", document.querySelector(".header").offsetHeight + "px");
11988    $(".menu").css({
11989        "top": document.querySelector(".header").offsetHeight + "px",
11990        "bottom": "0",
11991    });
11992    $(".mobile-menu").css({
11993        "top": document.querySelector(".header").offsetHeight + "px",
11994        "bottom": "0",
11995    });
11996
11997    let prevTop = $(window).scrollTop() <= 200 ? 200 : $(window).scrollTop();
11998    $(".main_people").css("background-position", `0 ${$(".header").height()}px`);
11999
12000    const $header = $(".header");
12001
12002    $(window).on("scroll", () => {
12003        if (isRestoringBodyScroll || $("body").hasClass("no-scroll")) {
12004            return;
12005        }
12006
12007        const scrollTop = $(window).scrollTop();
12008        const headerHeight = $header.outerHeight();
12009
12010        // если ещё не прокрутили высоту шапки
12011        if (scrollTop <= headerHeight) {
12012            $header.removeClass("scroll-up").stop(true, true).slideDown(300);
12013            $(".main_people").css("background-position", `0 ${headerHeight}px`);
12014            prevTop = headerHeight;
12015            return;
12016        }
12017
12018        if (scrollTop >= prevTop) {
12019            $header.slideUp(300);
12020            $(".main_people").css("background-position", "0 0");
12021            $header.removeClass("scroll-up");
12022            $header.addClass("scroll-down");
12023        } else {
12024            $header.slideDown(300);
12025            $(".main_people").css("background-position", `0 ${headerHeight}px`);
12026            $header.addClass("scroll-up");
12027            $header.removeClass("scroll-down");
12028        }
12029
12030        prevTop = scrollTop;
12031    });
12032});
12033
12034$(() => {
12035    const phoneInputs = document.querySelectorAll(".input.tel");
12036    const getInputNumberValue = function (input) {
12037        return input.value.replace(/\D+/g, "");
12038    };
12039
12040    const onPhoneInput = function (e) {
12041        const input = e.target;
12042        let inputValue = getInputNumberValue(input);
12043        let formattedInputValue = "";
12044
12045        if (!inputValue) {
12046            return (input.value = "");
12047        }
12048
12049        if (["7", "8", "9"].indexOf(inputValue[0]) > -1) {
12050            if (inputValue[0] == "9") {
12051                inputValue = `7${inputValue}`;
12052            }
12053            const firstSymbols = inputValue[0] == "8" || inputValue[0] == "+" ? "+7" : "+7";
12054            formattedInputValue = firstSymbols;
12055            if (inputValue.length > 1) {
12056                formattedInputValue += ` (${inputValue.substring(1, 4)}`;
12057            }
12058            if (inputValue.length >= 5) {
12059                formattedInputValue += `) ${inputValue.substring(4, 7)}`;
12060            }
12061            if (inputValue.length >= 8) {
12062                formattedInputValue += `-${inputValue.substring(7, 9)}`;
12063            }
12064            if (inputValue.length >= 10) {
12065                formattedInputValue += `-${inputValue.substring(9, 11)}`;
12066            }
12067        } else {
12068            formattedInputValue = `+${inputValue.substring(0, 16)}`;
12069        }
12070        input.value = formattedInputValue;
12071    };
12072
12073    phoneInputs?.forEach((input) => {
12074        input.addEventListener("input", onPhoneInput);
12075    });
12076});
12077
12078// $(() => {
12079//     $("[data-link]").on("click", (e) => {
12080//         const link = $(e.currentTarget).attr("data-link");
12081//         window.location.href = link;
12082//     });
12083// });
12084
12085$(() => {
12086
12087    $(".search-block__input").on("input", (e) => {
12088        const current = $(e.currentTarget);
12089
12090        if ($(".search-block").hasClass("error")) {
12091            $(".search-block__example").hide();
12092            $(".search-block__items-wrap").hide();
12093            $(".search-block__error").slideDown(300);
12094        } else {
12095            if (!!current.val()) {
12096                $(".search-block__example").hide();
12097                $(".search-block__items-wrap").slideDown(300);
12098            } else {
12099                $(".search-block__example").slideDown(300);
12100                $(".search-block__items-wrap").hide();
12101            }
12102        }
12103
12104    });
12105
12106});
12107
12108/**
12109 * SSR Window 5.0.1
12110 * Better handling for window object in SSR environment
12111 * https://github.com/nolimits4web/ssr-window
12112 *
12113 * Copyright 2025, Vladimir Kharlampidi
12114 *
12115 * Licensed under MIT
12116 *
12117 * Released on: June 27, 2025
12118 */
12119
12120/* eslint-disable no-param-reassign */
12121function isObject$1(obj) {
12122    return obj !== null && typeof obj === 'object' && 'constructor' in obj && obj.constructor === Object;
12123}
12124
vendor: 11,404 bytes, lines 12125-12518
12125function extend$1(target, src) {
12126    if (target === void 0) {
12127        target = {};
12128    }
12129    if (src === void 0) {
12130        src = {};
12131    }
12132    const noExtend = ['__proto__', 'constructor', 'prototype'];
12133    Object.keys(src).filter(key => noExtend.indexOf(key) < 0).forEach(key => {
12134        if (typeof target[key] === 'undefined') target[key] = src[key]; else if (isObject$1(src[key]) && isObject$1(target[key]) && Object.keys(src[key]).length > 0) {
12135            extend$1(target[key], src[key]);
12136        }
12137    });
12138}
12139
12140const ssrDocument = {
12141    body: {},
12142    addEventListener() {
12143    },
12144    removeEventListener() {
12145    },
12146    activeElement: {
12147        blur() {
12148        },
12149        nodeName: ''
12150    },
12151    querySelector() {
12152        return null;
12153    },
12154    querySelectorAll() {
12155        return [];
12156    },
12157    getElementById() {
12158        return null;
12159    },
12160    createEvent() {
12161        return {
12162            initEvent() {
12163            }
12164        };
12165    },
12166    createElement() {
12167        return {
12168            children: [],
12169            childNodes: [],
12170            style: {},
12171            setAttribute() {
12172            },
12173            getElementsByTagName() {
12174                return [];
12175            }
12176        };
12177    },
12178    createElementNS() {
12179        return {};
12180    },
12181    importNode() {
12182        return null;
12183    },
12184    location: {
12185        hash: '',
12186        host: '',
12187        hostname: '',
12188        href: '',
12189        origin: '',
12190        pathname: '',
12191        protocol: '',
12192        search: ''
12193    }
12194};
12195
12196function getDocument() {
12197    const doc = typeof document !== 'undefined' ? document : {};
12198    extend$1(doc, ssrDocument);
12199    return doc;
12200}
12201
12202const ssrWindow = {
12203    document: ssrDocument,
12204    navigator: {
12205        userAgent: ''
12206    },
12207    location: {
12208        hash: '',
12209        host: '',
12210        hostname: '',
12211        href: '',
12212        origin: '',
12213        pathname: '',
12214        protocol: '',
12215        search: ''
12216    },
12217    history: {
12218        replaceState() {
12219        },
12220        pushState() {
12221        },
12222        go() {
12223        },
12224        back() {
12225        }
12226    },
12227    CustomEvent: function CustomEvent() {
12228        return this;
12229    },
12230    addEventListener() {
12231    },
12232    removeEventListener() {
12233    },
12234    getComputedStyle() {
12235        return {
12236            getPropertyValue() {
12237                return '';
12238            }
12239        };
12240    },
12241    Image() {
12242    },
12243    Date() {
12244    },
12245    screen: {},
12246    setTimeout() {
12247    },
12248    clearTimeout() {
12249    },
12250    matchMedia() {
12251        return {};
12252    },
12253    requestAnimationFrame(callback) {
12254        if (typeof setTimeout === 'undefined') {
12255            callback();
12256            return null;
12257        }
12258        return setTimeout(callback, 0);
12259    },
12260    cancelAnimationFrame(id) {
12261        if (typeof setTimeout === 'undefined') {
12262            return;
12263        }
12264        clearTimeout(id);
12265    }
12266};
12267
12268function getWindow() {
12269    const win = typeof window !== 'undefined' ? window : {};
12270    extend$1(win, ssrWindow);
12271    return win;
12272}
12273
12274function classesToTokens(classes) {
12275    if (classes === void 0) {
12276        classes = '';
12277    }
12278    return classes.trim().split(' ').filter(c => !!c.trim());
12279}
12280
12281function deleteProps(obj) {
12282    const object = obj;
12283    Object.keys(object).forEach(key => {
12284        try {
12285            object[key] = null;
12286        } catch (e) {
12287            // no getter for object
12288        }
12289        try {
12290            delete object[key];
12291        } catch (e) {
12292            // something got wrong
12293        }
12294    });
12295}
12296
12297function nextTick(callback, delay) {
12298    if (delay === void 0) {
12299        delay = 0;
12300    }
12301    return setTimeout(callback, delay);
12302}
12303
12304function now() {
12305    return Date.now();
12306}
12307
12308function getComputedStyle$1(el) {
12309    const window = getWindow();
12310    let style;
12311    if (window.getComputedStyle) {
12312        style = window.getComputedStyle(el, null);
12313    }
12314    if (!style && el.currentStyle) {
12315        style = el.currentStyle;
12316    }
12317    if (!style) {
12318        style = el.style;
12319    }
12320    return style;
12321}
12322
12323function getTranslate(el, axis) {
12324    if (axis === void 0) {
12325        axis = 'x';
12326    }
12327    const window = getWindow();
12328    let matrix;
12329    let curTransform;
12330    let transformMatrix;
12331    const curStyle = getComputedStyle$1(el);
12332    if (window.WebKitCSSMatrix) {
12333        curTransform = curStyle.transform || curStyle.webkitTransform;
12334        if (curTransform.split(',').length > 6) {
12335            curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', ');
12336        }
12337        // Some old versions of Webkit choke when 'none' is passed; pass
12338        // empty string instead in this case
12339        transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
12340    } else {
12341        transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
12342        matrix = transformMatrix.toString().split(',');
12343    }
12344    if (axis === 'x') {
12345        // Latest Chrome and webkits Fix
12346        if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41;
12347        // Crazy IE10 Matrix
12348        else if (matrix.length === 16) curTransform = parseFloat(matrix[12]);
12349        // Normal Browsers
12350        else curTransform = parseFloat(matrix[4]);
12351    }
12352    if (axis === 'y') {
12353        // Latest Chrome and webkits Fix
12354        if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42;
12355        // Crazy IE10 Matrix
12356        else if (matrix.length === 16) curTransform = parseFloat(matrix[13]);
12357        // Normal Browsers
12358        else curTransform = parseFloat(matrix[5]);
12359    }
12360    return curTransform || 0;
12361}
12362
12363function isObject(o) {
12364    return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object';
12365}
12366
12367function isNode(node) {
12368    // eslint-disable-next-line
12369    if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') {
12370        return node instanceof HTMLElement;
12371    }
12372    return node && (node.nodeType === 1 || node.nodeType === 11);
12373}
12374
12375function extend() {
12376    const to = Object(arguments.length <= 0 ? undefined : arguments[0]);
12377    const noExtend = ['__proto__', 'constructor', 'prototype'];
12378    for (let i = 1; i < arguments.length; i += 1) {
12379        const nextSource = i < 0 || arguments.length <= i ? undefined : arguments[i];
12380        if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) {
12381            const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0);
12382            for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
12383                const nextKey = keysArray[nextIndex];
12384                const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
12385                if (desc !== undefined && desc.enumerable) {
12386                    if (isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
12387                        if (nextSource[nextKey].__swiper__) {
12388                            to[nextKey] = nextSource[nextKey];
12389                        } else {
12390                            extend(to[nextKey], nextSource[nextKey]);
12391                        }
12392                    } else if (!isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
12393                        to[nextKey] = {};
12394                        if (nextSource[nextKey].__swiper__) {
12395                            to[nextKey] = nextSource[nextKey];
12396                        } else {
12397                            extend(to[nextKey], nextSource[nextKey]);
12398                        }
12399                    } else {
12400                        to[nextKey] = nextSource[nextKey];
12401                    }
12402                }
12403            }
12404        }
12405    }
12406    return to;
12407}
12408
12409function setCSSProperty(el, varName, varValue) {
12410    el.style.setProperty(varName, varValue);
12411}
12412
12413function animateCSSModeScroll(_ref) {
12414    let {
12415        swiper,
12416        targetPosition,
12417        side
12418    } = _ref;
12419    const window = getWindow();
12420    const startPosition = -swiper.translate;
12421    let startTime = null;
12422    let time;
12423    const duration = swiper.params.speed;
12424    swiper.wrapperEl.style.scrollSnapType = 'none';
12425    window.cancelAnimationFrame(swiper.cssModeFrameID);
12426    const dir = targetPosition > startPosition ? 'next' : 'prev';
12427    const isOutOfBound = (current, target) => {
12428        return dir === 'next' && current >= target || dir === 'prev' && current <= target;
12429    };
12430    const animate = () => {
12431        time = new Date().getTime();
12432        if (startTime === null) {
12433            startTime = time;
12434        }
12435        const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
12436        const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
12437        let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);
12438        if (isOutOfBound(currentPosition, targetPosition)) {
12439            currentPosition = targetPosition;
12440        }
12441        swiper.wrapperEl.scrollTo({
12442            [side]: currentPosition
12443        });
12444        if (isOutOfBound(currentPosition, targetPosition)) {
12445            swiper.wrapperEl.style.overflow = 'hidden';
12446            swiper.wrapperEl.style.scrollSnapType = '';
12447            setTimeout(() => {
12448                swiper.wrapperEl.style.overflow = '';
12449                swiper.wrapperEl.scrollTo({
12450                    [side]: currentPosition
12451                });
12452            });
12453            window.cancelAnimationFrame(swiper.cssModeFrameID);
12454            return;
12455        }
12456        swiper.cssModeFrameID = window.requestAnimationFrame(animate);
12457    };
12458    animate();
12459}
12460
12461function getSlideTransformEl(slideEl) {
12462    return slideEl.querySelector('.swiper-slide-transform') || slideEl.shadowRoot && slideEl.shadowRoot.querySelector('.swiper-slide-transform') || slideEl;
12463}
12464
12465function elementChildren(element, selector) {
12466    if (selector === void 0) {
12467        selector = '';
12468    }
12469    const window = getWindow();
12470    const children = [...element.children];
12471    if (window.HTMLSlotElement && element instanceof HTMLSlotElement) {
12472        children.push(...element.assignedElements());
12473    }
12474    if (!selector) {
12475        return children;
12476    }
12477    return children.filter(el => el.matches(selector));
12478}
12479
12480function elementIsChildOfSlot(el, slot) {
12481    // Breadth-first search through all parent's children and assigned elements
12482    const elementsQueue = [slot];
12483    while (elementsQueue.length > 0) {
12484        const elementToCheck = elementsQueue.shift();
12485        if (el === elementToCheck) {
12486            return true;
12487        }
12488        elementsQueue.push(...elementToCheck.children, ...(elementToCheck.shadowRoot ? elementToCheck.shadowRoot.children : []), ...(elementToCheck.assignedElements ? elementToCheck.assignedElements() : []));
12489    }
12490}
12491
12492function elementIsChildOf(el, parent) {
12493    const window = getWindow();
12494    let isChild = parent.contains(el);
12495    if (!isChild && window.HTMLSlotElement && parent instanceof HTMLSlotElement) {
12496        const children = [...parent.assignedElements()];
12497        isChild = children.includes(el);
12498        if (!isChild) {
12499            isChild = elementIsChildOfSlot(el, parent);
12500        }
12501    }
12502    return isChild;
12503}
12504
12505function showWarning(text) {
12506    try {
12507        console.warn(text);
12508        return;
12509    } catch (err) {
12510        // err
12511    }
12512}
12513
12514function createElement(tag, classes) {
12515    if (classes === void 0) {
12516        classes = [];
12517    }
12518    const el = document.createElement(tag);
vendor: 4,072 bytes, lines 12519-12663
12519    el.classList.add(...(Array.isArray(classes) ? classes : classesToTokens(classes)));
12520    return el;
12521}
12522
12523function elementOffset(el) {
12524    const window = getWindow();
12525    const document = getDocument();
12526    const box = el.getBoundingClientRect();
12527    const body = document.body;
12528    const clientTop = el.clientTop || body.clientTop || 0;
12529    const clientLeft = el.clientLeft || body.clientLeft || 0;
12530    const scrollTop = el === window ? window.scrollY : el.scrollTop;
12531    const scrollLeft = el === window ? window.scrollX : el.scrollLeft;
12532    return {
12533        top: box.top + scrollTop - clientTop,
12534        left: box.left + scrollLeft - clientLeft
12535    };
12536}
12537
12538function elementPrevAll(el, selector) {
12539    const prevEls = [];
12540    while (el.previousElementSibling) {
12541        const prev = el.previousElementSibling; // eslint-disable-line
12542        if (selector) {
12543            if (prev.matches(selector)) prevEls.push(prev);
12544        } else prevEls.push(prev);
12545        el = prev;
12546    }
12547    return prevEls;
12548}
12549
12550function elementNextAll(el, selector) {
12551    const nextEls = [];
12552    while (el.nextElementSibling) {
12553        const next = el.nextElementSibling; // eslint-disable-line
12554        if (selector) {
12555            if (next.matches(selector)) nextEls.push(next);
12556        } else nextEls.push(next);
12557        el = next;
12558    }
12559    return nextEls;
12560}
12561
12562function elementStyle(el, prop) {
12563    const window = getWindow();
12564    return window.getComputedStyle(el, null).getPropertyValue(prop);
12565}
12566
12567function elementIndex(el) {
12568    let child = el;
12569    let i;
12570    if (child) {
12571        i = 0;
12572        // eslint-disable-next-line
12573        while ((child = child.previousSibling) !== null) {
12574            if (child.nodeType === 1) i += 1;
12575        }
12576        return i;
12577    }
12578    return undefined;
12579}
12580
12581function elementParents(el, selector) {
12582    const parents = []; // eslint-disable-line
12583    let parent = el.parentElement; // eslint-disable-line
12584    while (parent) {
12585        if (selector) {
12586            if (parent.matches(selector)) parents.push(parent);
12587        } else {
12588            parents.push(parent);
12589        }
12590        parent = parent.parentElement;
12591    }
12592    return parents;
12593}
12594
12595function elementTransitionEnd(el, callback) {
12596    function fireCallBack(e) {
12597        if (e.target !== el) return;
12598        callback.call(el, e);
12599        el.removeEventListener('transitionend', fireCallBack);
12600    }
12601
12602    if (callback) {
12603        el.addEventListener('transitionend', fireCallBack);
12604    }
12605}
12606
12607function elementOuterSize(el, size, includeMargins) {
12608    const window = getWindow();
12609    {
12610        return el[size === 'width' ? 'offsetWidth' : 'offsetHeight'] + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-right' : 'margin-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-left' : 'margin-bottom'));
12611    }
12612}
12613
12614function makeElementsArray(el) {
12615    return (Array.isArray(el) ? el : [el]).filter(e => !!e);
12616}
12617
12618function getRotateFix(swiper) {
12619    return v => {
12620        if (Math.abs(v) > 0 && swiper.browser && swiper.browser.need3dFix && Math.abs(v) % 90 === 0) {
12621            return v + 0.001;
12622        }
12623        return v;
12624    };
12625}
12626
12627function setInnerHTML(el, html) {
12628    if (html === void 0) {
12629        html = '';
12630    }
12631    if (typeof trustedTypes !== 'undefined') {
12632        el.innerHTML = trustedTypes.createPolicy('html', {
12633            createHTML: s => s
12634        }).createHTML(html);
12635    } else {
12636        el.innerHTML = html;
12637    }
12638}
12639
12640let support;
12641
12642function calcSupport() {
12643    const window = getWindow();
12644    const document = getDocument();
12645    return {
12646        smoothScroll: document.documentElement && document.documentElement.style && 'scrollBehavior' in document.documentElement.style,
12647        touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch)
12648    };
12649}
12650
12651function getSupport() {
12652    if (!support) {
12653        support = calcSupport();
12654    }
12655    return support;
12656}
12657
12658let deviceCached;
12659
12660function calcDevice(_temp) {
12661    let {
12662        userAgent
12663    } = _temp === void 0 ? {} : _temp;
vendor: 12,525 bytes, lines 12664-13021
12664    const support = getSupport();
12665    const window = getWindow();
12666    const platform = window.navigator.platform;
12667    const ua = userAgent || window.navigator.userAgent;
12668    const device = {
12669        ios: false,
12670        android: false
12671    };
12672    const screenWidth = window.screen.width;
12673    const screenHeight = window.screen.height;
12674    const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
12675    let ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
12676    const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
12677    const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
12678    const windows = platform === 'Win32';
12679    let macos = platform === 'MacIntel';
12680
12681    // iPadOs 13 fix
12682    const iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768', '820x1180', '1180x820', '810x1080', '1080x810'];
12683    if (!ipad && macos && support.touch && iPadScreens.indexOf(`${screenWidth}x${screenHeight}`) >= 0) {
12684        ipad = ua.match(/(Version)\/([\d.]+)/);
12685        if (!ipad) ipad = [0, 1, '13_0_0'];
12686        macos = false;
12687    }
12688
12689    // Android
12690    if (android && !windows) {
12691        device.os = 'android';
12692        device.android = true;
12693    }
12694    if (ipad || iphone || ipod) {
12695        device.os = 'ios';
12696        device.ios = true;
12697    }
12698
12699    // Export object
12700    return device;
12701}
12702
12703function getDevice(overrides) {
12704    if (overrides === void 0) {
12705        overrides = {};
12706    }
12707    if (!deviceCached) {
12708        deviceCached = calcDevice(overrides);
12709    }
12710    return deviceCached;
12711}
12712
12713let browser;
12714
12715function calcBrowser() {
12716    const window = getWindow();
12717    const device = getDevice();
12718    let needPerspectiveFix = false;
12719
12720    function isSafari() {
12721        const ua = window.navigator.userAgent.toLowerCase();
12722        return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0;
12723    }
12724
12725    if (isSafari()) {
12726        const ua = String(window.navigator.userAgent);
12727        if (ua.includes('Version/')) {
12728            const [major, minor] = ua.split('Version/')[1].split(' ')[0].split('.').map(num => Number(num));
12729            needPerspectiveFix = major < 16 || major === 16 && minor < 2;
12730        }
12731    }
12732    const isWebView = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent);
12733    const isSafariBrowser = isSafari();
12734    const need3dFix = isSafariBrowser || isWebView && device.ios;
12735    return {
12736        isSafari: needPerspectiveFix || isSafariBrowser,
12737        needPerspectiveFix,
12738        need3dFix,
12739        isWebView
12740    };
12741}
12742
12743function getBrowser() {
12744    if (!browser) {
12745        browser = calcBrowser();
12746    }
12747    return browser;
12748}
12749
12750function Resize(_ref) {
12751    let {
12752        swiper,
12753        on,
12754        emit
12755    } = _ref;
12756    const window = getWindow();
12757    let observer = null;
12758    let animationFrame = null;
12759    const resizeHandler = () => {
12760        if (!swiper || swiper.destroyed || !swiper.initialized) return;
12761        emit('beforeResize');
12762        emit('resize');
12763    };
12764    const createObserver = () => {
12765        if (!swiper || swiper.destroyed || !swiper.initialized) return;
12766        observer = new ResizeObserver(entries => {
12767            animationFrame = window.requestAnimationFrame(() => {
12768                const {
12769                    width,
12770                    height
12771                } = swiper;
12772                let newWidth = width;
12773                let newHeight = height;
12774                entries.forEach(_ref2 => {
12775                    let {
12776                        contentBoxSize,
12777                        contentRect,
12778                        target
12779                    } = _ref2;
12780                    if (target && target !== swiper.el) return;
12781                    newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize;
12782                    newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize;
12783                });
12784                if (newWidth !== width || newHeight !== height) {
12785                    resizeHandler();
12786                }
12787            });
12788        });
12789        observer.observe(swiper.el);
12790    };
12791    const removeObserver = () => {
12792        if (animationFrame) {
12793            window.cancelAnimationFrame(animationFrame);
12794        }
12795        if (observer && observer.unobserve && swiper.el) {
12796            observer.unobserve(swiper.el);
12797            observer = null;
12798        }
12799    };
12800    const orientationChangeHandler = () => {
12801        if (!swiper || swiper.destroyed || !swiper.initialized) return;
12802        emit('orientationchange');
12803    };
12804    on('init', () => {
12805        if (swiper.params.resizeObserver && typeof window.ResizeObserver !== 'undefined') {
12806            createObserver();
12807            return;
12808        }
12809        window.addEventListener('resize', resizeHandler);
12810        window.addEventListener('orientationchange', orientationChangeHandler);
12811    });
12812    on('destroy', () => {
12813        removeObserver();
12814        window.removeEventListener('resize', resizeHandler);
12815        window.removeEventListener('orientationchange', orientationChangeHandler);
12816    });
12817}
12818
12819function Observer(_ref) {
12820    let {
12821        swiper,
12822        extendParams,
12823        on,
12824        emit
12825    } = _ref;
12826    const observers = [];
12827    const window = getWindow();
12828    const attach = function (target, options) {
12829        if (options === void 0) {
12830            options = {};
12831        }
12832        const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
12833        const observer = new ObserverFunc(mutations => {
12834            // The observerUpdate event should only be triggered
12835            // once despite the number of mutations.  Additional
12836            // triggers are redundant and are very costly
12837            if (swiper.__preventObserver__) return;
12838            if (mutations.length === 1) {
12839                emit('observerUpdate', mutations[0]);
12840                return;
12841            }
12842            const observerUpdate = function observerUpdate() {
12843                emit('observerUpdate', mutations[0]);
12844            };
12845            if (window.requestAnimationFrame) {
12846                window.requestAnimationFrame(observerUpdate);
12847            } else {
12848                window.setTimeout(observerUpdate, 0);
12849            }
12850        });
12851        observer.observe(target, {
12852            attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
12853            childList: swiper.isElement || (typeof options.childList === 'undefined' ? true : options).childList,
12854            characterData: typeof options.characterData === 'undefined' ? true : options.characterData
12855        });
12856        observers.push(observer);
12857    };
12858    const init = () => {
12859        if (!swiper.params.observer) return;
12860        if (swiper.params.observeParents) {
12861            const containerParents = elementParents(swiper.hostEl);
12862            for (let i = 0; i < containerParents.length; i += 1) {
12863                attach(containerParents[i]);
12864            }
12865        }
12866        // Observe container
12867        attach(swiper.hostEl, {
12868            childList: swiper.params.observeSlideChildren
12869        });
12870
12871        // Observe wrapper
12872        attach(swiper.wrapperEl, {
12873            attributes: false
12874        });
12875    };
12876    const destroy = () => {
12877        observers.forEach(observer => {
12878            observer.disconnect();
12879        });
12880        observers.splice(0, observers.length);
12881    };
12882    extendParams({
12883        observer: false,
12884        observeParents: false,
12885        observeSlideChildren: false
12886    });
12887    on('init', init);
12888    on('destroy', destroy);
12889}
12890
12891/* eslint-disable no-underscore-dangle */
12892
12893var eventsEmitter = {
12894    on(events, handler, priority) {
12895        const self = this;
12896        if (!self.eventsListeners || self.destroyed) return self;
12897        if (typeof handler !== 'function') return self;
12898        const method = priority ? 'unshift' : 'push';
12899        events.split(' ').forEach(event => {
12900            if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
12901            self.eventsListeners[event][method](handler);
12902        });
12903        return self;
12904    },
12905    once(events, handler, priority) {
12906        const self = this;
12907        if (!self.eventsListeners || self.destroyed) return self;
12908        if (typeof handler !== 'function') return self;
12909
12910        function onceHandler() {
12911            self.off(events, onceHandler);
12912            if (onceHandler.__emitterProxy) {
12913                delete onceHandler.__emitterProxy;
12914            }
12915            for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
12916                args[_key] = arguments[_key];
12917            }
12918            handler.apply(self, args);
12919        }
12920
12921        onceHandler.__emitterProxy = handler;
12922        return self.on(events, onceHandler, priority);
12923    },
12924    onAny(handler, priority) {
12925        const self = this;
12926        if (!self.eventsListeners || self.destroyed) return self;
12927        if (typeof handler !== 'function') return self;
12928        const method = priority ? 'unshift' : 'push';
12929        if (self.eventsAnyListeners.indexOf(handler) < 0) {
12930            self.eventsAnyListeners[method](handler);
12931        }
12932        return self;
12933    },
12934    offAny(handler) {
12935        const self = this;
12936        if (!self.eventsListeners || self.destroyed) return self;
12937        if (!self.eventsAnyListeners) return self;
12938        const index = self.eventsAnyListeners.indexOf(handler);
12939        if (index >= 0) {
12940            self.eventsAnyListeners.splice(index, 1);
12941        }
12942        return self;
12943    },
12944    off(events, handler) {
12945        const self = this;
12946        if (!self.eventsListeners || self.destroyed) return self;
12947        if (!self.eventsListeners) return self;
12948        events.split(' ').forEach(event => {
12949            if (typeof handler === 'undefined') {
12950                self.eventsListeners[event] = [];
12951            } else if (self.eventsListeners[event]) {
12952                self.eventsListeners[event].forEach((eventHandler, index) => {
12953                    if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) {
12954                        self.eventsListeners[event].splice(index, 1);
12955                    }
12956                });
12957            }
12958        });
12959        return self;
12960    },
12961    emit() {
12962        const self = this;
12963        if (!self.eventsListeners || self.destroyed) return self;
12964        if (!self.eventsListeners) return self;
12965        let events;
12966        let data;
12967        let context;
12968        for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
12969            args[_key2] = arguments[_key2];
12970        }
12971        if (typeof args[0] === 'string' || Array.isArray(args[0])) {
12972            events = args[0];
12973            data = args.slice(1, args.length);
12974            context = self;
12975        } else {
12976            events = args[0].events;
12977            data = args[0].data;
12978            context = args[0].context || self;
12979        }
12980        data.unshift(context);
12981        const eventsArray = Array.isArray(events) ? events : events.split(' ');
12982        eventsArray.forEach(event => {
12983            if (self.eventsAnyListeners && self.eventsAnyListeners.length) {
12984                self.eventsAnyListeners.forEach(eventHandler => {
12985                    eventHandler.apply(context, [event, ...data]);
12986                });
12987            }
12988            if (self.eventsListeners && self.eventsListeners[event]) {
12989                self.eventsListeners[event].forEach(eventHandler => {
12990                    eventHandler.apply(context, data);
12991                });
12992            }
12993        });
12994        return self;
12995    }
12996};
12997
12998function updateSize() {
12999    const swiper = this;
13000    let width;
13001    let height;
13002    const el = swiper.el;
13003    if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
13004        width = swiper.params.width;
13005    } else {
13006        width = el.clientWidth;
13007    }
13008    if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
13009        height = swiper.params.height;
13010    } else {
13011        height = el.clientHeight;
13012    }
13013    if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {
13014        return;
13015    }
13016
13017    // Subtract paddings
13018    width = width - parseInt(elementStyle(el, 'padding-left') || 0, 10) - parseInt(elementStyle(el, 'padding-right') || 0, 10);
13019    height = height - parseInt(elementStyle(el, 'padding-top') || 0, 10) - parseInt(elementStyle(el, 'padding-bottom') || 0, 10);
13020    if (Number.isNaN(width)) width = 0;
13021    if (Number.isNaN(height)) height = 0;
vendor: 1,886 bytes, lines 13022-13075
13022    Object.assign(swiper, {
13023        width,
13024        height,
13025        size: swiper.isHorizontal() ? width : height
13026    });
13027}
13028
13029function updateSlides() {
13030    const swiper = this;
13031
13032    function getDirectionPropertyValue(node, label) {
13033        return parseFloat(node.getPropertyValue(swiper.getDirectionLabel(label)) || 0);
13034    }
13035
13036    const params = swiper.params;
13037    const {
13038        wrapperEl,
13039        slidesEl,
13040        size: swiperSize,
13041        rtlTranslate: rtl,
13042        wrongRTL
13043    } = swiper;
13044    const isVirtual = swiper.virtual && params.virtual.enabled;
13045    const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
13046    const slides = elementChildren(slidesEl, `.${swiper.params.slideClass}, swiper-slide`);
13047    const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
13048    let snapGrid = [];
13049    const slidesGrid = [];
13050    const slidesSizesGrid = [];
13051    let offsetBefore = params.slidesOffsetBefore;
13052    if (typeof offsetBefore === 'function') {
13053        offsetBefore = params.slidesOffsetBefore.call(swiper);
13054    }
13055    let offsetAfter = params.slidesOffsetAfter;
13056    if (typeof offsetAfter === 'function') {
13057        offsetAfter = params.slidesOffsetAfter.call(swiper);
13058    }
13059    const previousSnapGridLength = swiper.snapGrid.length;
13060    const previousSlidesGridLength = swiper.slidesGrid.length;
13061    let spaceBetween = params.spaceBetween;
13062    let slidePosition = -offsetBefore;
13063    let prevSlideSize = 0;
13064    let index = 0;
13065    if (typeof swiperSize === 'undefined') {
13066        return;
13067    }
13068    if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
13069        spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
13070    } else if (typeof spaceBetween === 'string') {
13071        spaceBetween = parseFloat(spaceBetween);
13072    }
13073    swiper.virtualSize = -spaceBetween;
13074
13075    // reset margins
vendor: 5,704 bytes, lines 13076-13197
13076    slides.forEach(slideEl => {
13077        if (rtl) {
13078            slideEl.style.marginLeft = '';
13079        } else {
13080            slideEl.style.marginRight = '';
13081        }
13082        slideEl.style.marginBottom = '';
13083        slideEl.style.marginTop = '';
13084    });
13085
13086    // reset cssMode offsets
13087    if (params.centeredSlides && params.cssMode) {
13088        setCSSProperty(wrapperEl, '--swiper-centered-offset-before', '');
13089        setCSSProperty(wrapperEl, '--swiper-centered-offset-after', '');
13090    }
13091    const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
13092    if (gridEnabled) {
13093        swiper.grid.initSlides(slides);
13094    } else if (swiper.grid) {
13095        swiper.grid.unsetSlides();
13096    }
13097
13098    // Calc slides
13099    let slideSize;
13100    const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => {
13101        return typeof params.breakpoints[key].slidesPerView !== 'undefined';
13102    }).length > 0;
13103    for (let i = 0; i < slidesLength; i += 1) {
13104        slideSize = 0;
13105        let slide;
13106        if (slides[i]) slide = slides[i];
13107        if (gridEnabled) {
13108            swiper.grid.updateSlide(i, slide, slides);
13109        }
13110        if (slides[i] && elementStyle(slide, 'display') === 'none') continue; // eslint-disable-line
13111
13112        if (params.slidesPerView === 'auto') {
13113            if (shouldResetSlideSize) {
13114                slides[i].style[swiper.getDirectionLabel('width')] = ``;
13115            }
13116            const slideStyles = getComputedStyle(slide);
13117            const currentTransform = slide.style.transform;
13118            const currentWebKitTransform = slide.style.webkitTransform;
13119            if (currentTransform) {
13120                slide.style.transform = 'none';
13121            }
13122            if (currentWebKitTransform) {
13123                slide.style.webkitTransform = 'none';
13124            }
13125            if (params.roundLengths) {
13126                slideSize = swiper.isHorizontal() ? elementOuterSize(slide, 'width') : elementOuterSize(slide, 'height');
13127            } else {
13128                // eslint-disable-next-line
13129                const width = getDirectionPropertyValue(slideStyles, 'width');
13130                const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
13131                const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
13132                const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
13133                const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
13134                const boxSizing = slideStyles.getPropertyValue('box-sizing');
13135                if (boxSizing && boxSizing === 'border-box') {
13136                    slideSize = width + marginLeft + marginRight;
13137                } else {
13138                    const {
13139                        clientWidth,
13140                        offsetWidth
13141                    } = slide;
13142                    slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);
13143                }
13144            }
13145            if (currentTransform) {
13146                slide.style.transform = currentTransform;
13147            }
13148            if (currentWebKitTransform) {
13149                slide.style.webkitTransform = currentWebKitTransform;
13150            }
13151            if (params.roundLengths) slideSize = Math.floor(slideSize);
13152        } else {
13153            slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
13154            if (params.roundLengths) slideSize = Math.floor(slideSize);
13155            if (slides[i]) {
13156                slides[i].style[swiper.getDirectionLabel('width')] = `${slideSize}px`;
13157            }
13158        }
13159        if (slides[i]) {
13160            slides[i].swiperSlideSize = slideSize;
13161        }
13162        slidesSizesGrid.push(slideSize);
13163        if (params.centeredSlides) {
13164            slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
13165            if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
13166            if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
13167            if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
13168            if (params.roundLengths) slidePosition = Math.floor(slidePosition);
13169            if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
13170            slidesGrid.push(slidePosition);
13171        } else {
13172            if (params.roundLengths) slidePosition = Math.floor(slidePosition);
13173            if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);
13174            slidesGrid.push(slidePosition);
13175            slidePosition = slidePosition + slideSize + spaceBetween;
13176        }
13177        swiper.virtualSize += slideSize + spaceBetween;
13178        prevSlideSize = slideSize;
13179        index += 1;
13180    }
13181    swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
13182    if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
13183        wrapperEl.style.width = `${swiper.virtualSize + spaceBetween}px`;
13184    }
13185    if (params.setWrapperSize) {
13186        wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
13187    }
13188    if (gridEnabled) {
13189        swiper.grid.updateWrapperSize(slideSize, snapGrid);
13190    }
13191
13192    // Remove last grid elements depending on width
13193    if (!params.centeredSlides) {
13194        const newSlidesGrid = [];
13195        for (let i = 0; i < snapGrid.length; i += 1) {
13196            let slidesGridItem = snapGrid[i];
13197            if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
vendor: 1,593 bytes, lines 13198-13233
13198            if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
13199                newSlidesGrid.push(slidesGridItem);
13200            }
13201        }
13202        snapGrid = newSlidesGrid;
13203        if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
13204            snapGrid.push(swiper.virtualSize - swiperSize);
13205        }
13206    }
13207    if (isVirtual && params.loop) {
13208        const size = slidesSizesGrid[0] + spaceBetween;
13209        if (params.slidesPerGroup > 1) {
13210            const groups = Math.ceil((swiper.virtual.slidesBefore + swiper.virtual.slidesAfter) / params.slidesPerGroup);
13211            const groupSize = size * params.slidesPerGroup;
13212            for (let i = 0; i < groups; i += 1) {
13213                snapGrid.push(snapGrid[snapGrid.length - 1] + groupSize);
13214            }
13215        }
13216        for (let i = 0; i < swiper.virtual.slidesBefore + swiper.virtual.slidesAfter; i += 1) {
13217            if (params.slidesPerGroup === 1) {
13218                snapGrid.push(snapGrid[snapGrid.length - 1] + size);
13219            }
13220            slidesGrid.push(slidesGrid[slidesGrid.length - 1] + size);
13221            swiper.virtualSize += size;
13222        }
13223    }
13224    if (snapGrid.length === 0) snapGrid = [0];
13225    if (spaceBetween !== 0) {
13226        const key = swiper.isHorizontal() && rtl ? 'marginLeft' : swiper.getDirectionLabel('marginRight');
13227        slides.filter((_, slideIndex) => {
13228            if (!params.cssMode || params.loop) return true;
13229            if (slideIndex === slides.length - 1) {
13230                return false;
13231            }
13232            return true;
13233        }
vendor: 7,512 bytes, lines 13233-13408
13233).forEach(slideEl => {
13234            slideEl.style[key] = `${spaceBetween}px`;
13235        });
13236    }
13237    if (params.centeredSlides && params.centeredSlidesBounds) {
13238        let allSlidesSize = 0;
13239        slidesSizesGrid.forEach(slideSizeValue => {
13240            allSlidesSize += slideSizeValue + (spaceBetween || 0);
13241        });
13242        allSlidesSize -= spaceBetween;
13243        const maxSnap = allSlidesSize > swiperSize ? allSlidesSize - swiperSize : 0;
13244        snapGrid = snapGrid.map(snap => {
13245            if (snap <= 0) return -offsetBefore;
13246            if (snap > maxSnap) return maxSnap + offsetAfter;
13247            return snap;
13248        });
13249    }
13250    if (params.centerInsufficientSlides) {
13251        let allSlidesSize = 0;
13252        slidesSizesGrid.forEach(slideSizeValue => {
13253            allSlidesSize += slideSizeValue + (spaceBetween || 0);
13254        });
13255        allSlidesSize -= spaceBetween;
13256        const offsetSize = (params.slidesOffsetBefore || 0) + (params.slidesOffsetAfter || 0);
13257        if (allSlidesSize + offsetSize < swiperSize) {
13258            const allSlidesOffset = (swiperSize - allSlidesSize - offsetSize) / 2;
13259            snapGrid.forEach((snap, snapIndex) => {
13260                snapGrid[snapIndex] = snap - allSlidesOffset;
13261            });
13262            slidesGrid.forEach((snap, snapIndex) => {
13263                slidesGrid[snapIndex] = snap + allSlidesOffset;
13264            });
13265        }
13266    }
13267    Object.assign(swiper, {
13268        slides,
13269        snapGrid,
13270        slidesGrid,
13271        slidesSizesGrid
13272    });
13273    if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) {
13274        setCSSProperty(wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`);
13275        setCSSProperty(wrapperEl, '--swiper-centered-offset-after', `${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`);
13276        const addToSnapGrid = -swiper.snapGrid[0];
13277        const addToSlidesGrid = -swiper.slidesGrid[0];
13278        swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);
13279        swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);
13280    }
13281    if (slidesLength !== previousSlidesLength) {
13282        swiper.emit('slidesLengthChange');
13283    }
13284    if (snapGrid.length !== previousSnapGridLength) {
13285        if (swiper.params.watchOverflow) swiper.checkOverflow();
13286        swiper.emit('snapGridLengthChange');
13287    }
13288    if (slidesGrid.length !== previousSlidesGridLength) {
13289        swiper.emit('slidesGridLengthChange');
13290    }
13291    if (params.watchSlidesProgress) {
13292        swiper.updateSlidesOffset();
13293    }
13294    swiper.emit('slidesUpdated');
13295    if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) {
13296        const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`;
13297        const hasClassBackfaceClassAdded = swiper.el.classList.contains(backFaceHiddenClass);
13298        if (slidesLength <= params.maxBackfaceHiddenSlides) {
13299            if (!hasClassBackfaceClassAdded) swiper.el.classList.add(backFaceHiddenClass);
13300        } else if (hasClassBackfaceClassAdded) {
13301            swiper.el.classList.remove(backFaceHiddenClass);
13302        }
13303    }
13304}
13305
13306function updateAutoHeight(speed) {
13307    const swiper = this;
13308    const activeSlides = [];
13309    const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
13310    let newHeight = 0;
13311    let i;
13312    if (typeof speed === 'number') {
13313        swiper.setTransition(speed);
13314    } else if (speed === true) {
13315        swiper.setTransition(swiper.params.speed);
13316    }
13317    const getSlideByIndex = index => {
13318        if (isVirtual) {
13319            return swiper.slides[swiper.getSlideIndexByData(index)];
13320        }
13321        return swiper.slides[index];
13322    };
13323    // Find slides currently in view
13324    if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
13325        if (swiper.params.centeredSlides) {
13326            (swiper.visibleSlides || []).forEach(slide => {
13327                activeSlides.push(slide);
13328            });
13329        } else {
13330            for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
13331                const index = swiper.activeIndex + i;
13332                if (index > swiper.slides.length && !isVirtual) break;
13333                activeSlides.push(getSlideByIndex(index));
13334            }
13335        }
13336    } else {
13337        activeSlides.push(getSlideByIndex(swiper.activeIndex));
13338    }
13339
13340    // Find new height from highest slide in view
13341    for (i = 0; i < activeSlides.length; i += 1) {
13342        if (typeof activeSlides[i] !== 'undefined') {
13343            const height = activeSlides[i].offsetHeight;
13344            newHeight = height > newHeight ? height : newHeight;
13345        }
13346    }
13347
13348    // Update Height
13349    if (newHeight || newHeight === 0) swiper.wrapperEl.style.height = `${newHeight}px`;
13350}
13351
13352function updateSlidesOffset() {
13353    const swiper = this;
13354    const slides = swiper.slides;
13355    // eslint-disable-next-line
13356    const minusOffset = swiper.isElement ? swiper.isHorizontal() ? swiper.wrapperEl.offsetLeft : swiper.wrapperEl.offsetTop : 0;
13357    for (let i = 0; i < slides.length; i += 1) {
13358        slides[i].swiperSlideOffset = (swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop) - minusOffset - swiper.cssOverflowAdjustment();
13359    }
13360}
13361
13362const toggleSlideClasses$1 = (slideEl, condition, className) => {
13363    if (condition && !slideEl.classList.contains(className)) {
13364        slideEl.classList.add(className);
13365    } else if (!condition && slideEl.classList.contains(className)) {
13366        slideEl.classList.remove(className);
13367    }
13368};
13369
13370function updateSlidesProgress(translate) {
13371    if (translate === void 0) {
13372        translate = this && this.translate || 0;
13373    }
13374    const swiper = this;
13375    const params = swiper.params;
13376    const {
13377        slides,
13378        rtlTranslate: rtl,
13379        snapGrid
13380    } = swiper;
13381    if (slides.length === 0) return;
13382    if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset();
13383    let offsetCenter = -translate;
13384    if (rtl) offsetCenter = translate;
13385    swiper.visibleSlidesIndexes = [];
13386    swiper.visibleSlides = [];
13387    let spaceBetween = params.spaceBetween;
13388    if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
13389        spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
13390    } else if (typeof spaceBetween === 'string') {
13391        spaceBetween = parseFloat(spaceBetween);
13392    }
13393    for (let i = 0; i < slides.length; i += 1) {
13394        const slide = slides[i];
13395        let slideOffset = slide.swiperSlideOffset;
13396        if (params.cssMode && params.centeredSlides) {
13397            slideOffset -= slides[0].swiperSlideOffset;
13398        }
13399        const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
13400        const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween);
13401        const slideBefore = -(offsetCenter - slideOffset);
13402        const slideAfter = slideBefore + swiper.slidesSizesGrid[i];
13403        const isFullyVisible = slideBefore >= 0 && slideBefore <= swiper.size - swiper.slidesSizesGrid[i];
13404        const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size;
13405        if (isVisible) {
13406            swiper.visibleSlides.push(slide);
13407            swiper.visibleSlidesIndexes.push(i);
13408        }
vendor: 4,940 bytes, lines 13409-13535
13409        toggleSlideClasses$1(slide, isVisible, params.slideVisibleClass);
13410        toggleSlideClasses$1(slide, isFullyVisible, params.slideFullyVisibleClass);
13411        slide.progress = rtl ? -slideProgress : slideProgress;
13412        slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;
13413    }
13414}
13415
13416function updateProgress(translate) {
13417    const swiper = this;
13418    if (typeof translate === 'undefined') {
13419        const multiplier = swiper.rtlTranslate ? -1 : 1;
13420        // eslint-disable-next-line
13421        translate = swiper && swiper.translate && swiper.translate * multiplier || 0;
13422    }
13423    const params = swiper.params;
13424    const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
13425    let {
13426        progress,
13427        isBeginning,
13428        isEnd,
13429        progressLoop
13430    } = swiper;
13431    const wasBeginning = isBeginning;
13432    const wasEnd = isEnd;
13433    if (translatesDiff === 0) {
13434        progress = 0;
13435        isBeginning = true;
13436        isEnd = true;
13437    } else {
13438        progress = (translate - swiper.minTranslate()) / translatesDiff;
13439        const isBeginningRounded = Math.abs(translate - swiper.minTranslate()) < 1;
13440        const isEndRounded = Math.abs(translate - swiper.maxTranslate()) < 1;
13441        isBeginning = isBeginningRounded || progress <= 0;
13442        isEnd = isEndRounded || progress >= 1;
13443        if (isBeginningRounded) progress = 0;
13444        if (isEndRounded) progress = 1;
13445    }
13446    if (params.loop) {
13447        const firstSlideIndex = swiper.getSlideIndexByData(0);
13448        const lastSlideIndex = swiper.getSlideIndexByData(swiper.slides.length - 1);
13449        const firstSlideTranslate = swiper.slidesGrid[firstSlideIndex];
13450        const lastSlideTranslate = swiper.slidesGrid[lastSlideIndex];
13451        const translateMax = swiper.slidesGrid[swiper.slidesGrid.length - 1];
13452        const translateAbs = Math.abs(translate);
13453        if (translateAbs >= firstSlideTranslate) {
13454            progressLoop = (translateAbs - firstSlideTranslate) / translateMax;
13455        } else {
13456            progressLoop = (translateAbs + translateMax - lastSlideTranslate) / translateMax;
13457        }
13458        if (progressLoop > 1) progressLoop -= 1;
13459    }
13460    Object.assign(swiper, {
13461        progress,
13462        progressLoop,
13463        isBeginning,
13464        isEnd
13465    });
13466    if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);
13467    if (isBeginning && !wasBeginning) {
13468        swiper.emit('reachBeginning toEdge');
13469    }
13470    if (isEnd && !wasEnd) {
13471        swiper.emit('reachEnd toEdge');
13472    }
13473    if (wasBeginning && !isBeginning || wasEnd && !isEnd) {
13474        swiper.emit('fromEdge');
13475    }
13476    swiper.emit('progress', progress);
13477}
13478
13479const toggleSlideClasses = (slideEl, condition, className) => {
13480    if (condition && !slideEl.classList.contains(className)) {
13481        slideEl.classList.add(className);
13482    } else if (!condition && slideEl.classList.contains(className)) {
13483        slideEl.classList.remove(className);
13484    }
13485};
13486
13487function updateSlidesClasses() {
13488    const swiper = this;
13489    const {
13490        slides,
13491        params,
13492        slidesEl,
13493        activeIndex
13494    } = swiper;
13495    const isVirtual = swiper.virtual && params.virtual.enabled;
13496    const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
13497    const getFilteredSlide = selector => {
13498        return elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0];
13499    };
13500    let activeSlide;
13501    let prevSlide;
13502    let nextSlide;
13503    if (isVirtual) {
13504        if (params.loop) {
13505            let slideIndex = activeIndex - swiper.virtual.slidesBefore;
13506            if (slideIndex < 0) slideIndex = swiper.virtual.slides.length + slideIndex;
13507            if (slideIndex >= swiper.virtual.slides.length) slideIndex -= swiper.virtual.slides.length;
13508            activeSlide = getFilteredSlide(`[data-swiper-slide-index="${slideIndex}"]`);
13509        } else {
13510            activeSlide = getFilteredSlide(`[data-swiper-slide-index="${activeIndex}"]`);
13511        }
13512    } else {
13513        if (gridEnabled) {
13514            activeSlide = slides.find(slideEl => slideEl.column === activeIndex);
13515            nextSlide = slides.find(slideEl => slideEl.column === activeIndex + 1);
13516            prevSlide = slides.find(slideEl => slideEl.column === activeIndex - 1);
13517        } else {
13518            activeSlide = slides[activeIndex];
13519        }
13520    }
13521    if (activeSlide) {
13522        if (!gridEnabled) {
13523            // Next Slide
13524            nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
13525            if (params.loop && !nextSlide) {
13526                nextSlide = slides[0];
13527            }
13528
13529            // Prev Slide
13530            prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
13531            if (params.loop && !prevSlide === 0) {
13532                prevSlide = slides[slides.length - 1];
13533            }
13534        }
13535    }
vendor: 13,540 bytes, lines 13536-13919
13536    slides.forEach(slideEl => {
13537        toggleSlideClasses(slideEl, slideEl === activeSlide, params.slideActiveClass);
13538        toggleSlideClasses(slideEl, slideEl === nextSlide, params.slideNextClass);
13539        toggleSlideClasses(slideEl, slideEl === prevSlide, params.slidePrevClass);
13540    });
13541    swiper.emitSlidesClasses();
13542}
13543
13544const processLazyPreloader = (swiper, imageEl) => {
13545    if (!swiper || swiper.destroyed || !swiper.params) return;
13546    const slideSelector = () => swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
13547    const slideEl = imageEl.closest(slideSelector());
13548    if (slideEl) {
13549        let lazyEl = slideEl.querySelector(`.${swiper.params.lazyPreloaderClass}`);
13550        if (!lazyEl && swiper.isElement) {
13551            if (slideEl.shadowRoot) {
13552                lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
13553            } else {
13554                // init later
13555                requestAnimationFrame(() => {
13556                    if (slideEl.shadowRoot) {
13557                        lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`);
13558                        if (lazyEl) lazyEl.remove();
13559                    }
13560                });
13561            }
13562        }
13563        if (lazyEl) lazyEl.remove();
13564    }
13565};
13566const unlazy = (swiper, index) => {
13567    if (!swiper.slides[index]) return;
13568    const imageEl = swiper.slides[index].querySelector('[loading="lazy"]');
13569    if (imageEl) imageEl.removeAttribute('loading');
13570};
13571const preload = swiper => {
13572    if (!swiper || swiper.destroyed || !swiper.params) return;
13573    let amount = swiper.params.lazyPreloadPrevNext;
13574    const len = swiper.slides.length;
13575    if (!len || !amount || amount < 0) return;
13576    amount = Math.min(amount, len);
13577    const slidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(swiper.params.slidesPerView);
13578    const activeIndex = swiper.activeIndex;
13579    if (swiper.params.grid && swiper.params.grid.rows > 1) {
13580        const activeColumn = activeIndex;
13581        const preloadColumns = [activeColumn - amount];
13582        preloadColumns.push(...Array.from({
13583            length: amount
13584        }).map((_, i) => {
13585            return activeColumn + slidesPerView + i;
13586        }));
13587        swiper.slides.forEach((slideEl, i) => {
13588            if (preloadColumns.includes(slideEl.column)) unlazy(swiper, i);
13589        });
13590        return;
13591    }
13592    const slideIndexLastInView = activeIndex + slidesPerView - 1;
13593    if (swiper.params.rewind || swiper.params.loop) {
13594        for (let i = activeIndex - amount; i <= slideIndexLastInView + amount; i += 1) {
13595            const realIndex = (i % len + len) % len;
13596            if (realIndex < activeIndex || realIndex > slideIndexLastInView) unlazy(swiper, realIndex);
13597        }
13598    } else {
13599        for (let i = Math.max(activeIndex - amount, 0); i <= Math.min(slideIndexLastInView + amount, len - 1); i += 1) {
13600            if (i !== activeIndex && (i > slideIndexLastInView || i < activeIndex)) {
13601                unlazy(swiper, i);
13602            }
13603        }
13604    }
13605};
13606
13607function getActiveIndexByTranslate(swiper) {
13608    const {
13609        slidesGrid,
13610        params
13611    } = swiper;
13612    const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
13613    let activeIndex;
13614    for (let i = 0; i < slidesGrid.length; i += 1) {
13615        if (typeof slidesGrid[i + 1] !== 'undefined') {
13616            if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) {
13617                activeIndex = i;
13618            } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
13619                activeIndex = i + 1;
13620            }
13621        } else if (translate >= slidesGrid[i]) {
13622            activeIndex = i;
13623        }
13624    }
13625    // Normalize slideIndex
13626    if (params.normalizeSlideIndex) {
13627        if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
13628    }
13629    return activeIndex;
13630}
13631
13632function updateActiveIndex(newActiveIndex) {
13633    const swiper = this;
13634    const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
13635    const {
13636        snapGrid,
13637        params,
13638        activeIndex: previousIndex,
13639        realIndex: previousRealIndex,
13640        snapIndex: previousSnapIndex
13641    } = swiper;
13642    let activeIndex = newActiveIndex;
13643    let snapIndex;
13644    const getVirtualRealIndex = aIndex => {
13645        let realIndex = aIndex - swiper.virtual.slidesBefore;
13646        if (realIndex < 0) {
13647            realIndex = swiper.virtual.slides.length + realIndex;
13648        }
13649        if (realIndex >= swiper.virtual.slides.length) {
13650            realIndex -= swiper.virtual.slides.length;
13651        }
13652        return realIndex;
13653    };
13654    if (typeof activeIndex === 'undefined') {
13655        activeIndex = getActiveIndexByTranslate(swiper);
13656    }
13657    if (snapGrid.indexOf(translate) >= 0) {
13658        snapIndex = snapGrid.indexOf(translate);
13659    } else {
13660        const skip = Math.min(params.slidesPerGroupSkip, activeIndex);
13661        snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
13662    }
13663    if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
13664    if (activeIndex === previousIndex && !swiper.params.loop) {
13665        if (snapIndex !== previousSnapIndex) {
13666            swiper.snapIndex = snapIndex;
13667            swiper.emit('snapIndexChange');
13668        }
13669        return;
13670    }
13671    if (activeIndex === previousIndex && swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
13672        swiper.realIndex = getVirtualRealIndex(activeIndex);
13673        return;
13674    }
13675    const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
13676
13677    // Get real index
13678    let realIndex;
13679    if (swiper.virtual && params.virtual.enabled && params.loop) {
13680        realIndex = getVirtualRealIndex(activeIndex);
13681    } else if (gridEnabled) {
13682        const firstSlideInColumn = swiper.slides.find(slideEl => slideEl.column === activeIndex);
13683        let activeSlideIndex = parseInt(firstSlideInColumn.getAttribute('data-swiper-slide-index'), 10);
13684        if (Number.isNaN(activeSlideIndex)) {
13685            activeSlideIndex = Math.max(swiper.slides.indexOf(firstSlideInColumn), 0);
13686        }
13687        realIndex = Math.floor(activeSlideIndex / params.grid.rows);
13688    } else if (swiper.slides[activeIndex]) {
13689        const slideIndex = swiper.slides[activeIndex].getAttribute('data-swiper-slide-index');
13690        if (slideIndex) {
13691            realIndex = parseInt(slideIndex, 10);
13692        } else {
13693            realIndex = activeIndex;
13694        }
13695    } else {
13696        realIndex = activeIndex;
13697    }
13698    Object.assign(swiper, {
13699        previousSnapIndex,
13700        snapIndex,
13701        previousRealIndex,
13702        realIndex,
13703        previousIndex,
13704        activeIndex
13705    });
13706    if (swiper.initialized) {
13707        preload(swiper);
13708    }
13709    swiper.emit('activeIndexChange');
13710    swiper.emit('snapIndexChange');
13711    if (swiper.initialized || swiper.params.runCallbacksOnInit) {
13712        if (previousRealIndex !== realIndex) {
13713            swiper.emit('realIndexChange');
13714        }
13715        swiper.emit('slideChange');
13716    }
13717}
13718
13719function updateClickedSlide(el, path) {
13720    const swiper = this;
13721    const params = swiper.params;
13722    let slide = el.closest(`.${params.slideClass}, swiper-slide`);
13723    if (!slide && swiper.isElement && path && path.length > 1 && path.includes(el)) {
13724        [...path.slice(path.indexOf(el) + 1, path.length)].forEach(pathEl => {
13725            if (!slide && pathEl.matches && pathEl.matches(`.${params.slideClass}, swiper-slide`)) {
13726                slide = pathEl;
13727            }
13728        });
13729    }
13730    let slideFound = false;
13731    let slideIndex;
13732    if (slide) {
13733        for (let i = 0; i < swiper.slides.length; i += 1) {
13734            if (swiper.slides[i] === slide) {
13735                slideFound = true;
13736                slideIndex = i;
13737                break;
13738            }
13739        }
13740    }
13741    if (slide && slideFound) {
13742        swiper.clickedSlide = slide;
13743        if (swiper.virtual && swiper.params.virtual.enabled) {
13744            swiper.clickedIndex = parseInt(slide.getAttribute('data-swiper-slide-index'), 10);
13745        } else {
13746            swiper.clickedIndex = slideIndex;
13747        }
13748    } else {
13749        swiper.clickedSlide = undefined;
13750        swiper.clickedIndex = undefined;
13751        return;
13752    }
13753    if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
13754        swiper.slideToClickedSlide();
13755    }
13756}
13757
13758var update = {
13759    updateSize,
13760    updateSlides,
13761    updateAutoHeight,
13762    updateSlidesOffset,
13763    updateSlidesProgress,
13764    updateProgress,
13765    updateSlidesClasses,
13766    updateActiveIndex,
13767    updateClickedSlide
13768};
13769
13770function getSwiperTranslate(axis) {
13771    if (axis === void 0) {
13772        axis = this.isHorizontal() ? 'x' : 'y';
13773    }
13774    const swiper = this;
13775    const {
13776        params,
13777        rtlTranslate: rtl,
13778        translate,
13779        wrapperEl
13780    } = swiper;
13781    if (params.virtualTranslate) {
13782        return rtl ? -translate : translate;
13783    }
13784    if (params.cssMode) {
13785        return translate;
13786    }
13787    let currentTranslate = getTranslate(wrapperEl, axis);
13788    currentTranslate += swiper.cssOverflowAdjustment();
13789    if (rtl) currentTranslate = -currentTranslate;
13790    return currentTranslate || 0;
13791}
13792
13793function setTranslate(translate, byController) {
13794    const swiper = this;
13795    const {
13796        rtlTranslate: rtl,
13797        params,
13798        wrapperEl,
13799        progress
13800    } = swiper;
13801    let x = 0;
13802    let y = 0;
13803    const z = 0;
13804    if (swiper.isHorizontal()) {
13805        x = rtl ? -translate : translate;
13806    } else {
13807        y = translate;
13808    }
13809    if (params.roundLengths) {
13810        x = Math.floor(x);
13811        y = Math.floor(y);
13812    }
13813    swiper.previousTranslate = swiper.translate;
13814    swiper.translate = swiper.isHorizontal() ? x : y;
13815    if (params.cssMode) {
13816        wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
13817    } else if (!params.virtualTranslate) {
13818        if (swiper.isHorizontal()) {
13819            x -= swiper.cssOverflowAdjustment();
13820        } else {
13821            y -= swiper.cssOverflowAdjustment();
13822        }
13823        wrapperEl.style.transform = `translate3d(${x}px, ${y}px, ${z}px)`;
13824    }
13825
13826    // Check if we need to update progress
13827    let newProgress;
13828    const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
13829    if (translatesDiff === 0) {
13830        newProgress = 0;
13831    } else {
13832        newProgress = (translate - swiper.minTranslate()) / translatesDiff;
13833    }
13834    if (newProgress !== progress) {
13835        swiper.updateProgress(translate);
13836    }
13837    swiper.emit('setTranslate', swiper.translate, byController);
13838}
13839
13840function minTranslate() {
13841    return -this.snapGrid[0];
13842}
13843
13844function maxTranslate() {
13845    return -this.snapGrid[this.snapGrid.length - 1];
13846}
13847
13848function translateTo(translate, speed, runCallbacks, translateBounds, internal) {
13849    if (translate === void 0) {
13850        translate = 0;
13851    }
13852    if (speed === void 0) {
13853        speed = this.params.speed;
13854    }
13855    if (runCallbacks === void 0) {
13856        runCallbacks = true;
13857    }
13858    if (translateBounds === void 0) {
13859        translateBounds = true;
13860    }
13861    const swiper = this;
13862    const {
13863        params,
13864        wrapperEl
13865    } = swiper;
13866    if (swiper.animating && params.preventInteractionOnTransition) {
13867        return false;
13868    }
13869    const minTranslate = swiper.minTranslate();
13870    const maxTranslate = swiper.maxTranslate();
13871    let newTranslate;
13872    if (translateBounds && translate > minTranslate) newTranslate = minTranslate; else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate; else newTranslate = translate;
13873
13874    // Update progress
13875    swiper.updateProgress(newTranslate);
13876    if (params.cssMode) {
13877        const isH = swiper.isHorizontal();
13878        if (speed === 0) {
13879            wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
13880        } else {
13881            if (!swiper.support.smoothScroll) {
13882                animateCSSModeScroll({
13883                    swiper,
13884                    targetPosition: -newTranslate,
13885                    side: isH ? 'left' : 'top'
13886                });
13887                return true;
13888            }
13889            wrapperEl.scrollTo({
13890                [isH ? 'left' : 'top']: -newTranslate,
13891                behavior: 'smooth'
13892            });
13893        }
13894        return true;
13895    }
13896    if (speed === 0) {
13897        swiper.setTransition(0);
13898        swiper.setTranslate(newTranslate);
13899        if (runCallbacks) {
13900            swiper.emit('beforeTransitionStart', speed, internal);
13901            swiper.emit('transitionEnd');
13902        }
13903    } else {
13904        swiper.setTransition(speed);
13905        swiper.setTranslate(newTranslate);
13906        if (runCallbacks) {
13907            swiper.emit('beforeTransitionStart', speed, internal);
13908            swiper.emit('transitionStart');
13909        }
13910        if (!swiper.animating) {
13911            swiper.animating = true;
13912            if (!swiper.onTranslateToWrapperTransitionEnd) {
13913                swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
13914                    if (!swiper || swiper.destroyed) return;
13915                    if (e.target !== this) return;
13916                    swiper.wrapperEl.removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
13917                    swiper.onTranslateToWrapperTransitionEnd = null;
13918                    delete swiper.onTranslateToWrapperTransitionEnd;
13919                    swiper.animating = false;
vendor: 4,649 bytes, lines 13920-14074
13920                    if (runCallbacks) {
13921                        swiper.emit('transitionEnd');
13922                    }
13923                };
13924            }
13925            swiper.wrapperEl.addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd);
13926        }
13927    }
13928    return true;
13929}
13930
13931var translate = {
13932    getTranslate: getSwiperTranslate,
13933    setTranslate,
13934    minTranslate,
13935    maxTranslate,
13936    translateTo
13937};
13938
13939function setTransition(duration, byController) {
13940    const swiper = this;
13941    if (!swiper.params.cssMode) {
13942        swiper.wrapperEl.style.transitionDuration = `${duration}ms`;
13943        swiper.wrapperEl.style.transitionDelay = duration === 0 ? `0ms` : '';
13944    }
13945    swiper.emit('setTransition', duration, byController);
13946}
13947
13948function transitionEmit(_ref) {
13949    let {
13950        swiper,
13951        runCallbacks,
13952        direction,
13953        step
13954    } = _ref;
13955    const {
13956        activeIndex,
13957        previousIndex
13958    } = swiper;
13959    let dir = direction;
13960    if (!dir) {
13961        if (activeIndex > previousIndex) dir = 'next'; else if (activeIndex < previousIndex) dir = 'prev'; else dir = 'reset';
13962    }
13963    swiper.emit(`transition${step}`);
13964    if (runCallbacks && dir === 'reset') {
13965        swiper.emit(`slideResetTransition${step}`);
13966    } else if (runCallbacks && activeIndex !== previousIndex) {
13967        swiper.emit(`slideChangeTransition${step}`);
13968        if (dir === 'next') {
13969            swiper.emit(`slideNextTransition${step}`);
13970        } else {
13971            swiper.emit(`slidePrevTransition${step}`);
13972        }
13973    }
13974}
13975
13976function transitionStart(runCallbacks, direction) {
13977    if (runCallbacks === void 0) {
13978        runCallbacks = true;
13979    }
13980    const swiper = this;
13981    const {
13982        params
13983    } = swiper;
13984    if (params.cssMode) return;
13985    if (params.autoHeight) {
13986        swiper.updateAutoHeight();
13987    }
13988    transitionEmit({
13989        swiper,
13990        runCallbacks,
13991        direction,
13992        step: 'Start'
13993    });
13994}
13995
13996function transitionEnd(runCallbacks, direction) {
13997    if (runCallbacks === void 0) {
13998        runCallbacks = true;
13999    }
14000    const swiper = this;
14001    const {
14002        params
14003    } = swiper;
14004    swiper.animating = false;
14005    if (params.cssMode) return;
14006    swiper.setTransition(0);
14007    transitionEmit({
14008        swiper,
14009        runCallbacks,
14010        direction,
14011        step: 'End'
14012    });
14013}
14014
14015var transition = {
14016    setTransition,
14017    transitionStart,
14018    transitionEnd
14019};
14020
14021function slideTo(index, speed, runCallbacks, internal, initial) {
14022    if (index === void 0) {
14023        index = 0;
14024    }
14025    if (runCallbacks === void 0) {
14026        runCallbacks = true;
14027    }
14028    if (typeof index === 'string') {
14029        index = parseInt(index, 10);
14030    }
14031    const swiper = this;
14032    let slideIndex = index;
14033    if (slideIndex < 0) slideIndex = 0;
14034    const {
14035        params,
14036        snapGrid,
14037        slidesGrid,
14038        previousIndex,
14039        activeIndex,
14040        rtlTranslate: rtl,
14041        wrapperEl,
14042        enabled
14043    } = swiper;
14044    if (!enabled && !internal && !initial || swiper.destroyed || swiper.animating && params.preventInteractionOnTransition) {
14045        return false;
14046    }
14047    if (typeof speed === 'undefined') {
14048        speed = swiper.params.speed;
14049    }
14050    const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
14051    let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
14052    if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
14053    const translate = -snapGrid[snapIndex];
14054    // Normalize slideIndex
14055    if (params.normalizeSlideIndex) {
14056        for (let i = 0; i < slidesGrid.length; i += 1) {
14057            const normalizedTranslate = -Math.floor(translate * 100);
14058            const normalizedGrid = Math.floor(slidesGrid[i] * 100);
14059            const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
14060            if (typeof slidesGrid[i + 1] !== 'undefined') {
14061                if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) {
14062                    slideIndex = i;
14063                } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
14064                    slideIndex = i + 1;
14065                }
14066            } else if (normalizedTranslate >= normalizedGrid) {
14067                slideIndex = i;
14068            }
14069        }
14070    }
14071    // Directions locks
14072    if (swiper.initialized && slideIndex !== activeIndex) {
14073        if (!swiper.allowSlideNext && (rtl ? translate > swiper.translate && translate > swiper.minTranslate() : translate < swiper.translate && translate < swiper.minTranslate())) {
14074            return false;
vendor: 21,728 bytes, lines 14075-14606
14075        }
14076        if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
14077            if ((activeIndex || 0) !== slideIndex) {
14078                return false;
14079            }
14080        }
14081    }
14082    if (slideIndex !== (previousIndex || 0) && runCallbacks) {
14083        swiper.emit('beforeSlideChangeStart');
14084    }
14085
14086    // Update progress
14087    swiper.updateProgress(translate);
14088    let direction;
14089    if (slideIndex > activeIndex) direction = 'next'; else if (slideIndex < activeIndex) direction = 'prev'; else direction = 'reset';
14090
14091    // initial virtual
14092    const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
14093    const isInitialVirtual = isVirtual && initial;
14094    // Update Index
14095    if (!isInitialVirtual && (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate)) {
14096        swiper.updateActiveIndex(slideIndex);
14097        // Update Height
14098        if (params.autoHeight) {
14099            swiper.updateAutoHeight();
14100        }
14101        swiper.updateSlidesClasses();
14102        if (params.effect !== 'slide') {
14103            swiper.setTranslate(translate);
14104        }
14105        if (direction !== 'reset') {
14106            swiper.transitionStart(runCallbacks, direction);
14107            swiper.transitionEnd(runCallbacks, direction);
14108        }
14109        return false;
14110    }
14111    if (params.cssMode) {
14112        const isH = swiper.isHorizontal();
14113        const t = rtl ? translate : -translate;
14114        if (speed === 0) {
14115            if (isVirtual) {
14116                swiper.wrapperEl.style.scrollSnapType = 'none';
14117                swiper._immediateVirtual = true;
14118            }
14119            if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) {
14120                swiper._cssModeVirtualInitialSet = true;
14121                requestAnimationFrame(() => {
14122                    wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
14123                });
14124            } else {
14125                wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
14126            }
14127            if (isVirtual) {
14128                requestAnimationFrame(() => {
14129                    swiper.wrapperEl.style.scrollSnapType = '';
14130                    swiper._immediateVirtual = false;
14131                });
14132            }
14133        } else {
14134            if (!swiper.support.smoothScroll) {
14135                animateCSSModeScroll({
14136                    swiper,
14137                    targetPosition: t,
14138                    side: isH ? 'left' : 'top'
14139                });
14140                return true;
14141            }
14142            wrapperEl.scrollTo({
14143                [isH ? 'left' : 'top']: t,
14144                behavior: 'smooth'
14145            });
14146        }
14147        return true;
14148    }
14149    const browser = getBrowser();
14150    const isSafari = browser.isSafari;
14151    if (isVirtual && !initial && isSafari && swiper.isElement) {
14152        swiper.virtual.update(false, false, slideIndex);
14153    }
14154    swiper.setTransition(speed);
14155    swiper.setTranslate(translate);
14156    swiper.updateActiveIndex(slideIndex);
14157    swiper.updateSlidesClasses();
14158    swiper.emit('beforeTransitionStart', speed, internal);
14159    swiper.transitionStart(runCallbacks, direction);
14160    if (speed === 0) {
14161        swiper.transitionEnd(runCallbacks, direction);
14162    } else if (!swiper.animating) {
14163        swiper.animating = true;
14164        if (!swiper.onSlideToWrapperTransitionEnd) {
14165            swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
14166                if (!swiper || swiper.destroyed) return;
14167                if (e.target !== this) return;
14168                swiper.wrapperEl.removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
14169                swiper.onSlideToWrapperTransitionEnd = null;
14170                delete swiper.onSlideToWrapperTransitionEnd;
14171                swiper.transitionEnd(runCallbacks, direction);
14172            };
14173        }
14174        swiper.wrapperEl.addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);
14175    }
14176    return true;
14177}
14178
14179function slideToLoop(index, speed, runCallbacks, internal) {
14180    if (index === void 0) {
14181        index = 0;
14182    }
14183    if (runCallbacks === void 0) {
14184        runCallbacks = true;
14185    }
14186    if (typeof index === 'string') {
14187        const indexAsNumber = parseInt(index, 10);
14188        index = indexAsNumber;
14189    }
14190    const swiper = this;
14191    if (swiper.destroyed) return;
14192    if (typeof speed === 'undefined') {
14193        speed = swiper.params.speed;
14194    }
14195    const gridEnabled = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
14196    let newIndex = index;
14197    if (swiper.params.loop) {
14198        if (swiper.virtual && swiper.params.virtual.enabled) {
14199            // eslint-disable-next-line
14200            newIndex = newIndex + swiper.virtual.slidesBefore;
14201        } else {
14202            let targetSlideIndex;
14203            if (gridEnabled) {
14204                const slideIndex = newIndex * swiper.params.grid.rows;
14205                targetSlideIndex = swiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex).column;
14206            } else {
14207                targetSlideIndex = swiper.getSlideIndexByData(newIndex);
14208            }
14209            const cols = gridEnabled ? Math.ceil(swiper.slides.length / swiper.params.grid.rows) : swiper.slides.length;
14210            const {
14211                centeredSlides
14212            } = swiper.params;
14213            let slidesPerView = swiper.params.slidesPerView;
14214            if (slidesPerView === 'auto') {
14215                slidesPerView = swiper.slidesPerViewDynamic();
14216            } else {
14217                slidesPerView = Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
14218                if (centeredSlides && slidesPerView % 2 === 0) {
14219                    slidesPerView = slidesPerView + 1;
14220                }
14221            }
14222            let needLoopFix = cols - targetSlideIndex < slidesPerView;
14223            if (centeredSlides) {
14224                needLoopFix = needLoopFix || targetSlideIndex < Math.ceil(slidesPerView / 2);
14225            }
14226            if (internal && centeredSlides && swiper.params.slidesPerView !== 'auto' && !gridEnabled) {
14227                needLoopFix = false;
14228            }
14229            if (needLoopFix) {
14230                const direction = centeredSlides ? targetSlideIndex < swiper.activeIndex ? 'prev' : 'next' : targetSlideIndex - swiper.activeIndex - 1 < swiper.params.slidesPerView ? 'next' : 'prev';
14231                swiper.loopFix({
14232                    direction,
14233                    slideTo: true,
14234                    activeSlideIndex: direction === 'next' ? targetSlideIndex + 1 : targetSlideIndex - cols + 1,
14235                    slideRealIndex: direction === 'next' ? swiper.realIndex : undefined
14236                });
14237            }
14238            if (gridEnabled) {
14239                const slideIndex = newIndex * swiper.params.grid.rows;
14240                newIndex = swiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex).column;
14241            } else {
14242                newIndex = swiper.getSlideIndexByData(newIndex);
14243            }
14244        }
14245    }
14246    requestAnimationFrame(() => {
14247        swiper.slideTo(newIndex, speed, runCallbacks, internal);
14248    });
14249    return swiper;
14250}
14251
14252/* eslint no-unused-vars: "off" */
14253function slideNext(speed, runCallbacks, internal) {
14254    if (runCallbacks === void 0) {
14255        runCallbacks = true;
14256    }
14257    const swiper = this;
14258    const {
14259        enabled,
14260        params,
14261        animating
14262    } = swiper;
14263    if (!enabled || swiper.destroyed) return swiper;
14264    if (typeof speed === 'undefined') {
14265        speed = swiper.params.speed;
14266    }
14267    let perGroup = params.slidesPerGroup;
14268    if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
14269        perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
14270    }
14271    const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
14272    const isVirtual = swiper.virtual && params.virtual.enabled;
14273    if (params.loop) {
14274        if (animating && !isVirtual && params.loopPreventsSliding) return false;
14275        swiper.loopFix({
14276            direction: 'next'
14277        });
14278        // eslint-disable-next-line
14279        swiper._clientLeft = swiper.wrapperEl.clientLeft;
14280        if (swiper.activeIndex === swiper.slides.length - 1 && params.cssMode) {
14281            requestAnimationFrame(() => {
14282                swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
14283            });
14284            return true;
14285        }
14286    }
14287    if (params.rewind && swiper.isEnd) {
14288        return swiper.slideTo(0, speed, runCallbacks, internal);
14289    }
14290    return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal);
14291}
14292
14293/* eslint no-unused-vars: "off" */
14294function slidePrev(speed, runCallbacks, internal) {
14295    if (runCallbacks === void 0) {
14296        runCallbacks = true;
14297    }
14298    const swiper = this;
14299    const {
14300        params,
14301        snapGrid,
14302        slidesGrid,
14303        rtlTranslate,
14304        enabled,
14305        animating
14306    } = swiper;
14307    if (!enabled || swiper.destroyed) return swiper;
14308    if (typeof speed === 'undefined') {
14309        speed = swiper.params.speed;
14310    }
14311    const isVirtual = swiper.virtual && params.virtual.enabled;
14312    if (params.loop) {
14313        if (animating && !isVirtual && params.loopPreventsSliding) return false;
14314        swiper.loopFix({
14315            direction: 'prev'
14316        });
14317        // eslint-disable-next-line
14318        swiper._clientLeft = swiper.wrapperEl.clientLeft;
14319    }
14320    const translate = rtlTranslate ? swiper.translate : -swiper.translate;
14321
14322    function normalize(val) {
14323        if (val < 0) return -Math.floor(Math.abs(val));
14324        return Math.floor(val);
14325    }
14326
14327    const normalizedTranslate = normalize(translate);
14328    const normalizedSnapGrid = snapGrid.map(val => normalize(val));
14329    const isFreeMode = params.freeMode && params.freeMode.enabled;
14330    let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
14331    if (typeof prevSnap === 'undefined' && (params.cssMode || isFreeMode)) {
14332        let prevSnapIndex;
14333        snapGrid.forEach((snap, snapIndex) => {
14334            if (normalizedTranslate >= snap) {
14335                // prevSnap = snap;
14336                prevSnapIndex = snapIndex;
14337            }
14338        });
14339        if (typeof prevSnapIndex !== 'undefined') {
14340            prevSnap = isFreeMode ? snapGrid[prevSnapIndex] : snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
14341        }
14342    }
14343    let prevIndex = 0;
14344    if (typeof prevSnap !== 'undefined') {
14345        prevIndex = slidesGrid.indexOf(prevSnap);
14346        if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
14347        if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
14348            prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1;
14349            prevIndex = Math.max(prevIndex, 0);
14350        }
14351    }
14352    if (params.rewind && swiper.isBeginning) {
14353        const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
14354        return swiper.slideTo(lastIndex, speed, runCallbacks, internal);
14355    } else if (params.loop && swiper.activeIndex === 0 && params.cssMode) {
14356        requestAnimationFrame(() => {
14357            swiper.slideTo(prevIndex, speed, runCallbacks, internal);
14358        });
14359        return true;
14360    }
14361    return swiper.slideTo(prevIndex, speed, runCallbacks, internal);
14362}
14363
14364/* eslint no-unused-vars: "off" */
14365function slideReset(speed, runCallbacks, internal) {
14366    if (runCallbacks === void 0) {
14367        runCallbacks = true;
14368    }
14369    const swiper = this;
14370    if (swiper.destroyed) return;
14371    if (typeof speed === 'undefined') {
14372        speed = swiper.params.speed;
14373    }
14374    return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
14375}
14376
14377/* eslint no-unused-vars: "off" */
14378function slideToClosest(speed, runCallbacks, internal, threshold) {
14379    if (runCallbacks === void 0) {
14380        runCallbacks = true;
14381    }
14382    if (threshold === void 0) {
14383        threshold = 0.5;
14384    }
14385    const swiper = this;
14386    if (swiper.destroyed) return;
14387    if (typeof speed === 'undefined') {
14388        speed = swiper.params.speed;
14389    }
14390    let index = swiper.activeIndex;
14391    const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
14392    const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
14393    const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
14394    if (translate >= swiper.snapGrid[snapIndex]) {
14395        // The current translate is on or after the current snap index, so the choice
14396        // is between the current index and the one after it.
14397        const currentSnap = swiper.snapGrid[snapIndex];
14398        const nextSnap = swiper.snapGrid[snapIndex + 1];
14399        if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {
14400            index += swiper.params.slidesPerGroup;
14401        }
14402    } else {
14403        // The current translate is before the current snap index, so the choice
14404        // is between the current index and the one before it.
14405        const prevSnap = swiper.snapGrid[snapIndex - 1];
14406        const currentSnap = swiper.snapGrid[snapIndex];
14407        if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) {
14408            index -= swiper.params.slidesPerGroup;
14409        }
14410    }
14411    index = Math.max(index, 0);
14412    index = Math.min(index, swiper.slidesGrid.length - 1);
14413    return swiper.slideTo(index, speed, runCallbacks, internal);
14414}
14415
14416function slideToClickedSlide() {
14417    const swiper = this;
14418    if (swiper.destroyed) return;
14419    const {
14420        params,
14421        slidesEl
14422    } = swiper;
14423    const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
14424    let slideToIndex = swiper.getSlideIndexWhenGrid(swiper.clickedIndex);
14425    let realIndex;
14426    const slideSelector = swiper.isElement ? `swiper-slide` : `.${params.slideClass}`;
14427    const isGrid = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
14428    if (params.loop) {
14429        if (swiper.animating) return;
14430        realIndex = parseInt(swiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
14431        if (params.centeredSlides) {
14432            swiper.slideToLoop(realIndex);
14433        } else if (slideToIndex > (isGrid ? (swiper.slides.length - slidesPerView) / 2 - (swiper.params.grid.rows - 1) : swiper.slides.length - slidesPerView)) {
14434            swiper.loopFix();
14435            slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
14436            nextTick(() => {
14437                swiper.slideTo(slideToIndex);
14438            });
14439        } else {
14440            swiper.slideTo(slideToIndex);
14441        }
14442    } else {
14443        swiper.slideTo(slideToIndex);
14444    }
14445}
14446
14447var slide = {
14448    slideTo,
14449    slideToLoop,
14450    slideNext,
14451    slidePrev,
14452    slideReset,
14453    slideToClosest,
14454    slideToClickedSlide
14455};
14456
14457function loopCreate(slideRealIndex, initial) {
14458    const swiper = this;
14459    const {
14460        params,
14461        slidesEl
14462    } = swiper;
14463    if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
14464    const initSlides = () => {
14465        const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
14466        slides.forEach((el, index) => {
14467            el.setAttribute('data-swiper-slide-index', index);
14468        });
14469    };
14470    const clearBlankSlides = () => {
14471        const slides = elementChildren(slidesEl, `.${params.slideBlankClass}`);
14472        slides.forEach(el => {
14473            el.remove();
14474        });
14475        if (slides.length > 0) {
14476            swiper.recalcSlides();
14477            swiper.updateSlides();
14478        }
14479    };
14480    const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
14481    if (params.loopAddBlankSlides && (params.slidesPerGroup > 1 || gridEnabled)) {
14482        clearBlankSlides();
14483    }
14484    const slidesPerGroup = params.slidesPerGroup * (gridEnabled ? params.grid.rows : 1);
14485    const shouldFillGroup = swiper.slides.length % slidesPerGroup !== 0;
14486    const shouldFillGrid = gridEnabled && swiper.slides.length % params.grid.rows !== 0;
14487    const addBlankSlides = amountOfSlides => {
14488        for (let i = 0; i < amountOfSlides; i += 1) {
14489            const slideEl = swiper.isElement ? createElement('swiper-slide', [params.slideBlankClass]) : createElement('div', [params.slideClass, params.slideBlankClass]);
14490            swiper.slidesEl.append(slideEl);
14491        }
14492    };
14493    if (shouldFillGroup) {
14494        if (params.loopAddBlankSlides) {
14495            const slidesToAdd = slidesPerGroup - swiper.slides.length % slidesPerGroup;
14496            addBlankSlides(slidesToAdd);
14497            swiper.recalcSlides();
14498            swiper.updateSlides();
14499        } else {
14500            showWarning('Swiper Loop Warning: The number of slides is not even to slidesPerGroup, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
14501        }
14502        initSlides();
14503    } else if (shouldFillGrid) {
14504        if (params.loopAddBlankSlides) {
14505            const slidesToAdd = params.grid.rows - swiper.slides.length % params.grid.rows;
14506            addBlankSlides(slidesToAdd);
14507            swiper.recalcSlides();
14508            swiper.updateSlides();
14509        } else {
14510            showWarning('Swiper Loop Warning: The number of slides is not even to grid.rows, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
14511        }
14512        initSlides();
14513    } else {
14514        initSlides();
14515    }
14516    swiper.loopFix({
14517        slideRealIndex,
14518        direction: params.centeredSlides ? undefined : 'next',
14519        initial
14520    });
14521}
14522
14523function loopFix(_temp) {
14524    let {
14525        slideRealIndex,
14526        slideTo = true,
14527        direction,
14528        setTranslate,
14529        activeSlideIndex,
14530        initial,
14531        byController,
14532        byMousewheel
14533    } = _temp === void 0 ? {} : _temp;
14534    const swiper = this;
14535    if (!swiper.params.loop) return;
14536    swiper.emit('beforeLoopFix');
14537    const {
14538        slides,
14539        allowSlidePrev,
14540        allowSlideNext,
14541        slidesEl,
14542        params
14543    } = swiper;
14544    const {
14545        centeredSlides,
14546        initialSlide
14547    } = params;
14548    swiper.allowSlidePrev = true;
14549    swiper.allowSlideNext = true;
14550    if (swiper.virtual && params.virtual.enabled) {
14551        if (slideTo) {
14552            if (!params.centeredSlides && swiper.snapIndex === 0) {
14553                swiper.slideTo(swiper.virtual.slides.length, 0, false, true);
14554            } else if (params.centeredSlides && swiper.snapIndex < params.slidesPerView) {
14555                swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true);
14556            } else if (swiper.snapIndex === swiper.snapGrid.length - 1) {
14557                swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true);
14558            }
14559        }
14560        swiper.allowSlidePrev = allowSlidePrev;
14561        swiper.allowSlideNext = allowSlideNext;
14562        swiper.emit('loopFix');
14563        return;
14564    }
14565    let slidesPerView = params.slidesPerView;
14566    if (slidesPerView === 'auto') {
14567        slidesPerView = swiper.slidesPerViewDynamic();
14568    } else {
14569        slidesPerView = Math.ceil(parseFloat(params.slidesPerView, 10));
14570        if (centeredSlides && slidesPerView % 2 === 0) {
14571            slidesPerView = slidesPerView + 1;
14572        }
14573    }
14574    const slidesPerGroup = params.slidesPerGroupAuto ? slidesPerView : params.slidesPerGroup;
14575    let loopedSlides = centeredSlides ? Math.max(slidesPerGroup, Math.ceil(slidesPerView / 2)) : slidesPerGroup;
14576    if (loopedSlides % slidesPerGroup !== 0) {
14577        loopedSlides += slidesPerGroup - loopedSlides % slidesPerGroup;
14578    }
14579    loopedSlides += params.loopAdditionalSlides;
14580    swiper.loopedSlides = loopedSlides;
14581    const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
14582    if (slides.length < slidesPerView + loopedSlides || swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
14583        showWarning('Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled or not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters');
14584    } else if (gridEnabled && params.grid.fill === 'row') {
14585        showWarning('Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`');
14586    }
14587    const prependSlidesIndexes = [];
14588    const appendSlidesIndexes = [];
14589    const cols = gridEnabled ? Math.ceil(slides.length / params.grid.rows) : slides.length;
14590    const isInitialOverflow = initial && cols - initialSlide < slidesPerView && !centeredSlides;
14591    let activeIndex = isInitialOverflow ? initialSlide : swiper.activeIndex;
14592    if (typeof activeSlideIndex === 'undefined') {
14593        activeSlideIndex = swiper.getSlideIndex(slides.find(el => el.classList.contains(params.slideActiveClass)));
14594    } else {
14595        activeIndex = activeSlideIndex;
14596    }
14597    const isNext = direction === 'next' || !direction;
14598    const isPrev = direction === 'prev' || !direction;
14599    let slidesPrepended = 0;
14600    let slidesAppended = 0;
14601    const activeColIndex = gridEnabled ? slides[activeSlideIndex].column : activeSlideIndex;
14602    const activeColIndexWithShift = activeColIndex + (centeredSlides && typeof setTranslate === 'undefined' ? -slidesPerView / 2 + 0.5 : 0);
14603    // prepend last slides before start
14604    if (activeColIndexWithShift < loopedSlides) {
14605        slidesPrepended = Math.max(loopedSlides - activeColIndexWithShift, slidesPerGroup);
14606        for (let i = 0; i < loopedSlides - activeColIndexWithShift; i += 1) {
vendor: 6,526 bytes, lines 14607-14750
14607            const index = i - Math.floor(i / cols) * cols;
14608            if (gridEnabled) {
14609                const colIndexToPrepend = cols - index - 1;
14610                for (let i = slides.length - 1; i >= 0; i -= 1) {
14611                    if (slides[i].column === colIndexToPrepend) prependSlidesIndexes.push(i);
14612                }
14613                // slides.forEach((slide, slideIndex) => {
14614                //   if (slide.column === colIndexToPrepend) prependSlidesIndexes.push(slideIndex);
14615                // });
14616            } else {
14617                prependSlidesIndexes.push(cols - index - 1);
14618            }
14619        }
14620    } else if (activeColIndexWithShift + slidesPerView > cols - loopedSlides) {
14621        slidesAppended = Math.max(activeColIndexWithShift - (cols - loopedSlides * 2), slidesPerGroup);
14622        if (isInitialOverflow) {
14623            slidesAppended = Math.max(slidesAppended, slidesPerView - cols + initialSlide + 1);
14624        }
14625        for (let i = 0; i < slidesAppended; i += 1) {
14626            const index = i - Math.floor(i / cols) * cols;
14627            if (gridEnabled) {
14628                slides.forEach((slide, slideIndex) => {
14629                    if (slide.column === index) appendSlidesIndexes.push(slideIndex);
14630                });
14631            } else {
14632                appendSlidesIndexes.push(index);
14633            }
14634        }
14635    }
14636    swiper.__preventObserver__ = true;
14637    requestAnimationFrame(() => {
14638        swiper.__preventObserver__ = false;
14639    });
14640    if (swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
14641        if (appendSlidesIndexes.includes(activeSlideIndex)) {
14642            appendSlidesIndexes.splice(appendSlidesIndexes.indexOf(activeSlideIndex), 1);
14643        }
14644        if (prependSlidesIndexes.includes(activeSlideIndex)) {
14645            prependSlidesIndexes.splice(prependSlidesIndexes.indexOf(activeSlideIndex), 1);
14646        }
14647    }
14648    if (isPrev) {
14649        prependSlidesIndexes.forEach(index => {
14650            slides[index].swiperLoopMoveDOM = true;
14651            slidesEl.prepend(slides[index]);
14652            slides[index].swiperLoopMoveDOM = false;
14653        });
14654    }
14655    if (isNext) {
14656        appendSlidesIndexes.forEach(index => {
14657            slides[index].swiperLoopMoveDOM = true;
14658            slidesEl.append(slides[index]);
14659            slides[index].swiperLoopMoveDOM = false;
14660        });
14661    }
14662    swiper.recalcSlides();
14663    if (params.slidesPerView === 'auto') {
14664        swiper.updateSlides();
14665    } else if (gridEnabled && (prependSlidesIndexes.length > 0 && isPrev || appendSlidesIndexes.length > 0 && isNext)) {
14666        swiper.slides.forEach((slide, slideIndex) => {
14667            swiper.grid.updateSlide(slideIndex, slide, swiper.slides);
14668        });
14669    }
14670    if (params.watchSlidesProgress) {
14671        swiper.updateSlidesOffset();
14672    }
14673    if (slideTo) {
14674        if (prependSlidesIndexes.length > 0 && isPrev) {
14675            if (typeof slideRealIndex === 'undefined') {
14676                const currentSlideTranslate = swiper.slidesGrid[activeIndex];
14677                const newSlideTranslate = swiper.slidesGrid[activeIndex + slidesPrepended];
14678                const diff = newSlideTranslate - currentSlideTranslate;
14679                if (byMousewheel) {
14680                    swiper.setTranslate(swiper.translate - diff);
14681                } else {
14682                    swiper.slideTo(activeIndex + Math.ceil(slidesPrepended), 0, false, true);
14683                    if (setTranslate) {
14684                        swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
14685                        swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
14686                    }
14687                }
14688            } else {
14689                if (setTranslate) {
14690                    const shift = gridEnabled ? prependSlidesIndexes.length / params.grid.rows : prependSlidesIndexes.length;
14691                    swiper.slideTo(swiper.activeIndex + shift, 0, false, true);
14692                    swiper.touchEventsData.currentTranslate = swiper.translate;
14693                }
14694            }
14695        } else if (appendSlidesIndexes.length > 0 && isNext) {
14696            if (typeof slideRealIndex === 'undefined') {
14697                const currentSlideTranslate = swiper.slidesGrid[activeIndex];
14698                const newSlideTranslate = swiper.slidesGrid[activeIndex - slidesAppended];
14699                const diff = newSlideTranslate - currentSlideTranslate;
14700                if (byMousewheel) {
14701                    swiper.setTranslate(swiper.translate - diff);
14702                } else {
14703                    swiper.slideTo(activeIndex - slidesAppended, 0, false, true);
14704                    if (setTranslate) {
14705                        swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff;
14706                        swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
14707                    }
14708                }
14709            } else {
14710                const shift = gridEnabled ? appendSlidesIndexes.length / params.grid.rows : appendSlidesIndexes.length;
14711                swiper.slideTo(swiper.activeIndex - shift, 0, false, true);
14712            }
14713        }
14714    }
14715    swiper.allowSlidePrev = allowSlidePrev;
14716    swiper.allowSlideNext = allowSlideNext;
14717    if (swiper.controller && swiper.controller.control && !byController) {
14718        const loopParams = {
14719            slideRealIndex,
14720            direction,
14721            setTranslate,
14722            activeSlideIndex,
14723            byController: true
14724        };
14725        if (Array.isArray(swiper.controller.control)) {
14726            swiper.controller.control.forEach(c => {
14727                if (!c.destroyed && c.params.loop) c.loopFix({
14728                    ...loopParams,
14729                    slideTo: c.params.slidesPerView === params.slidesPerView ? slideTo : false
14730                });
14731            });
14732        } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) {
14733            swiper.controller.control.loopFix({
14734                ...loopParams,
14735                slideTo: swiper.controller.control.params.slidesPerView === params.slidesPerView ? slideTo : false
14736            });
14737        }
14738    }
14739    swiper.emit('loopFix');
14740}
14741
14742function loopDestroy() {
14743    const swiper = this;
14744    const {
14745        params,
14746        slidesEl
14747    } = swiper;
14748    if (!params.loop || !slidesEl || swiper.virtual && swiper.params.virtual.enabled) return;
14749    swiper.recalcSlides();
14750    const newSlidesOrder = [];
vendor: 5,602 bytes, lines 14751-14920
14751    swiper.slides.forEach(slideEl => {
14752        const index = typeof slideEl.swiperSlideIndex === 'undefined' ? slideEl.getAttribute('data-swiper-slide-index') * 1 : slideEl.swiperSlideIndex;
14753        newSlidesOrder[index] = slideEl;
14754    });
14755    swiper.slides.forEach(slideEl => {
14756        slideEl.removeAttribute('data-swiper-slide-index');
14757    });
14758    newSlidesOrder.forEach(slideEl => {
14759        slidesEl.append(slideEl);
14760    });
14761    swiper.recalcSlides();
14762    swiper.slideTo(swiper.realIndex, 0);
14763}
14764
14765var loop = {
14766    loopCreate,
14767    loopFix,
14768    loopDestroy
14769};
14770
14771function setGrabCursor(moving) {
14772    const swiper = this;
14773    if (!swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return;
14774    const el = swiper.params.touchEventsTarget === 'container' ? swiper.el : swiper.wrapperEl;
14775    if (swiper.isElement) {
14776        swiper.__preventObserver__ = true;
14777    }
14778    el.style.cursor = 'move';
14779    el.style.cursor = moving ? 'grabbing' : 'grab';
14780    if (swiper.isElement) {
14781        requestAnimationFrame(() => {
14782            swiper.__preventObserver__ = false;
14783        });
14784    }
14785}
14786
14787function unsetGrabCursor() {
14788    const swiper = this;
14789    if (swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {
14790        return;
14791    }
14792    if (swiper.isElement) {
14793        swiper.__preventObserver__ = true;
14794    }
14795    swiper[swiper.params.touchEventsTarget === 'container' ? 'el' : 'wrapperEl'].style.cursor = '';
14796    if (swiper.isElement) {
14797        requestAnimationFrame(() => {
14798            swiper.__preventObserver__ = false;
14799        });
14800    }
14801}
14802
14803var grabCursor = {
14804    setGrabCursor,
14805    unsetGrabCursor
14806};
14807
14808// Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
14809function closestElement(selector, base) {
14810    if (base === void 0) {
14811        base = this;
14812    }
14813
14814    function __closestFrom(el) {
14815        if (!el || el === getDocument() || el === getWindow()) return null;
14816        if (el.assignedSlot) el = el.assignedSlot;
14817        const found = el.closest(selector);
14818        if (!found && !el.getRootNode) {
14819            return null;
14820        }
14821        return found || __closestFrom(el.getRootNode().host);
14822    }
14823
14824    return __closestFrom(base);
14825}
14826
14827function preventEdgeSwipe(swiper, event, startX) {
14828    const window = getWindow();
14829    const {
14830        params
14831    } = swiper;
14832    const edgeSwipeDetection = params.edgeSwipeDetection;
14833    const edgeSwipeThreshold = params.edgeSwipeThreshold;
14834    if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) {
14835        if (edgeSwipeDetection === 'prevent') {
14836            event.preventDefault();
14837            return true;
14838        }
14839        return false;
14840    }
14841    return true;
14842}
14843
14844function onTouchStart(event) {
14845    const swiper = this;
14846    const document = getDocument();
14847    let e = event;
14848    if (e.originalEvent) e = e.originalEvent;
14849    const data = swiper.touchEventsData;
14850    if (e.type === 'pointerdown') {
14851        if (data.pointerId !== null && data.pointerId !== e.pointerId) {
14852            return;
14853        }
14854        data.pointerId = e.pointerId;
14855    } else if (e.type === 'touchstart' && e.targetTouches.length === 1) {
14856        data.touchId = e.targetTouches[0].identifier;
14857    }
14858    if (e.type === 'touchstart') {
14859        // don't proceed touch event
14860        preventEdgeSwipe(swiper, e, e.targetTouches[0].pageX);
14861        return;
14862    }
14863    const {
14864        params,
14865        touches,
14866        enabled
14867    } = swiper;
14868    if (!enabled) return;
14869    if (!params.simulateTouch && e.pointerType === 'mouse') return;
14870    if (swiper.animating && params.preventInteractionOnTransition) {
14871        return;
14872    }
14873    if (!swiper.animating && params.cssMode && params.loop) {
14874        swiper.loopFix();
14875    }
14876    let targetEl = e.target;
14877    if (params.touchEventsTarget === 'wrapper') {
14878        if (!elementIsChildOf(targetEl, swiper.wrapperEl)) return;
14879    }
14880    if ('which' in e && e.which === 3) return;
14881    if ('button' in e && e.button > 0) return;
14882    if (data.isTouched && data.isMoved) return;
14883
14884    // change target el for shadow root component
14885    const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
14886    // eslint-disable-next-line
14887    const eventPath = e.composedPath ? e.composedPath() : e.path;
14888    if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) {
14889        targetEl = eventPath[0];
14890    }
14891    const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
14892    const isTargetShadow = !!(e.target && e.target.shadowRoot);
14893
14894    // use closestElement for shadow root element to get the actual closest for nested shadow root element
14895    if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))) {
14896        swiper.allowClick = true;
14897        return;
14898    }
14899    if (params.swipeHandler) {
14900        if (!targetEl.closest(params.swipeHandler)) return;
14901    }
14902    touches.currentX = e.pageX;
14903    touches.currentY = e.pageY;
14904    const startX = touches.currentX;
14905    const startY = touches.currentY;
14906
14907    // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
14908
14909    if (!preventEdgeSwipe(swiper, e, startX)) {
14910        return;
14911    }
14912    Object.assign(data, {
14913        isTouched: true,
14914        isMoved: false,
14915        allowTouchCallbacks: true,
14916        isScrolling: undefined,
14917        startMoving: undefined
14918    });
14919    touches.startX = startX;
14920    touches.startY = startY;
vendor: 18,270 bytes, lines 14921-15374
14921    data.touchStartTime = now();
14922    swiper.allowClick = true;
14923    swiper.updateSize();
14924    swiper.swipeDirection = undefined;
14925    if (params.threshold > 0) data.allowThresholdMove = false;
14926    let preventDefault = true;
14927    if (targetEl.matches(data.focusableElements)) {
14928        preventDefault = false;
14929        if (targetEl.nodeName === 'SELECT') {
14930            data.isTouched = false;
14931        }
14932    }
14933    if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== targetEl && (e.pointerType === 'mouse' || e.pointerType !== 'mouse' && !targetEl.matches(data.focusableElements))) {
14934        document.activeElement.blur();
14935    }
14936    const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
14937    if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) {
14938        e.preventDefault();
14939    }
14940    if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {
14941        swiper.freeMode.onTouchStart();
14942    }
14943    swiper.emit('touchStart', e);
14944}
14945
14946function onTouchMove(event) {
14947    const document = getDocument();
14948    const swiper = this;
14949    const data = swiper.touchEventsData;
14950    const {
14951        params,
14952        touches,
14953        rtlTranslate: rtl,
14954        enabled
14955    } = swiper;
14956    if (!enabled) return;
14957    if (!params.simulateTouch && event.pointerType === 'mouse') return;
14958    let e = event;
14959    if (e.originalEvent) e = e.originalEvent;
14960    if (e.type === 'pointermove') {
14961        if (data.touchId !== null) return; // return from pointer if we use touch
14962        const id = e.pointerId;
14963        if (id !== data.pointerId) return;
14964    }
14965    let targetTouch;
14966    if (e.type === 'touchmove') {
14967        targetTouch = [...e.changedTouches].find(t => t.identifier === data.touchId);
14968        if (!targetTouch || targetTouch.identifier !== data.touchId) return;
14969    } else {
14970        targetTouch = e;
14971    }
14972    if (!data.isTouched) {
14973        if (data.startMoving && data.isScrolling) {
14974            swiper.emit('touchMoveOpposite', e);
14975        }
14976        return;
14977    }
14978    const pageX = targetTouch.pageX;
14979    const pageY = targetTouch.pageY;
14980    if (e.preventedByNestedSwiper) {
14981        touches.startX = pageX;
14982        touches.startY = pageY;
14983        return;
14984    }
14985    if (!swiper.allowTouchMove) {
14986        if (!e.target.matches(data.focusableElements)) {
14987            swiper.allowClick = false;
14988        }
14989        if (data.isTouched) {
14990            Object.assign(touches, {
14991                startX: pageX,
14992                startY: pageY,
14993                currentX: pageX,
14994                currentY: pageY
14995            });
14996            data.touchStartTime = now();
14997        }
14998        return;
14999    }
15000    if (params.touchReleaseOnEdges && !params.loop) {
15001        if (swiper.isVertical()) {
15002            // Vertical
15003            if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {
15004                data.isTouched = false;
15005                data.isMoved = false;
15006                return;
15007            }
15008        } else if (rtl && (pageX > touches.startX && -swiper.translate <= swiper.maxTranslate() || pageX < touches.startX && -swiper.translate >= swiper.minTranslate())) {
15009            return;
15010        } else if (!rtl && (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate())) {
15011            return;
15012        }
15013    }
15014    if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== e.target && e.pointerType !== 'mouse') {
15015        document.activeElement.blur();
15016    }
15017    if (document.activeElement) {
15018        if (e.target === document.activeElement && e.target.matches(data.focusableElements)) {
15019            data.isMoved = true;
15020            swiper.allowClick = false;
15021            return;
15022        }
15023    }
15024    if (data.allowTouchCallbacks) {
15025        swiper.emit('touchMove', e);
15026    }
15027    touches.previousX = touches.currentX;
15028    touches.previousY = touches.currentY;
15029    touches.currentX = pageX;
15030    touches.currentY = pageY;
15031    const diffX = touches.currentX - touches.startX;
15032    const diffY = touches.currentY - touches.startY;
15033    if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return;
15034    if (typeof data.isScrolling === 'undefined') {
15035        let touchAngle;
15036        if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) {
15037            data.isScrolling = false;
15038        } else {
15039            // eslint-disable-next-line
15040            if (diffX * diffX + diffY * diffY >= 25) {
15041                touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
15042                data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle;
15043            }
15044        }
15045    }
15046    if (data.isScrolling) {
15047        swiper.emit('touchMoveOpposite', e);
15048    }
15049    if (typeof data.startMoving === 'undefined') {
15050        if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
15051            data.startMoving = true;
15052        }
15053    }
15054    if (data.isScrolling || e.type === 'touchmove' && data.preventTouchMoveFromPointerMove) {
15055        data.isTouched = false;
15056        return;
15057    }
15058    if (!data.startMoving) {
15059        return;
15060    }
15061    swiper.allowClick = false;
15062    if (!params.cssMode && e.cancelable) {
15063        e.preventDefault();
15064    }
15065    if (params.touchMoveStopPropagation && !params.nested) {
15066        e.stopPropagation();
15067    }
15068    let diff = swiper.isHorizontal() ? diffX : diffY;
15069    let touchesDiff = swiper.isHorizontal() ? touches.currentX - touches.previousX : touches.currentY - touches.previousY;
15070    if (params.oneWayMovement) {
15071        diff = Math.abs(diff) * (rtl ? 1 : -1);
15072        touchesDiff = Math.abs(touchesDiff) * (rtl ? 1 : -1);
15073    }
15074    touches.diff = diff;
15075    diff *= params.touchRatio;
15076    if (rtl) {
15077        diff = -diff;
15078        touchesDiff = -touchesDiff;
15079    }
15080    const prevTouchesDirection = swiper.touchesDirection;
15081    swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
15082    swiper.touchesDirection = touchesDiff > 0 ? 'prev' : 'next';
15083    const isLoop = swiper.params.loop && !params.cssMode;
15084    const allowLoopFix = swiper.touchesDirection === 'next' && swiper.allowSlideNext || swiper.touchesDirection === 'prev' && swiper.allowSlidePrev;
15085    if (!data.isMoved) {
15086        if (isLoop && allowLoopFix) {
15087            swiper.loopFix({
15088                direction: swiper.swipeDirection
15089            });
15090        }
15091        data.startTranslate = swiper.getTranslate();
15092        swiper.setTransition(0);
15093        if (swiper.animating) {
15094            const evt = new window.CustomEvent('transitionend', {
15095                bubbles: true,
15096                cancelable: true,
15097                detail: {
15098                    bySwiperTouchMove: true
15099                }
15100            });
15101            swiper.wrapperEl.dispatchEvent(evt);
15102        }
15103        data.allowMomentumBounce = false;
15104        // Grab Cursor
15105        if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
15106            swiper.setGrabCursor(true);
15107        }
15108        swiper.emit('sliderFirstMove', e);
15109    }
15110    new Date().getTime();
15111    if (params._loopSwapReset !== false && data.isMoved && data.allowThresholdMove && prevTouchesDirection !== swiper.touchesDirection && isLoop && allowLoopFix && Math.abs(diff) >= 1) {
15112        Object.assign(touches, {
15113            startX: pageX,
15114            startY: pageY,
15115            currentX: pageX,
15116            currentY: pageY,
15117            startTranslate: data.currentTranslate
15118        });
15119        data.loopSwapReset = true;
15120        data.startTranslate = data.currentTranslate;
15121        return;
15122    }
15123    swiper.emit('sliderMove', e);
15124    data.isMoved = true;
15125    data.currentTranslate = diff + data.startTranslate;
15126    let disableParentSwiper = true;
15127    let resistanceRatio = params.resistanceRatio;
15128    if (params.touchReleaseOnEdges) {
15129        resistanceRatio = 0;
15130    }
15131    if (diff > 0) {
15132        if (isLoop && allowLoopFix && true && data.allowThresholdMove && data.currentTranslate > (params.centeredSlides ? swiper.minTranslate() - swiper.slidesSizesGrid[swiper.activeIndex + 1] - (params.slidesPerView !== 'auto' && swiper.slides.length - params.slidesPerView >= 2 ? swiper.slidesSizesGrid[swiper.activeIndex + 1] + swiper.params.spaceBetween : 0) - swiper.params.spaceBetween : swiper.minTranslate())) {
15133            swiper.loopFix({
15134                direction: 'prev',
15135                setTranslate: true,
15136                activeSlideIndex: 0
15137            });
15138        }
15139        if (data.currentTranslate > swiper.minTranslate()) {
15140            disableParentSwiper = false;
15141            if (params.resistance) {
15142                data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio;
15143            }
15144        }
15145    } else if (diff < 0) {
15146        if (isLoop && allowLoopFix && true && data.allowThresholdMove && data.currentTranslate < (params.centeredSlides ? swiper.maxTranslate() + swiper.slidesSizesGrid[swiper.slidesSizesGrid.length - 1] + swiper.params.spaceBetween + (params.slidesPerView !== 'auto' && swiper.slides.length - params.slidesPerView >= 2 ? swiper.slidesSizesGrid[swiper.slidesSizesGrid.length - 1] + swiper.params.spaceBetween : 0) : swiper.maxTranslate())) {
15147            swiper.loopFix({
15148                direction: 'next',
15149                setTranslate: true,
15150                activeSlideIndex: swiper.slides.length - (params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10)))
15151            });
15152        }
15153        if (data.currentTranslate < swiper.maxTranslate()) {
15154            disableParentSwiper = false;
15155            if (params.resistance) {
15156                data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio;
15157            }
15158        }
15159    }
15160    if (disableParentSwiper) {
15161        e.preventedByNestedSwiper = true;
15162    }
15163
15164    // Directions locks
15165    if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
15166        data.currentTranslate = data.startTranslate;
15167    }
15168    if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
15169        data.currentTranslate = data.startTranslate;
15170    }
15171    if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
15172        data.currentTranslate = data.startTranslate;
15173    }
15174
15175    // Threshold
15176    if (params.threshold > 0) {
15177        if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
15178            if (!data.allowThresholdMove) {
15179                data.allowThresholdMove = true;
15180                touches.startX = touches.currentX;
15181                touches.startY = touches.currentY;
15182                data.currentTranslate = data.startTranslate;
15183                touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;
15184                return;
15185            }
15186        } else {
15187            data.currentTranslate = data.startTranslate;
15188            return;
15189        }
15190    }
15191    if (!params.followFinger || params.cssMode) return;
15192
15193    // Update active index in free mode
15194    if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {
15195        swiper.updateActiveIndex();
15196        swiper.updateSlidesClasses();
15197    }
15198    if (params.freeMode && params.freeMode.enabled && swiper.freeMode) {
15199        swiper.freeMode.onTouchMove();
15200    }
15201    // Update progress
15202    swiper.updateProgress(data.currentTranslate);
15203    // Update translate
15204    swiper.setTranslate(data.currentTranslate);
15205}
15206
15207function onTouchEnd(event) {
15208    const swiper = this;
15209    const data = swiper.touchEventsData;
15210    let e = event;
15211    if (e.originalEvent) e = e.originalEvent;
15212    let targetTouch;
15213    const isTouchEvent = e.type === 'touchend' || e.type === 'touchcancel';
15214    if (!isTouchEvent) {
15215        if (data.touchId !== null) return; // return from pointer if we use touch
15216        if (e.pointerId !== data.pointerId) return;
15217        targetTouch = e;
15218    } else {
15219        targetTouch = [...e.changedTouches].find(t => t.identifier === data.touchId);
15220        if (!targetTouch || targetTouch.identifier !== data.touchId) return;
15221    }
15222    if (['pointercancel', 'pointerout', 'pointerleave', 'contextmenu'].includes(e.type)) {
15223        const proceed = ['pointercancel', 'contextmenu'].includes(e.type) && (swiper.browser.isSafari || swiper.browser.isWebView);
15224        if (!proceed) {
15225            return;
15226        }
15227    }
15228    data.pointerId = null;
15229    data.touchId = null;
15230    const {
15231        params,
15232        touches,
15233        rtlTranslate: rtl,
15234        slidesGrid,
15235        enabled
15236    } = swiper;
15237    if (!enabled) return;
15238    if (!params.simulateTouch && e.pointerType === 'mouse') return;
15239    if (data.allowTouchCallbacks) {
15240        swiper.emit('touchEnd', e);
15241    }
15242    data.allowTouchCallbacks = false;
15243    if (!data.isTouched) {
15244        if (data.isMoved && params.grabCursor) {
15245            swiper.setGrabCursor(false);
15246        }
15247        data.isMoved = false;
15248        data.startMoving = false;
15249        return;
15250    }
15251
15252    // Return Grab Cursor
15253    if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
15254        swiper.setGrabCursor(false);
15255    }
15256
15257    // Time diff
15258    const touchEndTime = now();
15259    const timeDiff = touchEndTime - data.touchStartTime;
15260
15261    // Tap, doubleTap, Click
15262    if (swiper.allowClick) {
15263        const pathTree = e.path || e.composedPath && e.composedPath();
15264        swiper.updateClickedSlide(pathTree && pathTree[0] || e.target, pathTree);
15265        swiper.emit('tap click', e);
15266        if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {
15267            swiper.emit('doubleTap doubleClick', e);
15268        }
15269    }
15270    data.lastClickTime = now();
15271    nextTick(() => {
15272        if (!swiper.destroyed) swiper.allowClick = true;
15273    });
15274    if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 && !data.loopSwapReset || data.currentTranslate === data.startTranslate && !data.loopSwapReset) {
15275        data.isTouched = false;
15276        data.isMoved = false;
15277        data.startMoving = false;
15278        return;
15279    }
15280    data.isTouched = false;
15281    data.isMoved = false;
15282    data.startMoving = false;
15283    let currentPos;
15284    if (params.followFinger) {
15285        currentPos = rtl ? swiper.translate : -swiper.translate;
15286    } else {
15287        currentPos = -data.currentTranslate;
15288    }
15289    if (params.cssMode) {
15290        return;
15291    }
15292    if (params.freeMode && params.freeMode.enabled) {
15293        swiper.freeMode.onTouchEnd({
15294            currentPos
15295        });
15296        return;
15297    }
15298
15299    // Find current slide
15300    const swipeToLast = currentPos >= -swiper.maxTranslate() && !swiper.params.loop;
15301    let stopIndex = 0;
15302    let groupSize = swiper.slidesSizesGrid[0];
15303    for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {
15304        const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
15305        if (typeof slidesGrid[i + increment] !== 'undefined') {
15306            if (swipeToLast || currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {
15307                stopIndex = i;
15308                groupSize = slidesGrid[i + increment] - slidesGrid[i];
15309            }
15310        } else if (swipeToLast || currentPos >= slidesGrid[i]) {
15311            stopIndex = i;
15312            groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
15313        }
15314    }
15315    let rewindFirstIndex = null;
15316    let rewindLastIndex = null;
15317    if (params.rewind) {
15318        if (swiper.isBeginning) {
15319            rewindLastIndex = params.virtual && params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
15320        } else if (swiper.isEnd) {
15321            rewindFirstIndex = 0;
15322        }
15323    }
15324    // Find current slide size
15325    const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
15326    const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
15327    if (timeDiff > params.longSwipesMs) {
15328        // Long touches
15329        if (!params.longSwipes) {
15330            swiper.slideTo(swiper.activeIndex);
15331            return;
15332        }
15333        if (swiper.swipeDirection === 'next') {
15334            if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment); else swiper.slideTo(stopIndex);
15335        }
15336        if (swiper.swipeDirection === 'prev') {
15337            if (ratio > 1 - params.longSwipesRatio) {
15338                swiper.slideTo(stopIndex + increment);
15339            } else if (rewindLastIndex !== null && ratio < 0 && Math.abs(ratio) > params.longSwipesRatio) {
15340                swiper.slideTo(rewindLastIndex);
15341            } else {
15342                swiper.slideTo(stopIndex);
15343            }
15344        }
15345    } else {
15346        // Short swipes
15347        if (!params.shortSwipes) {
15348            swiper.slideTo(swiper.activeIndex);
15349            return;
15350        }
15351        const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl);
15352        if (!isNavButtonTarget) {
15353            if (swiper.swipeDirection === 'next') {
15354                swiper.slideTo(rewindFirstIndex !== null ? rewindFirstIndex : stopIndex + increment);
15355            }
15356            if (swiper.swipeDirection === 'prev') {
15357                swiper.slideTo(rewindLastIndex !== null ? rewindLastIndex : stopIndex);
15358            }
15359        } else if (e.target === swiper.navigation.nextEl) {
15360            swiper.slideTo(stopIndex + increment);
15361        } else {
15362            swiper.slideTo(stopIndex);
15363        }
15364    }
15365}
15366
15367function onResize() {
15368    const swiper = this;
15369    const {
15370        params,
15371        el
15372    } = swiper;
15373    if (el && el.offsetWidth === 0) return;
15374
vendor: 6,957 bytes, lines 15375-15601
15375    // Breakpoints
15376    if (params.breakpoints) {
15377        swiper.setBreakpoint();
15378    }
15379
15380    // Save locks
15381    const {
15382        allowSlideNext,
15383        allowSlidePrev,
15384        snapGrid
15385    } = swiper;
15386    const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
15387
15388    // Disable locks on resize
15389    swiper.allowSlideNext = true;
15390    swiper.allowSlidePrev = true;
15391    swiper.updateSize();
15392    swiper.updateSlides();
15393    swiper.updateSlidesClasses();
15394    const isVirtualLoop = isVirtual && params.loop;
15395    if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides && !isVirtualLoop) {
15396        swiper.slideTo(swiper.slides.length - 1, 0, false, true);
15397    } else {
15398        if (swiper.params.loop && !isVirtual) {
15399            swiper.slideToLoop(swiper.realIndex, 0, false, true);
15400        } else {
15401            swiper.slideTo(swiper.activeIndex, 0, false, true);
15402        }
15403    }
15404    if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
15405        clearTimeout(swiper.autoplay.resizeTimeout);
15406        swiper.autoplay.resizeTimeout = setTimeout(() => {
15407            if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
15408                swiper.autoplay.resume();
15409            }
15410        }, 500);
15411    }
15412    // Return locks after resize
15413    swiper.allowSlidePrev = allowSlidePrev;
15414    swiper.allowSlideNext = allowSlideNext;
15415    if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
15416        swiper.checkOverflow();
15417    }
15418}
15419
15420function onClick(e) {
15421    const swiper = this;
15422    if (!swiper.enabled) return;
15423    if (!swiper.allowClick) {
15424        if (swiper.params.preventClicks) e.preventDefault();
15425        if (swiper.params.preventClicksPropagation && swiper.animating) {
15426            e.stopPropagation();
15427            e.stopImmediatePropagation();
15428        }
15429    }
15430}
15431
15432function onScroll() {
15433    const swiper = this;
15434    const {
15435        wrapperEl,
15436        rtlTranslate,
15437        enabled
15438    } = swiper;
15439    if (!enabled) return;
15440    swiper.previousTranslate = swiper.translate;
15441    if (swiper.isHorizontal()) {
15442        swiper.translate = -wrapperEl.scrollLeft;
15443    } else {
15444        swiper.translate = -wrapperEl.scrollTop;
15445    }
15446    // eslint-disable-next-line
15447    if (swiper.translate === 0) swiper.translate = 0;
15448    swiper.updateActiveIndex();
15449    swiper.updateSlidesClasses();
15450    let newProgress;
15451    const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
15452    if (translatesDiff === 0) {
15453        newProgress = 0;
15454    } else {
15455        newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;
15456    }
15457    if (newProgress !== swiper.progress) {
15458        swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
15459    }
15460    swiper.emit('setTranslate', swiper.translate, false);
15461}
15462
15463function onLoad(e) {
15464    const swiper = this;
15465    processLazyPreloader(swiper, e.target);
15466    if (swiper.params.cssMode || swiper.params.slidesPerView !== 'auto' && !swiper.params.autoHeight) {
15467        return;
15468    }
15469    swiper.update();
15470}
15471
15472function onDocumentTouchStart() {
15473    const swiper = this;
15474    if (swiper.documentTouchHandlerProceeded) return;
15475    swiper.documentTouchHandlerProceeded = true;
15476    if (swiper.params.touchReleaseOnEdges) {
15477        swiper.el.style.touchAction = 'auto';
15478    }
15479}
15480
15481const events = (swiper, method) => {
15482    const document = getDocument();
15483    const {
15484        params,
15485        el,
15486        wrapperEl,
15487        device
15488    } = swiper;
15489    const capture = !!params.nested;
15490    const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
15491    const swiperMethod = method;
15492    if (!el || typeof el === 'string') return;
15493
15494    // Touch Events
15495    document[domMethod]('touchstart', swiper.onDocumentTouchStart, {
15496        passive: false,
15497        capture
15498    });
15499    el[domMethod]('touchstart', swiper.onTouchStart, {
15500        passive: false
15501    });
15502    el[domMethod]('pointerdown', swiper.onTouchStart, {
15503        passive: false
15504    });
15505    document[domMethod]('touchmove', swiper.onTouchMove, {
15506        passive: false,
15507        capture
15508    });
15509    document[domMethod]('pointermove', swiper.onTouchMove, {
15510        passive: false,
15511        capture
15512    });
15513    document[domMethod]('touchend', swiper.onTouchEnd, {
15514        passive: true
15515    });
15516    document[domMethod]('pointerup', swiper.onTouchEnd, {
15517        passive: true
15518    });
15519    document[domMethod]('pointercancel', swiper.onTouchEnd, {
15520        passive: true
15521    });
15522    document[domMethod]('touchcancel', swiper.onTouchEnd, {
15523        passive: true
15524    });
15525    document[domMethod]('pointerout', swiper.onTouchEnd, {
15526        passive: true
15527    });
15528    document[domMethod]('pointerleave', swiper.onTouchEnd, {
15529        passive: true
15530    });
15531    document[domMethod]('contextmenu', swiper.onTouchEnd, {
15532        passive: true
15533    });
15534
15535    // Prevent Links Clicks
15536    if (params.preventClicks || params.preventClicksPropagation) {
15537        el[domMethod]('click', swiper.onClick, true);
15538    }
15539    if (params.cssMode) {
15540        wrapperEl[domMethod]('scroll', swiper.onScroll);
15541    }
15542
15543    // Resize handler
15544    if (params.updateOnWindowResize) {
15545        swiper[swiperMethod](device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize, true);
15546    } else {
15547        swiper[swiperMethod]('observerUpdate', onResize, true);
15548    }
15549
15550    // Images loader
15551    el[domMethod]('load', swiper.onLoad, {
15552        capture: true
15553    });
15554};
15555
15556function attachEvents() {
15557    const swiper = this;
15558    const {
15559        params
15560    } = swiper;
15561    swiper.onTouchStart = onTouchStart.bind(swiper);
15562    swiper.onTouchMove = onTouchMove.bind(swiper);
15563    swiper.onTouchEnd = onTouchEnd.bind(swiper);
15564    swiper.onDocumentTouchStart = onDocumentTouchStart.bind(swiper);
15565    if (params.cssMode) {
15566        swiper.onScroll = onScroll.bind(swiper);
15567    }
15568    swiper.onClick = onClick.bind(swiper);
15569    swiper.onLoad = onLoad.bind(swiper);
15570    events(swiper, 'on');
15571}
15572
15573function detachEvents() {
15574    const swiper = this;
15575    events(swiper, 'off');
15576}
15577
15578var events$1 = {
15579    attachEvents,
15580    detachEvents
15581};
15582
15583const isGridEnabled = (swiper, params) => {
15584    return swiper.grid && params.grid && params.grid.rows > 1;
15585};
15586
15587function setBreakpoint() {
15588    const swiper = this;
15589    const {
15590        realIndex,
15591        initialized,
15592        params,
15593        el
15594    } = swiper;
15595    const breakpoints = params.breakpoints;
15596    if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return;
15597    const document = getDocument();
15598
15599    // Get breakpoint for window/container width and update parameters
15600    const breakpointsBase = params.breakpointsBase === 'window' || !params.breakpointsBase ? params.breakpointsBase : 'container';
15601    const breakpointContainer = ['window', 'container'].includes(params.breakpointsBase) || !params.breakpointsBase ? swiper.el : document.querySelector(params.breakpointsBase);
vendor: 4,514 bytes, lines 15602-15715
15602    const breakpoint = swiper.getBreakpoint(breakpoints, breakpointsBase, breakpointContainer);
15603    if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;
15604    const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
15605    const breakpointParams = breakpointOnlyParams || swiper.originalParams;
15606    const wasMultiRow = isGridEnabled(swiper, params);
15607    const isMultiRow = isGridEnabled(swiper, breakpointParams);
15608    const wasGrabCursor = swiper.params.grabCursor;
15609    const isGrabCursor = breakpointParams.grabCursor;
15610    const wasEnabled = params.enabled;
15611    if (wasMultiRow && !isMultiRow) {
15612        el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
15613        swiper.emitContainerClasses();
15614    } else if (!wasMultiRow && isMultiRow) {
15615        el.classList.add(`${params.containerModifierClass}grid`);
15616        if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') {
15617            el.classList.add(`${params.containerModifierClass}grid-column`);
15618        }
15619        swiper.emitContainerClasses();
15620    }
15621    if (wasGrabCursor && !isGrabCursor) {
15622        swiper.unsetGrabCursor();
15623    } else if (!wasGrabCursor && isGrabCursor) {
15624        swiper.setGrabCursor();
15625    }
15626
15627    // Toggle navigation, pagination, scrollbar
15628    ['navigation', 'pagination', 'scrollbar'].forEach(prop => {
15629        if (typeof breakpointParams[prop] === 'undefined') return;
15630        const wasModuleEnabled = params[prop] && params[prop].enabled;
15631        const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
15632        if (wasModuleEnabled && !isModuleEnabled) {
15633            swiper[prop].disable();
15634        }
15635        if (!wasModuleEnabled && isModuleEnabled) {
15636            swiper[prop].enable();
15637        }
15638    });
15639    const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
15640    const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
15641    const wasLoop = params.loop;
15642    if (directionChanged && initialized) {
15643        swiper.changeDirection();
15644    }
15645    extend(swiper.params, breakpointParams);
15646    const isEnabled = swiper.params.enabled;
15647    const hasLoop = swiper.params.loop;
15648    Object.assign(swiper, {
15649        allowTouchMove: swiper.params.allowTouchMove,
15650        allowSlideNext: swiper.params.allowSlideNext,
15651        allowSlidePrev: swiper.params.allowSlidePrev
15652    });
15653    if (wasEnabled && !isEnabled) {
15654        swiper.disable();
15655    } else if (!wasEnabled && isEnabled) {
15656        swiper.enable();
15657    }
15658    swiper.currentBreakpoint = breakpoint;
15659    swiper.emit('_beforeBreakpoint', breakpointParams);
15660    if (initialized) {
15661        if (needsReLoop) {
15662            swiper.loopDestroy();
15663            swiper.loopCreate(realIndex);
15664            swiper.updateSlides();
15665        } else if (!wasLoop && hasLoop) {
15666            swiper.loopCreate(realIndex);
15667            swiper.updateSlides();
15668        } else if (wasLoop && !hasLoop) {
15669            swiper.loopDestroy();
15670        }
15671    }
15672    swiper.emit('breakpoint', breakpointParams);
15673}
15674
15675function getBreakpoint(breakpoints, base, containerEl) {
15676    if (base === void 0) {
15677        base = 'window';
15678    }
15679    if (!breakpoints || base === 'container' && !containerEl) return undefined;
15680    let breakpoint = false;
15681    const window = getWindow();
15682    const currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight;
15683    const points = Object.keys(breakpoints).map(point => {
15684        if (typeof point === 'string' && point.indexOf('@') === 0) {
15685            const minRatio = parseFloat(point.substr(1));
15686            const value = currentHeight * minRatio;
15687            return {
15688                value,
15689                point
15690            };
15691        }
15692        return {
15693            value: point,
15694            point
15695        };
15696    });
15697    points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10));
15698    for (let i = 0; i < points.length; i += 1) {
15699        const {
15700            point,
15701            value
15702        } = points[i];
15703        if (base === 'window') {
15704            if (window.matchMedia(`(min-width: ${value}px)`).matches) {
15705                breakpoint = point;
15706            }
15707        } else if (value <= containerEl.clientWidth) {
15708            breakpoint = point;
15709        }
15710    }
15711    return breakpoint || 'max';
15712}
15713
15714var breakpoints = {
15715    setBreakpoint,
vendor: 3,707 bytes, lines 15716-15857
15716    getBreakpoint
15717};
15718
15719function prepareClasses(entries, prefix) {
15720    const resultClasses = [];
15721    entries.forEach(item => {
15722        if (typeof item === 'object') {
15723            Object.keys(item).forEach(classNames => {
15724                if (item[classNames]) {
15725                    resultClasses.push(prefix + classNames);
15726                }
15727            });
15728        } else if (typeof item === 'string') {
15729            resultClasses.push(prefix + item);
15730        }
15731    });
15732    return resultClasses;
15733}
15734
15735function addClasses() {
15736    const swiper = this;
15737    const {
15738        classNames,
15739        params,
15740        rtl,
15741        el,
15742        device
15743    } = swiper;
15744    // prettier-ignore
15745    const suffixes = prepareClasses(['initialized', params.direction, {
15746        'free-mode': swiper.params.freeMode && params.freeMode.enabled
15747    }, {
15748        'autoheight': params.autoHeight
15749    }, {
15750        'rtl': rtl
15751    }, {
15752        'grid': params.grid && params.grid.rows > 1
15753    }, {
15754        'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
15755    }, {
15756        'android': device.android
15757    }, {
15758        'ios': device.ios
15759    }, {
15760        'css-mode': params.cssMode
15761    }, {
15762        'centered': params.cssMode && params.centeredSlides
15763    }, {
15764        'watch-progress': params.watchSlidesProgress
15765    }], params.containerModifierClass);
15766    classNames.push(...suffixes);
15767    el.classList.add(...classNames);
15768    swiper.emitContainerClasses();
15769}
15770
15771function removeClasses() {
15772    const swiper = this;
15773    const {
15774        el,
15775        classNames
15776    } = swiper;
15777    if (!el || typeof el === 'string') return;
15778    el.classList.remove(...classNames);
15779    swiper.emitContainerClasses();
15780}
15781
15782var classes = {
15783    addClasses,
15784    removeClasses
15785};
15786
15787function checkOverflow() {
15788    const swiper = this;
15789    const {
15790        isLocked: wasLocked,
15791        params
15792    } = swiper;
15793    const {
15794        slidesOffsetBefore
15795    } = params;
15796    if (slidesOffsetBefore) {
15797        const lastSlideIndex = swiper.slides.length - 1;
15798        const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] + slidesOffsetBefore * 2;
15799        swiper.isLocked = swiper.size > lastSlideRightEdge;
15800    } else {
15801        swiper.isLocked = swiper.snapGrid.length === 1;
15802    }
15803    if (params.allowSlideNext === true) {
15804        swiper.allowSlideNext = !swiper.isLocked;
15805    }
15806    if (params.allowSlidePrev === true) {
15807        swiper.allowSlidePrev = !swiper.isLocked;
15808    }
15809    if (wasLocked && wasLocked !== swiper.isLocked) {
15810        swiper.isEnd = false;
15811    }
15812    if (wasLocked !== swiper.isLocked) {
15813        swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
15814    }
15815}
15816
15817var checkOverflow$1 = {
15818    checkOverflow
15819};
15820
15821var defaults = {
15822    init: true,
15823    direction: 'horizontal',
15824    oneWayMovement: false,
15825    swiperElementNodeName: 'SWIPER-CONTAINER',
15826    touchEventsTarget: 'wrapper',
15827    initialSlide: 0,
15828    speed: 300,
15829    cssMode: false,
15830    updateOnWindowResize: true,
15831    resizeObserver: true,
15832    nested: false,
15833    createElements: false,
15834    eventsPrefix: 'swiper',
15835    enabled: true,
15836    focusableElements: 'input, select, option, textarea, button, video, label',
15837    // Overrides
15838    width: null,
15839    height: null,
15840    //
15841    preventInteractionOnTransition: false,
15842    // ssr
15843    userAgent: null,
15844    url: null,
15845    // To support iOS's swipe-to-go-back gesture (when being used in-app).
15846    edgeSwipeDetection: false,
15847    edgeSwipeThreshold: 20,
15848    // Autoheight
15849    autoHeight: false,
15850    // Set wrapper width
15851    setWrapperSize: false,
15852    // Virtual Translate
15853    virtualTranslate: false,
15854    // Effects
15855    effect: 'slide',
15856    // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
15857
vendor: 4,284 bytes, lines 15858-16002
15858    // Breakpoints
15859    breakpoints: undefined,
15860    breakpointsBase: 'window',
15861    // Slides grid
15862    spaceBetween: 0,
15863    slidesPerView: 1,
15864    slidesPerGroup: 1,
15865    slidesPerGroupSkip: 0,
15866    slidesPerGroupAuto: false,
15867    centeredSlides: false,
15868    centeredSlidesBounds: false,
15869    slidesOffsetBefore: 0,
15870    // in px
15871    slidesOffsetAfter: 0,
15872    // in px
15873    normalizeSlideIndex: true,
15874    centerInsufficientSlides: false,
15875    // Disable swiper and hide navigation when container not overflow
15876    watchOverflow: true,
15877    // Round length
15878    roundLengths: false,
15879    // Touches
15880    touchRatio: 1,
15881    touchAngle: 45,
15882    simulateTouch: true,
15883    shortSwipes: true,
15884    longSwipes: true,
15885    longSwipesRatio: 0.5,
15886    longSwipesMs: 300,
15887    followFinger: true,
15888    allowTouchMove: true,
15889    threshold: 5,
15890    touchMoveStopPropagation: false,
15891    touchStartPreventDefault: true,
15892    touchStartForcePreventDefault: false,
15893    touchReleaseOnEdges: false,
15894    // Unique Navigation Elements
15895    uniqueNavElements: true,
15896    // Resistance
15897    resistance: true,
15898    resistanceRatio: 0.85,
15899    // Progress
15900    watchSlidesProgress: false,
15901    // Cursor
15902    grabCursor: false,
15903    // Clicks
15904    preventClicks: true,
15905    preventClicksPropagation: true,
15906    slideToClickedSlide: false,
15907    // loop
15908    loop: false,
15909    loopAddBlankSlides: true,
15910    loopAdditionalSlides: 0,
15911    loopPreventsSliding: true,
15912    // rewind
15913    rewind: false,
15914    // Swiping/no swiping
15915    allowSlidePrev: true,
15916    allowSlideNext: true,
15917    swipeHandler: null,
15918    // '.swipe-handler',
15919    noSwiping: true,
15920    noSwipingClass: 'swiper-no-swiping',
15921    noSwipingSelector: null,
15922    // Passive Listeners
15923    passiveListeners: true,
15924    maxBackfaceHiddenSlides: 10,
15925    // NS
15926    containerModifierClass: 'swiper-',
15927    // NEW
15928    slideClass: 'swiper-slide',
15929    slideBlankClass: 'swiper-slide-blank',
15930    slideActiveClass: 'swiper-slide-active',
15931    slideVisibleClass: 'swiper-slide-visible',
15932    slideFullyVisibleClass: 'swiper-slide-fully-visible',
15933    slideNextClass: 'swiper-slide-next',
15934    slidePrevClass: 'swiper-slide-prev',
15935    wrapperClass: 'swiper-wrapper',
15936    lazyPreloaderClass: 'swiper-lazy-preloader',
15937    lazyPreloadPrevNext: 0,
15938    // Callbacks
15939    runCallbacksOnInit: true,
15940    // Internals
15941    _emitClasses: false
15942};
15943
15944function moduleExtendParams(params, allModulesParams) {
15945    return function extendParams(obj) {
15946        if (obj === void 0) {
15947            obj = {};
15948        }
15949        const moduleParamName = Object.keys(obj)[0];
15950        const moduleParams = obj[moduleParamName];
15951        if (typeof moduleParams !== 'object' || moduleParams === null) {
15952            extend(allModulesParams, obj);
15953            return;
15954        }
15955        if (params[moduleParamName] === true) {
15956            params[moduleParamName] = {
15957                enabled: true
15958            };
15959        }
15960        if (moduleParamName === 'navigation' && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].prevEl && !params[moduleParamName].nextEl) {
15961            params[moduleParamName].auto = true;
15962        }
15963        if (['pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].el) {
15964            params[moduleParamName].auto = true;
15965        }
15966        if (!(moduleParamName in params && 'enabled' in moduleParams)) {
15967            extend(allModulesParams, obj);
15968            return;
15969        }
15970        if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {
15971            params[moduleParamName].enabled = true;
15972        }
15973        if (!params[moduleParamName]) params[moduleParamName] = {
15974            enabled: false
15975        };
15976        extend(allModulesParams, obj);
15977    };
15978}
15979
15980/* eslint no-param-reassign: "off" */
15981const prototypes = {
15982    eventsEmitter,
15983    update,
15984    translate,
15985    transition,
15986    slide,
15987    loop,
15988    grabCursor,
15989    events: events$1,
15990    breakpoints,
15991    checkOverflow: checkOverflow$1,
15992    classes
15993};
15994const extendedDefaults = {};
15995
15996class Swiper {
15997    constructor() {
15998        let el;
15999        let params;
16000        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
16001            args[_key] = arguments[_key];
16002        }
vendor: 2,238 bytes, lines 16003-16060
16003        if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') {
16004            params = args[0];
16005        } else {
16006            [el, params] = args;
16007        }
16008        if (!params) params = {};
16009        params = extend({}, params);
16010        if (el && !params.el) params.el = el;
16011        const document = getDocument();
16012        if (params.el && typeof params.el === 'string' && document.querySelectorAll(params.el).length > 1) {
16013            const swipers = [];
16014            document.querySelectorAll(params.el).forEach(containerEl => {
16015                const newParams = extend({}, params, {
16016                    el: containerEl
16017                });
16018                swipers.push(new Swiper(newParams));
16019            });
16020            // eslint-disable-next-line no-constructor-return
16021            return swipers;
16022        }
16023
16024        // Swiper Instance
16025        const swiper = this;
16026        swiper.__swiper__ = true;
16027        swiper.support = getSupport();
16028        swiper.device = getDevice({
16029            userAgent: params.userAgent
16030        });
16031        swiper.browser = getBrowser();
16032        swiper.eventsListeners = {};
16033        swiper.eventsAnyListeners = [];
16034        swiper.modules = [...swiper.__modules__];
16035        if (params.modules && Array.isArray(params.modules)) {
16036            swiper.modules.push(...params.modules);
16037        }
16038        const allModulesParams = {};
16039        swiper.modules.forEach(mod => {
16040            mod({
16041                params,
16042                swiper,
16043                extendParams: moduleExtendParams(params, allModulesParams),
16044                on: swiper.on.bind(swiper),
16045                once: swiper.once.bind(swiper),
16046                off: swiper.off.bind(swiper),
16047                emit: swiper.emit.bind(swiper)
16048            });
16049        });
16050
16051        // Extend defaults with modules params
16052        const swiperParams = extend({}, defaults, allModulesParams);
16053
16054        // Extend defaults with passed params
16055        swiper.params = extend({}, swiperParams, extendedDefaults, params);
16056        swiper.originalParams = extend({}, swiper.params);
16057        swiper.passedParams = extend({}, params);
16058
16059        // add event listeners
16060        if (swiper.params && swiper.params.on) {
vendor: 6,389 bytes, lines 16061-16258
16061            Object.keys(swiper.params.on).forEach(eventName => {
16062                swiper.on(eventName, swiper.params.on[eventName]);
16063            });
16064        }
16065        if (swiper.params && swiper.params.onAny) {
16066            swiper.onAny(swiper.params.onAny);
16067        }
16068
16069        // Extend Swiper
16070        Object.assign(swiper, {
16071            enabled: swiper.params.enabled,
16072            el,
16073            // Classes
16074            classNames: [],
16075            // Slides
16076            slides: [],
16077            slidesGrid: [],
16078            snapGrid: [],
16079            slidesSizesGrid: [],
16080            // isDirection
16081            isHorizontal() {
16082                return swiper.params.direction === 'horizontal';
16083            },
16084            isVertical() {
16085                return swiper.params.direction === 'vertical';
16086            },
16087            // Indexes
16088            activeIndex: 0,
16089            realIndex: 0,
16090            //
16091            isBeginning: true,
16092            isEnd: false,
16093            // Props
16094            translate: 0,
16095            previousTranslate: 0,
16096            progress: 0,
16097            velocity: 0,
16098            animating: false,
16099            cssOverflowAdjustment() {
16100                // Returns 0 unless `translate` is > 2**23
16101                // Should be subtracted from css values to prevent overflow
16102                return Math.trunc(this.translate / 2 ** 23) * 2 ** 23;
16103            },
16104            // Locks
16105            allowSlideNext: swiper.params.allowSlideNext,
16106            allowSlidePrev: swiper.params.allowSlidePrev,
16107            // Touch Events
16108            touchEventsData: {
16109                isTouched: undefined,
16110                isMoved: undefined,
16111                allowTouchCallbacks: undefined,
16112                touchStartTime: undefined,
16113                isScrolling: undefined,
16114                currentTranslate: undefined,
16115                startTranslate: undefined,
16116                allowThresholdMove: undefined,
16117                // Form elements to match
16118                focusableElements: swiper.params.focusableElements,
16119                // Last click time
16120                lastClickTime: 0,
16121                clickTimeout: undefined,
16122                // Velocities
16123                velocities: [],
16124                allowMomentumBounce: undefined,
16125                startMoving: undefined,
16126                pointerId: null,
16127                touchId: null
16128            },
16129            // Clicks
16130            allowClick: true,
16131            // Touches
16132            allowTouchMove: swiper.params.allowTouchMove,
16133            touches: {
16134                startX: 0,
16135                startY: 0,
16136                currentX: 0,
16137                currentY: 0,
16138                diff: 0
16139            },
16140            // Images
16141            imagesToLoad: [],
16142            imagesLoaded: 0
16143        });
16144        swiper.emit('_swiper');
16145
16146        // Init
16147        if (swiper.params.init) {
16148            swiper.init();
16149        }
16150
16151        // Return app instance
16152        // eslint-disable-next-line no-constructor-return
16153        return swiper;
16154    }
16155
16156    getDirectionLabel(property) {
16157        if (this.isHorizontal()) {
16158            return property;
16159        }
16160        // prettier-ignore
16161        return {
16162            'width': 'height',
16163            'margin-top': 'margin-left',
16164            'margin-bottom ': 'margin-right',
16165            'margin-left': 'margin-top',
16166            'margin-right': 'margin-bottom',
16167            'padding-left': 'padding-top',
16168            'padding-right': 'padding-bottom',
16169            'marginRight': 'marginBottom'
16170        }[property];
16171    }
16172
16173    getSlideIndex(slideEl) {
16174        const {
16175            slidesEl,
16176            params
16177        } = this;
16178        const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
16179        const firstSlideIndex = elementIndex(slides[0]);
16180        return elementIndex(slideEl) - firstSlideIndex;
16181    }
16182
16183    getSlideIndexByData(index) {
16184        return this.getSlideIndex(this.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === index));
16185    }
16186
16187    getSlideIndexWhenGrid(index) {
16188        if (this.grid && this.params.grid && this.params.grid.rows > 1) {
16189            if (this.params.grid.fill === 'column') {
16190                index = Math.floor(index / this.params.grid.rows);
16191            } else if (this.params.grid.fill === 'row') {
16192                index = index % Math.ceil(this.slides.length / this.params.grid.rows);
16193            }
16194        }
16195        return index;
16196    }
16197
16198    recalcSlides() {
16199        const swiper = this;
16200        const {
16201            slidesEl,
16202            params
16203        } = swiper;
16204        swiper.slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
16205    }
16206
16207    enable() {
16208        const swiper = this;
16209        if (swiper.enabled) return;
16210        swiper.enabled = true;
16211        if (swiper.params.grabCursor) {
16212            swiper.setGrabCursor();
16213        }
16214        swiper.emit('enable');
16215    }
16216
16217    disable() {
16218        const swiper = this;
16219        if (!swiper.enabled) return;
16220        swiper.enabled = false;
16221        if (swiper.params.grabCursor) {
16222            swiper.unsetGrabCursor();
16223        }
16224        swiper.emit('disable');
16225    }
16226
16227    setProgress(progress, speed) {
16228        const swiper = this;
16229        progress = Math.min(Math.max(progress, 0), 1);
16230        const min = swiper.minTranslate();
16231        const max = swiper.maxTranslate();
16232        const current = (max - min) * progress + min;
16233        swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
16234        swiper.updateActiveIndex();
16235        swiper.updateSlidesClasses();
16236    }
16237
16238    emitContainerClasses() {
16239        const swiper = this;
16240        if (!swiper.params._emitClasses || !swiper.el) return;
16241        const cls = swiper.el.className.split(' ').filter(className => {
16242            return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0;
16243        });
16244        swiper.emit('_containerClasses', cls.join(' '));
16245    }
16246
16247    getSlideClasses(slideEl) {
16248        const swiper = this;
16249        if (swiper.destroyed) return '';
16250        return slideEl.className.split(' ').filter(className => {
16251            return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0;
16252        }).join(' ');
16253    }
16254
16255    emitSlidesClasses() {
16256        const swiper = this;
16257        if (!swiper.params._emitClasses || !swiper.el) return;
16258        const updates = [];
vendor: 2,605 bytes, lines 16259-16333
16259        swiper.slides.forEach(slideEl => {
16260            const classNames = swiper.getSlideClasses(slideEl);
16261            updates.push({
16262                slideEl,
16263                classNames
16264            });
16265            swiper.emit('_slideClass', slideEl, classNames);
16266        });
16267        swiper.emit('_slideClasses', updates);
16268    }
16269
16270    slidesPerViewDynamic(view, exact) {
16271        if (view === void 0) {
16272            view = 'current';
16273        }
16274        if (exact === void 0) {
16275            exact = false;
16276        }
16277        const swiper = this;
16278        const {
16279            params,
16280            slides,
16281            slidesGrid,
16282            slidesSizesGrid,
16283            size: swiperSize,
16284            activeIndex
16285        } = swiper;
16286        let spv = 1;
16287        if (typeof params.slidesPerView === 'number') return params.slidesPerView;
16288        if (params.centeredSlides) {
16289            let slideSize = slides[activeIndex] ? Math.ceil(slides[activeIndex].swiperSlideSize) : 0;
16290            let breakLoop;
16291            for (let i = activeIndex + 1; i < slides.length; i += 1) {
16292                if (slides[i] && !breakLoop) {
16293                    slideSize += Math.ceil(slides[i].swiperSlideSize);
16294                    spv += 1;
16295                    if (slideSize > swiperSize) breakLoop = true;
16296                }
16297            }
16298            for (let i = activeIndex - 1; i >= 0; i -= 1) {
16299                if (slides[i] && !breakLoop) {
16300                    slideSize += slides[i].swiperSlideSize;
16301                    spv += 1;
16302                    if (slideSize > swiperSize) breakLoop = true;
16303                }
16304            }
16305        } else {
16306            // eslint-disable-next-line
16307            if (view === 'current') {
16308                for (let i = activeIndex + 1; i < slides.length; i += 1) {
16309                    const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
16310                    if (slideInView) {
16311                        spv += 1;
16312                    }
16313                }
16314            } else {
16315                // previous
16316                for (let i = activeIndex - 1; i >= 0; i -= 1) {
16317                    const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
16318                    if (slideInView) {
16319                        spv += 1;
16320                    }
16321                }
16322            }
16323        }
16324        return spv;
16325    }
16326
16327    update() {
16328        const swiper = this;
16329        if (!swiper || swiper.destroyed) return;
16330        const {
16331            snapGrid,
16332            params
16333        } = swiper;
vendor: 2,540 bytes, lines 16334-16395
16334        // Breakpoints
16335        if (params.breakpoints) {
16336            swiper.setBreakpoint();
16337        }
16338        [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach(imageEl => {
16339            if (imageEl.complete) {
16340                processLazyPreloader(swiper, imageEl);
16341            }
16342        });
16343        swiper.updateSize();
16344        swiper.updateSlides();
16345        swiper.updateProgress();
16346        swiper.updateSlidesClasses();
16347
16348        function setTranslate() {
16349            const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
16350            const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
16351            swiper.setTranslate(newTranslate);
16352            swiper.updateActiveIndex();
16353            swiper.updateSlidesClasses();
16354        }
16355
16356        let translated;
16357        if (params.freeMode && params.freeMode.enabled && !params.cssMode) {
16358            setTranslate();
16359            if (params.autoHeight) {
16360                swiper.updateAutoHeight();
16361            }
16362        } else {
16363            if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
16364                const slides = swiper.virtual && params.virtual.enabled ? swiper.virtual.slides : swiper.slides;
16365                translated = swiper.slideTo(slides.length - 1, 0, false, true);
16366            } else {
16367                translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
16368            }
16369            if (!translated) {
16370                setTranslate();
16371            }
16372        }
16373        if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
16374            swiper.checkOverflow();
16375        }
16376        swiper.emit('update');
16377    }
16378
16379    changeDirection(newDirection, needUpdate) {
16380        if (needUpdate === void 0) {
16381            needUpdate = true;
16382        }
16383        const swiper = this;
16384        const currentDirection = swiper.params.direction;
16385        if (!newDirection) {
16386            // eslint-disable-next-line
16387            newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
16388        }
16389        if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
16390            return swiper;
16391        }
16392        swiper.el.classList.remove(`${swiper.params.containerModifierClass}${currentDirection}`);
16393        swiper.el.classList.add(`${swiper.params.containerModifierClass}${newDirection}`);
16394        swiper.emitContainerClasses();
16395        swiper.params.direction = newDirection;
vendor: 2,253 bytes, lines 16396-16455
16396        swiper.slides.forEach(slideEl => {
16397            if (newDirection === 'vertical') {
16398                slideEl.style.width = '';
16399            } else {
16400                slideEl.style.height = '';
16401            }
16402        });
16403        swiper.emit('changeDirection');
16404        if (needUpdate) swiper.update();
16405        return swiper;
16406    }
16407
16408    changeLanguageDirection(direction) {
16409        const swiper = this;
16410        if (swiper.rtl && direction === 'rtl' || !swiper.rtl && direction === 'ltr') return;
16411        swiper.rtl = direction === 'rtl';
16412        swiper.rtlTranslate = swiper.params.direction === 'horizontal' && swiper.rtl;
16413        if (swiper.rtl) {
16414            swiper.el.classList.add(`${swiper.params.containerModifierClass}rtl`);
16415            swiper.el.dir = 'rtl';
16416        } else {
16417            swiper.el.classList.remove(`${swiper.params.containerModifierClass}rtl`);
16418            swiper.el.dir = 'ltr';
16419        }
16420        swiper.update();
16421    }
16422
16423    mount(element) {
16424        const swiper = this;
16425        if (swiper.mounted) return true;
16426
16427        // Find el
16428        let el = element || swiper.params.el;
16429        if (typeof el === 'string') {
16430            el = document.querySelector(el);
16431        }
16432        if (!el) {
16433            return false;
16434        }
16435        el.swiper = swiper;
16436        if (el.parentNode && el.parentNode.host && el.parentNode.host.nodeName === swiper.params.swiperElementNodeName.toUpperCase()) {
16437            swiper.isElement = true;
16438        }
16439        const getWrapperSelector = () => {
16440            return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`;
16441        };
16442        const getWrapper = () => {
16443            if (el && el.shadowRoot && el.shadowRoot.querySelector) {
16444                const res = el.shadowRoot.querySelector(getWrapperSelector());
16445                // Children needs to return slot items
16446                return res;
16447            }
16448            return elementChildren(el, getWrapperSelector())[0];
16449        };
16450        // Find Wrapper
16451        let wrapperEl = getWrapper();
16452        if (!wrapperEl && swiper.params.createElements) {
16453            wrapperEl = createElement('div', swiper.params.wrapperClass);
16454            el.append(wrapperEl);
16455            elementChildren(el, `.${swiper.params.slideClass}
16455`).forEach(slideEl => {
16456                wrapperEl.append(slideEl);
16457            });
16458        }
16459        Object.assign(swiper, {
16460            el,
16461            wrapperEl,
16462            slidesEl: swiper.isElement && !el.parentNode.host.slideSlots ? el.parentNode.host : wrapperEl,
16463            hostEl: swiper.isElement ? el.parentNode.host : el,
16464            mounted: true,
16465            // RTL
16466            rtl: el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl',
16467            rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl'),
16468            wrongRTL: elementStyle(wrapperEl, 'display') === '-webkit-box'
16469        });
16470        return true;
16471    }
16472
16473    init(el) {
16474        const swiper = this;
16475        if (swiper.initialized) return swiper;
16476        const mounted = swiper.mount(el);
16477        if (mounted === false) return swiper;
16478        swiper.emit('beforeInit');
16479
16480        // Set breakpoint
16481        if (swiper.params.breakpoints) {
16482            swiper.setBreakpoint();
16483        }
16484
16485        // Add Classes
16486        swiper.addClasses();
16487
16488        // Update size
16489        swiper.updateSize();
16490
16491        // Update slides
16492        swiper.updateSlides();
16493        if (swiper.params.watchOverflow) {
16494            swiper.checkOverflow();
16495        }
16496
16497        // Set Grab Cursor
16498        if (swiper.params.grabCursor && swiper.enabled) {
16499            swiper.setGrabCursor();
16500        }
16501
16502        // Slide To Initial Slide
16503        if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
16504            swiper.slideTo(swiper.params.initialSlide + swiper.virtual.slidesBefore, 0, swiper.params.runCallbacksOnInit, false, true);
16505        } else {
16506            swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
16507        }
16508
16509        // Create loop
16510        if (swiper.params.loop) {
16511            swiper.loopCreate(undefined, true);
16512        }
16513
16514        // Attach events
16515        swiper.attachEvents();
16516        const lazyElements = [...swiper.el.querySelectorAll('[loading="lazy"]')];
16517        if (swiper.isElement) {
16518            lazyElements.push(...swiper.hostEl.querySelectorAll('[loading="lazy"]'));
16519        }
16520        lazyElements.forEach(imageEl => {
16521            if (imageEl.complete) {
16522                processLazyPreloader(swiper, imageEl);
16523            } else {
16524                imageEl.addEventListener('load', e => {
16525                    processLazyPreloader(swiper, e.target);
16526                });
16527            }
16528        });
16529        preload(swiper);
16530
16531        // Init Flag
16532        swiper.initialized = true;
16533        preload(swiper);
16534
16535        // Emit
16536        swiper.emit('init');
16537        swiper.emit('afterInit');
16538        return swiper;
16539    }
16540
16541    destroy(deleteInstance, cleanStyles) {
16542        if (deleteInstance === void 0) {
16543            deleteInstance = true;
16544        }
16545        if (cleanStyles === void 0) {
16546            cleanStyles = true;
16547        }
16548        const swiper = this;
16549        const {
16550            params,
16551            el,
16552            wrapperEl,
16553            slides
16554        } = swiper;
16555        if (typeof swiper.params === 'undefined' || swiper.destroyed) {
16556            return null;
16557        }
16558        swiper.emit('beforeDestroy');
16559
16560        // Init Flag
16561        swiper.initialized = false;
16562
16563        // Detach events
16564        swiper.detachEvents();
16565
16566        // Destroy loop
16567        if (params.loop) {
16568            swiper.loopDestroy();
16569        }
16570
16571        // Cleanup styles
16572        if (cleanStyles) {
16573            swiper.removeClasses();
16574            if (el && typeof el !== 'string') {
16575                el.removeAttribute('style');
16576            }
16577            if (wrapperEl) {
16578                wrapperEl.removeAttribute('style');
16579            }
16580            if (slides && slides.length) {
vendor: 6,074 bytes, lines 16581-16768
16581                slides.forEach(slideEl => {
16582                    slideEl.classList.remove(params.slideVisibleClass, params.slideFullyVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
16583                    slideEl.removeAttribute('style');
16584                    slideEl.removeAttribute('data-swiper-slide-index');
16585                });
16586            }
16587        }
16588        swiper.emit('destroy');
16589
16590        // Detach emitter events
16591        Object.keys(swiper.eventsListeners).forEach(eventName => {
16592            swiper.off(eventName);
16593        });
16594        if (deleteInstance !== false) {
16595            if (swiper.el && typeof swiper.el !== 'string') {
16596                swiper.el.swiper = null;
16597            }
16598            deleteProps(swiper);
16599        }
16600        swiper.destroyed = true;
16601        return null;
16602    }
16603
16604    static extendDefaults(newDefaults) {
16605        extend(extendedDefaults, newDefaults);
16606    }
16607
16608    static get extendedDefaults() {
16609        return extendedDefaults;
16610    }
16611
16612    static get defaults() {
16613        return defaults;
16614    }
16615
16616    static installModule(mod) {
16617        if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];
16618        const modules = Swiper.prototype.__modules__;
16619        if (typeof mod === 'function' && modules.indexOf(mod) < 0) {
16620            modules.push(mod);
16621        }
16622    }
16623
16624    static use(module) {
16625        if (Array.isArray(module)) {
16626            module.forEach(m => Swiper.installModule(m));
16627            return Swiper;
16628        }
16629        Swiper.installModule(module);
16630        return Swiper;
16631    }
16632}
16633
16634Object.keys(prototypes).forEach(prototypeGroup => {
16635    Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => {
16636        Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
16637    });
16638});
16639Swiper.use([Resize, Observer]);
16640
16641function Virtual(_ref) {
16642    let {
16643        swiper,
16644        extendParams,
16645        on,
16646        emit
16647    } = _ref;
16648    extendParams({
16649        virtual: {
16650            enabled: false,
16651            slides: [],
16652            cache: true,
16653            renderSlide: null,
16654            renderExternal: null,
16655            renderExternalUpdate: true,
16656            addSlidesBefore: 0,
16657            addSlidesAfter: 0
16658        }
16659    });
16660    let cssModeTimeout;
16661    const document = getDocument();
16662    swiper.virtual = {
16663        cache: {},
16664        from: undefined,
16665        to: undefined,
16666        slides: [],
16667        offset: 0,
16668        slidesGrid: []
16669    };
16670    const tempDOM = document.createElement('div');
16671
16672    function renderSlide(slide, index) {
16673        const params = swiper.params.virtual;
16674        if (params.cache && swiper.virtual.cache[index]) {
16675            return swiper.virtual.cache[index];
16676        }
16677        // eslint-disable-next-line
16678        let slideEl;
16679        if (params.renderSlide) {
16680            slideEl = params.renderSlide.call(swiper, slide, index);
16681            if (typeof slideEl === 'string') {
16682                setInnerHTML(tempDOM, slideEl);
16683                slideEl = tempDOM.children[0];
16684            }
16685        } else if (swiper.isElement) {
16686            slideEl = createElement('swiper-slide');
16687        } else {
16688            slideEl = createElement('div', swiper.params.slideClass);
16689        }
16690        slideEl.setAttribute('data-swiper-slide-index', index);
16691        if (!params.renderSlide) {
16692            setInnerHTML(slideEl, slide);
16693        }
16694        if (params.cache) {
16695            swiper.virtual.cache[index] = slideEl;
16696        }
16697        return slideEl;
16698    }
16699
16700    function update(force, beforeInit, forceActiveIndex) {
16701        const {
16702            slidesPerView,
16703            slidesPerGroup,
16704            centeredSlides,
16705            loop: isLoop,
16706            initialSlide
16707        } = swiper.params;
16708        if (beforeInit && !isLoop && initialSlide > 0) {
16709            return;
16710        }
16711        const {
16712            addSlidesBefore,
16713            addSlidesAfter
16714        } = swiper.params.virtual;
16715        const {
16716            from: previousFrom,
16717            to: previousTo,
16718            slides,
16719            slidesGrid: previousSlidesGrid,
16720            offset: previousOffset
16721        } = swiper.virtual;
16722        if (!swiper.params.cssMode) {
16723            swiper.updateActiveIndex();
16724        }
16725        const activeIndex = typeof forceActiveIndex === 'undefined' ? swiper.activeIndex || 0 : forceActiveIndex;
16726        let offsetProp;
16727        if (swiper.rtlTranslate) offsetProp = 'right'; else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
16728        let slidesAfter;
16729        let slidesBefore;
16730        if (centeredSlides) {
16731            slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;
16732            slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;
16733        } else {
16734            slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;
16735            slidesBefore = (isLoop ? slidesPerView : slidesPerGroup) + addSlidesBefore;
16736        }
16737        let from = activeIndex - slidesBefore;
16738        let to = activeIndex + slidesAfter;
16739        if (!isLoop) {
16740            from = Math.max(from, 0);
16741            to = Math.min(to, slides.length - 1);
16742        }
16743        let offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
16744        if (isLoop && activeIndex >= slidesBefore) {
16745            from -= slidesBefore;
16746            if (!centeredSlides) offset += swiper.slidesGrid[0];
16747        } else if (isLoop && activeIndex < slidesBefore) {
16748            from = -slidesBefore;
16749            if (centeredSlides) offset += swiper.slidesGrid[0];
16750        }
16751        Object.assign(swiper.virtual, {
16752            from,
16753            to,
16754            offset,
16755            slidesGrid: swiper.slidesGrid,
16756            slidesBefore,
16757            slidesAfter
16758        });
16759
16760        function onRendered() {
16761            swiper.updateSlides();
16762            swiper.updateProgress();
16763            swiper.updateSlidesClasses();
16764            emit('virtualUpdate');
16765        }
16766
16767        if (previousFrom === from && previousTo === to && !force) {
16768            if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
vendor: 1,518 bytes, lines 16769-16810
16769                swiper.slides.forEach(slideEl => {
16770                    slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
16771                });
16772            }
16773            swiper.updateProgress();
16774            emit('virtualUpdate');
16775            return;
16776        }
16777        if (swiper.params.virtual.renderExternal) {
16778            swiper.params.virtual.renderExternal.call(swiper, {
16779                offset,
16780                from,
16781                to,
16782                slides: function getSlides() {
16783                    const slidesToRender = [];
16784                    for (let i = from; i <= to; i += 1) {
16785                        slidesToRender.push(slides[i]);
16786                    }
16787                    return slidesToRender;
16788                }()
16789            });
16790            if (swiper.params.virtual.renderExternalUpdate) {
16791                onRendered();
16792            } else {
16793                emit('virtualUpdate');
16794            }
16795            return;
16796        }
16797        const prependIndexes = [];
16798        const appendIndexes = [];
16799        const getSlideIndex = index => {
16800            let slideIndex = index;
16801            if (index < 0) {
16802                slideIndex = slides.length + index;
16803            } else if (slideIndex >= slides.length) {
16804                // eslint-disable-next-line
16805                slideIndex = slideIndex - slides.length;
16806            }
16807            return slideIndex;
16808        };
16809        if (force) {
16810            swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}
16810, swiper-slide`)).forEach(slideEl => {
16811                slideEl.remove();
16812            });
16813        } else {
16814            for (let i = previousFrom; i <= previousTo; i += 1) {
16815                if (i < from || i > to) {
16816                    const slideIndex = getSlideIndex(i);
16817                    swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}[data-swiper-slide-index="${slideIndex}"], swiper-slide[data-swiper-slide-index="${slideIndex}"]`)).forEach(slideEl => {
16818                        slideEl.remove();
16819                    });
16820                }
16821            }
16822        }
16823        const loopFrom = isLoop ? -slides.length : 0;
16824        const loopTo = isLoop ? slides.length * 2 : slides.length;
16825        for (let i = loopFrom; i < loopTo; i += 1) {
16826            if (i >= from && i <= to) {
16827                const slideIndex = getSlideIndex(i);
16828                if (typeof previousTo === 'undefined' || force) {
16829                    appendIndexes.push(slideIndex);
16830                } else {
16831                    if (i > previousTo) appendIndexes.push(slideIndex);
16832                    if (i < previousFrom) prependIndexes.push(slideIndex);
16833                }
16834            }
16835        }
16836        appendIndexes.forEach(index => {
16837            swiper.slidesEl.append(renderSlide(slides[index], index));
16838        });
16839        if (isLoop) {
16840            for (let i = prependIndexes.length - 1; i >= 0; i -= 1) {
16841                const index = prependIndexes[i];
16842                swiper.slidesEl.prepend(renderSlide(slides[index], index));
16843            }
16844        } else {
16845            prependIndexes.sort((a, b) => b - a);
16846            prependIndexes.forEach(index => {
16847                swiper.slidesEl.prepend(renderSlide(slides[index], index));
16848            });
16849        }
16850        elementChildren(swiper.slidesEl, '.swiper-slide, swiper-slide').forEach(sli
vendor: 4,348 bytes, lines 16850-16953
16850deEl => {
16851            slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
16852        });
16853        onRendered();
16854    }
16855
16856    function appendSlide(slides) {
16857        if (typeof slides === 'object' && 'length' in slides) {
16858            for (let i = 0; i < slides.length; i += 1) {
16859                if (slides[i]) swiper.virtual.slides.push(slides[i]);
16860            }
16861        } else {
16862            swiper.virtual.slides.push(slides);
16863        }
16864        update(true);
16865    }
16866
16867    function prependSlide(slides) {
16868        const activeIndex = swiper.activeIndex;
16869        let newActiveIndex = activeIndex + 1;
16870        let numberOfNewSlides = 1;
16871        if (Array.isArray(slides)) {
16872            for (let i = 0; i < slides.length; i += 1) {
16873                if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
16874            }
16875            newActiveIndex = activeIndex + slides.length;
16876            numberOfNewSlides = slides.length;
16877        } else {
16878            swiper.virtual.slides.unshift(slides);
16879        }
16880        if (swiper.params.virtual.cache) {
16881            const cache = swiper.virtual.cache;
16882            const newCache = {};
16883            Object.keys(cache).forEach(cachedIndex => {
16884                const cachedEl = cache[cachedIndex];
16885                const cachedElIndex = cachedEl.getAttribute('data-swiper-slide-index');
16886                if (cachedElIndex) {
16887                    cachedEl.setAttribute('data-swiper-slide-index', parseInt(cachedElIndex, 10) + numberOfNewSlides);
16888                }
16889                newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cachedEl;
16890            });
16891            swiper.virtual.cache = newCache;
16892        }
16893        update(true);
16894        swiper.slideTo(newActiveIndex, 0);
16895    }
16896
16897    function removeSlide(slidesIndexes) {
16898        if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
16899        let activeIndex = swiper.activeIndex;
16900        if (Array.isArray(slidesIndexes)) {
16901            for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {
16902                if (swiper.params.virtual.cache) {
16903                    delete swiper.virtual.cache[slidesIndexes[i]];
16904                    // shift cache indexes
16905                    Object.keys(swiper.virtual.cache).forEach(key => {
16906                        if (key > slidesIndexes) {
16907                            swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
16908                            swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
16909                            delete swiper.virtual.cache[key];
16910                        }
16911                    });
16912                }
16913                swiper.virtual.slides.splice(slidesIndexes[i], 1);
16914                if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
16915                activeIndex = Math.max(activeIndex, 0);
16916            }
16917        } else {
16918            if (swiper.params.virtual.cache) {
16919                delete swiper.virtual.cache[slidesIndexes];
16920                // shift cache indexes
16921                Object.keys(swiper.virtual.cache).forEach(key => {
16922                    if (key > slidesIndexes) {
16923                        swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
16924                        swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
16925                        delete swiper.virtual.cache[key];
16926                    }
16927                });
16928            }
16929            swiper.virtual.slides.splice(slidesIndexes, 1);
16930            if (slidesIndexes < activeIndex) activeIndex -= 1;
16931            activeIndex = Math.max(activeIndex, 0);
16932        }
16933        update(true);
16934        swiper.slideTo(activeIndex, 0);
16935    }
16936
16937    function removeAllSlides() {
16938        swiper.virtual.slides = [];
16939        if (swiper.params.virtual.cache) {
16940            swiper.virtual.cache = {};
16941        }
16942        update(true);
16943        swiper.slideTo(0, 0);
16944    }
16945
16946    on('beforeInit', () => {
16947        if (!swiper.params.virtual.enabled) return;
16948        let domSlidesAssigned;
16949        if (typeof swiper.passedParams.virtual.slides === 'undefined') {
16950            const slides = [...swiper.slidesEl.children].filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`));
16951            if (slides && slides.length) {
16952                swiper.virtual.slides = [...slides];
16953                domSlidesAssigned = true;
vendor: 4,809 bytes, lines 16954-17069
16954                slides.forEach((slideEl, slideIndex) => {
16955                    slideEl.setAttribute('data-swiper-slide-index', slideIndex);
16956                    swiper.virtual.cache[slideIndex] = slideEl;
16957                    slideEl.remove();
16958                });
16959            }
16960        }
16961        if (!domSlidesAssigned) {
16962            swiper.virtual.slides = swiper.params.virtual.slides;
16963        }
16964        swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
16965        swiper.params.watchSlidesProgress = true;
16966        swiper.originalParams.watchSlidesProgress = true;
16967        update(false, true);
16968    });
16969    on('setTranslate', () => {
16970        if (!swiper.params.virtual.enabled) return;
16971        if (swiper.params.cssMode && !swiper._immediateVirtual) {
16972            clearTimeout(cssModeTimeout);
16973            cssModeTimeout = setTimeout(() => {
16974                update();
16975            }, 100);
16976        } else {
16977            update();
16978        }
16979    });
16980    on('init update resize', () => {
16981        if (!swiper.params.virtual.enabled) return;
16982        if (swiper.params.cssMode) {
16983            setCSSProperty(swiper.wrapperEl, '--swiper-virtual-size', `${swiper.virtualSize}px`);
16984        }
16985    });
16986    Object.assign(swiper.virtual, {
16987        appendSlide,
16988        prependSlide,
16989        removeSlide,
16990        removeAllSlides,
16991        update
16992    });
16993}
16994
16995/* eslint-disable consistent-return */
16996function Keyboard(_ref) {
16997    let {
16998        swiper,
16999        extendParams,
17000        on,
17001        emit
17002    } = _ref;
17003    const document = getDocument();
17004    const window = getWindow();
17005    swiper.keyboard = {
17006        enabled: false
17007    };
17008    extendParams({
17009        keyboard: {
17010            enabled: false,
17011            onlyInViewport: true,
17012            pageUpDown: true
17013        }
17014    });
17015
17016    function handle(event) {
17017        if (!swiper.enabled) return;
17018        const {
17019            rtlTranslate: rtl
17020        } = swiper;
17021        let e = event;
17022        if (e.originalEvent) e = e.originalEvent; // jquery fix
17023        const kc = e.keyCode || e.charCode;
17024        const pageUpDown = swiper.params.keyboard.pageUpDown;
17025        const isPageUp = pageUpDown && kc === 33;
17026        const isPageDown = pageUpDown && kc === 34;
17027        const isArrowLeft = kc === 37;
17028        const isArrowRight = kc === 39;
17029        const isArrowUp = kc === 38;
17030        const isArrowDown = kc === 40;
17031        // Directions locks
17032        if (!swiper.allowSlideNext && (swiper.isHorizontal() && isArrowRight || swiper.isVertical() && isArrowDown || isPageDown)) {
17033            return false;
17034        }
17035        if (!swiper.allowSlidePrev && (swiper.isHorizontal() && isArrowLeft || swiper.isVertical() && isArrowUp || isPageUp)) {
17036            return false;
17037        }
17038        if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
17039            return undefined;
17040        }
17041        if (document.activeElement && (document.activeElement.isContentEditable || document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea'))) {
17042            return undefined;
17043        }
17044        if (swiper.params.keyboard.onlyInViewport && (isPageUp || isPageDown || isArrowLeft || isArrowRight || isArrowUp || isArrowDown)) {
17045            let inView = false;
17046            // Check that swiper should be inside of visible area of window
17047            if (elementParents(swiper.el, `.${swiper.params.slideClass}, swiper-slide`).length > 0 && elementParents(swiper.el, `.${swiper.params.slideActiveClass}`).length === 0) {
17048                return undefined;
17049            }
17050            const el = swiper.el;
17051            const swiperWidth = el.clientWidth;
17052            const swiperHeight = el.clientHeight;
17053            const windowWidth = window.innerWidth;
17054            const windowHeight = window.innerHeight;
17055            const swiperOffset = elementOffset(el);
17056            if (rtl) swiperOffset.left -= el.scrollLeft;
17057            const swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiperWidth, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiperHeight], [swiperOffset.left + swiperWidth, swiperOffset.top + swiperHeight]];
17058            for (let i = 0; i < swiperCoord.length; i += 1) {
17059                const point = swiperCoord[i];
17060                if (point[0] >= 0 && point[0] <= windowWidth && point[1] >= 0 && point[1] <= windowHeight) {
17061                    if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line
17062                    inView = true;
17063                }
17064            }
17065            if (!inView) return undefined;
17066        }
17067        if (swiper.isHorizontal()) {
17068            if (isPageUp || isPageDown || isArrowLeft || isArrowRight) {
17069                if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
17070            }
17071            if ((isPageDown || isArrowRight) && !rtl || (isPageUp || isArrowLeft) && rtl) swiper.slideNext();
17072            if ((isPageUp || isArrowLeft) && !rtl || (isPageDown || isArrowRight) && rtl) swiper.slidePrev();
17073        } else {
17074            if (isPageUp || isPageDown || isArrowUp || isArrowDown) {
17075                if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
17076            }
17077            if (isPageDown || isArrowDown) swiper.slideNext();
17078            if (isPageUp || isArrowUp) swiper.slidePrev();
17079        }
17080        emit('keyPress', kc);
17081        return undefined;
17082    }
17083
17084    function enable() {
17085        if (swiper.keyboard.enabled) return;
17086        document.addEventListener('keydown', handle);
17087        swiper.keyboard.enabled = true;
17088    }
17089
17090    function disable() {
17091        if (!swiper.keyboard.enabled) return;
17092        document.removeEventListener('keydown', handle);
17093        swiper.keyboard.enabled = false;
17094    }
17095
17096    on('init', () => {
17097        if (swiper.params.keyboard.enabled) {
17098            enable();
17099        }
17100    });
17101    on('destroy', () => {
17102        if (swiper.keyboard.enabled) {
17103            disable();
17104        }
17105    });
17106    Object.assign(swiper.keyboard, {
17107        enable,
17108        disable
17109    });
17110}
17111
17112/* eslint-disable consistent-return */
17113function Mousewheel(_ref) {
17114    let {
17115        swiper,
17116        extendParams,
17117        on,
17118        emit
17119    } = _ref;
17120    const window = getWindow();
17121    extendParams({
17122        mousewheel: {
17123            enabled: false,
17124            releaseOnEdges: false,
17125            invert: false,
vendor: 19,989 bytes, lines 17126-17615
17126            forceToAxis: false,
17127            sensitivity: 1,
17128            eventsTarget: 'container',
17129            thresholdDelta: null,
17130            thresholdTime: null,
17131            noMousewheelClass: 'swiper-no-mousewheel'
17132        }
17133    });
17134    swiper.mousewheel = {
17135        enabled: false
17136    };
17137    let timeout;
17138    let lastScrollTime = now();
17139    let lastEventBeforeSnap;
17140    const recentWheelEvents = [];
17141
17142    function normalize(e) {
17143        // Reasonable defaults
17144        const PIXEL_STEP = 10;
17145        const LINE_HEIGHT = 40;
17146        const PAGE_HEIGHT = 800;
17147        let sX = 0;
17148        let sY = 0; // spinX, spinY
17149        let pX = 0;
17150        let pY = 0; // pixelX, pixelY
17151
17152        // Legacy
17153        if ('detail' in e) {
17154            sY = e.detail;
17155        }
17156        if ('wheelDelta' in e) {
17157            sY = -e.wheelDelta / 120;
17158        }
17159        if ('wheelDeltaY' in e) {
17160            sY = -e.wheelDeltaY / 120;
17161        }
17162        if ('wheelDeltaX' in e) {
17163            sX = -e.wheelDeltaX / 120;
17164        }
17165
17166        // side scrolling on FF with DOMMouseScroll
17167        if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {
17168            sX = sY;
17169            sY = 0;
17170        }
17171        pX = sX * PIXEL_STEP;
17172        pY = sY * PIXEL_STEP;
17173        if ('deltaY' in e) {
17174            pY = e.deltaY;
17175        }
17176        if ('deltaX' in e) {
17177            pX = e.deltaX;
17178        }
17179        if (e.shiftKey && !pX) {
17180            // if user scrolls with shift he wants horizontal scroll
17181            pX = pY;
17182            pY = 0;
17183        }
17184        if ((pX || pY) && e.deltaMode) {
17185            if (e.deltaMode === 1) {
17186                // delta in LINE units
17187                pX *= LINE_HEIGHT;
17188                pY *= LINE_HEIGHT;
17189            } else {
17190                // delta in PAGE units
17191                pX *= PAGE_HEIGHT;
17192                pY *= PAGE_HEIGHT;
17193            }
17194        }
17195
17196        // Fall-back if spin cannot be determined
17197        if (pX && !sX) {
17198            sX = pX < 1 ? -1 : 1;
17199        }
17200        if (pY && !sY) {
17201            sY = pY < 1 ? -1 : 1;
17202        }
17203        return {
17204            spinX: sX,
17205            spinY: sY,
17206            pixelX: pX,
17207            pixelY: pY
17208        };
17209    }
17210
17211    function handleMouseEnter() {
17212        if (!swiper.enabled) return;
17213        swiper.mouseEntered = true;
17214    }
17215
17216    function handleMouseLeave() {
17217        if (!swiper.enabled) return;
17218        swiper.mouseEntered = false;
17219    }
17220
17221    function animateSlider(newEvent) {
17222        if (swiper.params.mousewheel.thresholdDelta && newEvent.delta < swiper.params.mousewheel.thresholdDelta) {
17223            // Prevent if delta of wheel scroll delta is below configured threshold
17224            return false;
17225        }
17226        if (swiper.params.mousewheel.thresholdTime && now() - lastScrollTime < swiper.params.mousewheel.thresholdTime) {
17227            // Prevent if time between scrolls is below configured threshold
17228            return false;
17229        }
17230
17231        // If the movement is NOT big enough and
17232        // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider):
17233        //   Don't go any further (avoid insignificant scroll movement).
17234        if (newEvent.delta >= 6 && now() - lastScrollTime < 60) {
17235            // Return false as a default
17236            return true;
17237        }
17238        // If user is scrolling towards the end:
17239        //   If the slider hasn't hit the latest slide or
17240        //   if the slider is a loop and
17241        //   if the slider isn't moving right now:
17242        //     Go to next slide and
17243        //     emit a scroll event.
17244        // Else (the user is scrolling towards the beginning) and
17245        // if the slider hasn't hit the first slide or
17246        // if the slider is a loop and
17247        // if the slider isn't moving right now:
17248        //   Go to prev slide and
17249        //   emit a scroll event.
17250        if (newEvent.direction < 0) {
17251            if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {
17252                swiper.slideNext();
17253                emit('scroll', newEvent.raw);
17254            }
17255        } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {
17256            swiper.slidePrev();
17257            emit('scroll', newEvent.raw);
17258        }
17259        // If you got here is because an animation has been triggered so store the current time
17260        lastScrollTime = new window.Date().getTime();
17261        // Return false as a default
17262        return false;
17263    }
17264
17265    function releaseScroll(newEvent) {
17266        const params = swiper.params.mousewheel;
17267        if (newEvent.direction < 0) {
17268            if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) {
17269                // Return true to animate scroll on edges
17270                return true;
17271            }
17272        } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) {
17273            // Return true to animate scroll on edges
17274            return true;
17275        }
17276        return false;
17277    }
17278
17279    function handle(event) {
17280        let e = event;
17281        let disableParentSwiper = true;
17282        if (!swiper.enabled) return;
17283
17284        // Ignore event if the target or its parents have the swiper-no-mousewheel class
17285        if (event.target.closest(`.${swiper.params.mousewheel.noMousewheelClass}`)) return;
17286        const params = swiper.params.mousewheel;
17287        if (swiper.params.cssMode) {
17288            e.preventDefault();
17289        }
17290        let targetEl = swiper.el;
17291        if (swiper.params.mousewheel.eventsTarget !== 'container') {
17292            targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
17293        }
17294        const targetElContainsTarget = targetEl && targetEl.contains(e.target);
17295        if (!swiper.mouseEntered && !targetElContainsTarget && !params.releaseOnEdges) return true;
17296        if (e.originalEvent) e = e.originalEvent; // jquery fix
17297        let delta = 0;
17298        const rtlFactor = swiper.rtlTranslate ? -1 : 1;
17299        const data = normalize(e);
17300        if (params.forceToAxis) {
17301            if (swiper.isHorizontal()) {
17302                if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = -data.pixelX * rtlFactor; else return true;
17303            } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = -data.pixelY; else return true;
17304        } else {
17305            delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;
17306        }
17307        if (delta === 0) return true;
17308        if (params.invert) delta = -delta;
17309
17310        // Get the scroll positions
17311        let positions = swiper.getTranslate() + delta * params.sensitivity;
17312        if (positions >= swiper.minTranslate()) positions = swiper.minTranslate();
17313        if (positions <= swiper.maxTranslate()) positions = swiper.maxTranslate();
17314
17315        // When loop is true:
17316        //     the disableParentSwiper will be true.
17317        // When loop is false:
17318        //     if the scroll positions is not on edge,
17319        //     then the disableParentSwiper will be true.
17320        //     if the scroll on edge positions,
17321        //     then the disableParentSwiper will be false.
17322        disableParentSwiper = swiper.params.loop ? true : !(positions === swiper.minTranslate() || positions === swiper.maxTranslate());
17323        if (disableParentSwiper && swiper.params.nested) e.stopPropagation();
17324        if (!swiper.params.freeMode || !swiper.params.freeMode.enabled) {
17325            // Register the new event in a variable which stores the relevant data
17326            const newEvent = {
17327                time: now(),
17328                delta: Math.abs(delta),
17329                direction: Math.sign(delta),
17330                raw: event
17331            };
17332
17333            // Keep the most recent events
17334            if (recentWheelEvents.length >= 2) {
17335                recentWheelEvents.shift(); // only store the last N events
17336            }
17337
17338            const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
17339            recentWheelEvents.push(newEvent);
17340
17341            // If there is at least one previous recorded event:
17342            //   If direction has changed or
17343            //   if the scroll is quicker than the previous one:
17344            //     Animate the slider.
17345            // Else (this is the first time the wheel is moved):
17346            //     Animate the slider.
17347            if (prevEvent) {
17348                if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) {
17349                    animateSlider(newEvent);
17350                }
17351            } else {
17352                animateSlider(newEvent);
17353            }
17354
17355            // If it's time to release the scroll:
17356            //   Return now so you don't hit the preventDefault.
17357            if (releaseScroll(newEvent)) {
17358                return true;
17359            }
17360        } else {
17361            // Freemode or scrollContainer:
17362
17363            // If we recently snapped after a momentum scroll, then ignore wheel events
17364            // to give time for the deceleration to finish. Stop ignoring after 500 msecs
17365            // or if it's a new scroll (larger delta or inverse sign as last event before
17366            // an end-of-momentum snap).
17367            const newEvent = {
17368                time: now(),
17369                delta: Math.abs(delta),
17370                direction: Math.sign(delta)
17371            };
17372            const ignoreWheelEvents = lastEventBeforeSnap && newEvent.time < lastEventBeforeSnap.time + 500 && newEvent.delta <= lastEventBeforeSnap.delta && newEvent.direction === lastEventBeforeSnap.direction;
17373            if (!ignoreWheelEvents) {
17374                lastEventBeforeSnap = undefined;
17375                let position = swiper.getTranslate() + delta * params.sensitivity;
17376                const wasBeginning = swiper.isBeginning;
17377                const wasEnd = swiper.isEnd;
17378                if (position >= swiper.minTranslate()) position = swiper.minTranslate();
17379                if (position <= swiper.maxTranslate()) position = swiper.maxTranslate();
17380                swiper.setTransition(0);
17381                swiper.setTranslate(position);
17382                swiper.updateProgress();
17383                swiper.updateActiveIndex();
17384                swiper.updateSlidesClasses();
17385                if (!wasBeginning && swiper.isBeginning || !wasEnd && swiper.isEnd) {
17386                    swiper.updateSlidesClasses();
17387                }
17388                if (swiper.params.loop) {
17389                    swiper.loopFix({
17390                        direction: newEvent.direction < 0 ? 'next' : 'prev',
17391                        byMousewheel: true
17392                    });
17393                }
17394                if (swiper.params.freeMode.sticky) {
17395                    // When wheel scrolling starts with sticky (aka snap) enabled, then detect
17396                    // the end of a momentum scroll by storing recent (N=15?) wheel events.
17397                    // 1. do all N events have decreasing or same (absolute value) delta?
17398                    // 2. did all N events arrive in the last M (M=500?) msecs?
17399                    // 3. does the earliest event have an (absolute value) delta that's
17400                    //    at least P (P=1?) larger than the most recent event's delta?
17401                    // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels?
17402                    // If 1-4 are "yes" then we're near the end of a momentum scroll deceleration.
17403                    // Snap immediately and ignore remaining wheel events in this scroll.
17404                    // See comment above for "remaining wheel events in this scroll" determination.
17405                    // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event.
17406                    clearTimeout(timeout);
17407                    timeout = undefined;
17408                    if (recentWheelEvents.length >= 15) {
17409                        recentWheelEvents.shift(); // only store the last N events
17410                    }
17411
17412                    const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined;
17413                    const firstEvent = recentWheelEvents[0];
17414                    recentWheelEvents.push(newEvent);
17415                    if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) {
17416                        // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log.
17417                        recentWheelEvents.splice(0);
17418                    } else if (recentWheelEvents.length >= 15 && newEvent.time - firstEvent.time < 500 && firstEvent.delta - newEvent.delta >= 1 && newEvent.delta <= 6) {
17419                        // We're at the end of the deceleration of a momentum scroll, so there's no need
17420                        // to wait for more events. Snap ASAP on the next tick.
17421                        // Also, because there's some remaining momentum we'll bias the snap in the
17422                        // direction of the ongoing scroll because it's better UX for the scroll to snap
17423                        // in the same direction as the scroll instead of reversing to snap.  Therefore,
17424                        // if it's already scrolled more than 20% in the current direction, keep going.
17425                        const snapToThreshold = delta > 0 ? 0.8 : 0.2;
17426                        lastEventBeforeSnap = newEvent;
17427                        recentWheelEvents.splice(0);
17428                        timeout = nextTick(() => {
17429                            if (swiper.destroyed || !swiper.params) return;
17430                            swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
17431                        }, 0); // no delay; move on next tick
17432                    }
17433
17434                    if (!timeout) {
17435                        // if we get here, then we haven't detected the end of a momentum scroll, so
17436                        // we'll consider a scroll "complete" when there haven't been any wheel events
17437                        // for 500ms.
17438                        timeout = nextTick(() => {
17439                            if (swiper.destroyed || !swiper.params) return;
17440                            const snapToThreshold = 0.5;
17441                            lastEventBeforeSnap = newEvent;
17442                            recentWheelEvents.splice(0);
17443                            swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold);
17444                        }, 500);
17445                    }
17446                }
17447
17448                // Emit event
17449                if (!ignoreWheelEvents) emit('scroll', e);
17450
17451                // Stop autoplay
17452                if (swiper.params.autoplay && swiper.params.autoplay.disableOnInteraction) swiper.autoplay.stop();
17453                // Return page scroll on edge positions
17454                if (params.releaseOnEdges && (position === swiper.minTranslate() || position === swiper.maxTranslate())) {
17455                    return true;
17456                }
17457            }
17458        }
17459        if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
17460        return false;
17461    }
17462
17463    function events(method) {
17464        let targetEl = swiper.el;
17465        if (swiper.params.mousewheel.eventsTarget !== 'container') {
17466            targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget);
17467        }
17468        targetEl[method]('mouseenter', handleMouseEnter);
17469        targetEl[method]('mouseleave', handleMouseLeave);
17470        targetEl[method]('wheel', handle);
17471    }
17472
17473    function enable() {
17474        if (swiper.params.cssMode) {
17475            swiper.wrapperEl.removeEventListener('wheel', handle);
17476            return true;
17477        }
17478        if (swiper.mousewheel.enabled) return false;
17479        events('addEventListener');
17480        swiper.mousewheel.enabled = true;
17481        return true;
17482    }
17483
17484    function disable() {
17485        if (swiper.params.cssMode) {
17486            swiper.wrapperEl.addEventListener(event, handle);
17487            return true;
17488        }
17489        if (!swiper.mousewheel.enabled) return false;
17490        events('removeEventListener');
17491        swiper.mousewheel.enabled = false;
17492        return true;
17493    }
17494
17495    on('init', () => {
17496        if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) {
17497            disable();
17498        }
17499        if (swiper.params.mousewheel.enabled) enable();
17500    });
17501    on('destroy', () => {
17502        if (swiper.params.cssMode) {
17503            enable();
17504        }
17505        if (swiper.mousewheel.enabled) disable();
17506    });
17507    Object.assign(swiper.mousewheel, {
17508        enable,
17509        disable
17510    });
17511}
17512
17513function createElementIfNotDefined(swiper, originalParams, params, checkProps) {
17514    if (swiper.params.createElements) {
17515        Object.keys(checkProps).forEach(key => {
17516            if (!params[key] && params.auto === true) {
17517                let element = elementChildren(swiper.el, `.${checkProps[key]}`)[0];
17518                if (!element) {
17519                    element = createElement('div', checkProps[key]);
17520                    element.className = checkProps[key];
17521                    swiper.el.append(element);
17522                }
17523                params[key] = element;
17524                originalParams[key] = element;
17525            }
17526        });
17527    }
17528    return params;
17529}
17530
17531function Navigation(_ref) {
17532    let {
17533        swiper,
17534        extendParams,
17535        on,
17536        emit
17537    } = _ref;
17538    extendParams({
17539        navigation: {
17540            nextEl: null,
17541            prevEl: null,
17542            hideOnClick: false,
17543            disabledClass: 'swiper-button-disabled',
17544            hiddenClass: 'swiper-button-hidden',
17545            lockClass: 'swiper-button-lock',
17546            navigationDisabledClass: 'swiper-navigation-disabled'
17547        }
17548    });
17549    swiper.navigation = {
17550        nextEl: null,
17551        prevEl: null
17552    };
17553
17554    function getEl(el) {
17555        let res;
17556        if (el && typeof el === 'string' && swiper.isElement) {
17557            res = swiper.el.querySelector(el) || swiper.hostEl.querySelector(el);
17558            if (res) return res;
17559        }
17560        if (el) {
17561            if (typeof el === 'string') res = [...document.querySelectorAll(el)];
17562            if (swiper.params.uniqueNavElements && typeof el === 'string' && res && res.length > 1 && swiper.el.querySelectorAll(el).length === 1) {
17563                res = swiper.el.querySelector(el);
17564            } else if (res && res.length === 1) {
17565                res = res[0];
17566            }
17567        }
17568        if (el && !res) return el;
17569        // if (Array.isArray(res) && res.length === 1) res = res[0];
17570        return res;
17571    }
17572
17573    function toggleEl(el, disabled) {
17574        const params = swiper.params.navigation;
17575        el = makeElementsArray(el);
17576        el.forEach(subEl => {
17577            if (subEl) {
17578                subEl.classList[disabled ? 'add' : 'remove'](...params.disabledClass.split(' '));
17579                if (subEl.tagName === 'BUTTON') subEl.disabled = disabled;
17580                if (swiper.params.watchOverflow && swiper.enabled) {
17581                    subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
17582                }
17583            }
17584        });
17585    }
17586
17587    function update() {
17588        // Update Navigation Buttons
17589        const {
17590            nextEl,
17591            prevEl
17592        } = swiper.navigation;
17593        if (swiper.params.loop) {
17594            toggleEl(prevEl, false);
17595            toggleEl(nextEl, false);
17596            return;
17597        }
17598        toggleEl(prevEl, swiper.isBeginning && !swiper.params.rewind);
17599        toggleEl(nextEl, swiper.isEnd && !swiper.params.rewind);
17600    }
17601
17602    function onPrevClick(e) {
17603        e.preventDefault();
17604        if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;
17605        swiper.slidePrev();
17606        emit('navigationPrev');
17607    }
17608
17609    function onNextClick(e) {
17610        e.preventDefault();
17611        if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;
17612        swiper.slideNext();
17613        emit('navigationNext');
17614    }
17615
vendor: 4,124 bytes, lines 17616-17725
17616    function init() {
17617        const params = swiper.params.navigation;
17618        swiper.params.navigation = createElementIfNotDefined(swiper, swiper.originalParams.navigation, swiper.params.navigation, {
17619            nextEl: 'swiper-button-next',
17620            prevEl: 'swiper-button-prev'
17621        });
17622        if (!(params.nextEl || params.prevEl)) return;
17623        let nextEl = getEl(params.nextEl);
17624        let prevEl = getEl(params.prevEl);
17625        Object.assign(swiper.navigation, {
17626            nextEl,
17627            prevEl
17628        });
17629        nextEl = makeElementsArray(nextEl);
17630        prevEl = makeElementsArray(prevEl);
17631        const initButton = (el, dir) => {
17632            if (el) {
17633                el.addEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
17634            }
17635            if (!swiper.enabled && el) {
17636                el.classList.add(...params.lockClass.split(' '));
17637            }
17638        };
17639        nextEl.forEach(el => initButton(el, 'next'));
17640        prevEl.forEach(el => initButton(el, 'prev'));
17641    }
17642
17643    function destroy() {
17644        let {
17645            nextEl,
17646            prevEl
17647        } = swiper.navigation;
17648        nextEl = makeElementsArray(nextEl);
17649        prevEl = makeElementsArray(prevEl);
17650        const destroyButton = (el, dir) => {
17651            el.removeEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
17652            el.classList.remove(...swiper.params.navigation.disabledClass.split(' '));
17653        };
17654        nextEl.forEach(el => destroyButton(el, 'next'));
17655        prevEl.forEach(el => destroyButton(el, 'prev'));
17656    }
17657
17658    on('init', () => {
17659        if (swiper.params.navigation.enabled === false) {
17660            // eslint-disable-next-line
17661            disable();
17662        } else {
17663            init();
17664            update();
17665        }
17666    });
17667    on('toEdge fromEdge lock unlock', () => {
17668        update();
17669    });
17670    on('destroy', () => {
17671        destroy();
17672    });
17673    on('enable disable', () => {
17674        let {
17675            nextEl,
17676            prevEl
17677        } = swiper.navigation;
17678        nextEl = makeElementsArray(nextEl);
17679        prevEl = makeElementsArray(prevEl);
17680        if (swiper.enabled) {
17681            update();
17682            return;
17683        }
17684        [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.add(swiper.params.navigation.lockClass));
17685    });
17686    on('click', (_s, e) => {
17687        let {
17688            nextEl,
17689            prevEl
17690        } = swiper.navigation;
17691        nextEl = makeElementsArray(nextEl);
17692        prevEl = makeElementsArray(prevEl);
17693        const targetEl = e.target;
17694        let targetIsButton = prevEl.includes(targetEl) || nextEl.includes(targetEl);
17695        if (swiper.isElement && !targetIsButton) {
17696            const path = e.path || e.composedPath && e.composedPath();
17697            if (path) {
17698                targetIsButton = path.find(pathEl => nextEl.includes(pathEl) || prevEl.includes(pathEl));
17699            }
17700        }
17701        if (swiper.params.navigation.hideOnClick && !targetIsButton) {
17702            if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return;
17703            let isHidden;
17704            if (nextEl.length) {
17705                isHidden = nextEl[0].classList.contains(swiper.params.navigation.hiddenClass);
17706            } else if (prevEl.length) {
17707                isHidden = prevEl[0].classList.contains(swiper.params.navigation.hiddenClass);
17708            }
17709            if (isHidden === true) {
17710                emit('navigationShow');
17711            } else {
17712                emit('navigationHide');
17713            }
17714            [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.toggle(swiper.params.navigation.hiddenClass));
17715        }
17716    });
17717    const enable = () => {
17718        swiper.el.classList.remove(...swiper.params.navigation.navigationDisabledClass.split(' '));
17719        init();
17720        update();
17721    };
17722    const disable = () => {
17723        swiper.el.classList.add(...swiper.params.navigation.navigationDisabledClass.split(' '));
17724        destroy();
17725    };
vendor: 19,987 bytes, lines 17726-18196
17726    Object.assign(swiper.navigation, {
17727        enable,
17728        disable,
17729        update,
17730        init,
17731        destroy
17732    });
17733}
17734
17735function classesToSelector(classes) {
17736    if (classes === void 0) {
17737        classes = '';
17738    }
17739    return `.${classes.trim().replace(/([\.:!+\/()[\]])/g, '\\$1') // eslint-disable-line
17740        .replace(/ /g, '.')}`;
17741}
17742
17743function Pagination(_ref) {
17744    let {
17745        swiper,
17746        extendParams,
17747        on,
17748        emit
17749    } = _ref;
17750    const pfx = 'swiper-pagination';
17751    extendParams({
17752        pagination: {
17753            el: null,
17754            bulletElement: 'span',
17755            clickable: false,
17756            hideOnClick: false,
17757            renderBullet: null,
17758            renderProgressbar: null,
17759            renderFraction: null,
17760            renderCustom: null,
17761            progressbarOpposite: false,
17762            type: 'bullets',
17763            // 'bullets' or 'progressbar' or 'fraction' or 'custom'
17764            dynamicBullets: false,
17765            dynamicMainBullets: 1,
17766            formatFractionCurrent: number => number,
17767            formatFractionTotal: number => number,
17768            bulletClass: `${pfx}-bullet`,
17769            bulletActiveClass: `${pfx}-bullet-active`,
17770            modifierClass: `${pfx}-`,
17771            currentClass: `${pfx}-current`,
17772            totalClass: `${pfx}-total`,
17773            hiddenClass: `${pfx}-hidden`,
17774            progressbarFillClass: `${pfx}-progressbar-fill`,
17775            progressbarOppositeClass: `${pfx}-progressbar-opposite`,
17776            clickableClass: `${pfx}-clickable`,
17777            lockClass: `${pfx}-lock`,
17778            horizontalClass: `${pfx}-horizontal`,
17779            verticalClass: `${pfx}-vertical`,
17780            paginationDisabledClass: `${pfx}-disabled`
17781        }
17782    });
17783    swiper.pagination = {
17784        el: null,
17785        bullets: []
17786    };
17787    let bulletSize;
17788    let dynamicBulletIndex = 0;
17789
17790    function isPaginationDisabled() {
17791        return !swiper.params.pagination.el || !swiper.pagination.el || Array.isArray(swiper.pagination.el) && swiper.pagination.el.length === 0;
17792    }
17793
17794    function setSideBullets(bulletEl, position) {
17795        const {
17796            bulletActiveClass
17797        } = swiper.params.pagination;
17798        if (!bulletEl) return;
17799        bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
17800        if (bulletEl) {
17801            bulletEl.classList.add(`${bulletActiveClass}-${position}`);
17802            bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`];
17803            if (bulletEl) {
17804                bulletEl.classList.add(`${bulletActiveClass}-${position}-${position}`);
17805            }
17806        }
17807    }
17808
17809    function getMoveDirection(prevIndex, nextIndex, length) {
17810        prevIndex = prevIndex % length;
17811        nextIndex = nextIndex % length;
17812        if (nextIndex === prevIndex + 1) {
17813            return 'next';
17814        } else if (nextIndex === prevIndex - 1) {
17815            return 'previous';
17816        }
17817        return;
17818    }
17819
17820    function onBulletClick(e) {
17821        const bulletEl = e.target.closest(classesToSelector(swiper.params.pagination.bulletClass));
17822        if (!bulletEl) {
17823            return;
17824        }
17825        e.preventDefault();
17826        const index = elementIndex(bulletEl) * swiper.params.slidesPerGroup;
17827        if (swiper.params.loop) {
17828            if (swiper.realIndex === index) return;
17829            const moveDirection = getMoveDirection(swiper.realIndex, index, swiper.slides.length);
17830            if (moveDirection === 'next') {
17831                swiper.slideNext();
17832            } else if (moveDirection === 'previous') {
17833                swiper.slidePrev();
17834            } else {
17835                swiper.slideToLoop(index);
17836            }
17837        } else {
17838            swiper.slideTo(index);
17839        }
17840    }
17841
17842    function update() {
17843        // Render || Update Pagination bullets/items
17844        const rtl = swiper.rtl;
17845        const params = swiper.params.pagination;
17846        if (isPaginationDisabled()) return;
17847        let el = swiper.pagination.el;
17848        el = makeElementsArray(el);
17849        // Current/Total
17850        let current;
17851        let previousIndex;
17852        const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;
17853        const total = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
17854        if (swiper.params.loop) {
17855            previousIndex = swiper.previousRealIndex || 0;
17856            current = swiper.params.slidesPerGroup > 1 ? Math.floor(swiper.realIndex / swiper.params.slidesPerGroup) : swiper.realIndex;
17857        } else if (typeof swiper.snapIndex !== 'undefined') {
17858            current = swiper.snapIndex;
17859            previousIndex = swiper.previousSnapIndex;
17860        } else {
17861            previousIndex = swiper.previousIndex || 0;
17862            current = swiper.activeIndex || 0;
17863        }
17864        // Types
17865        if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {
17866            const bullets = swiper.pagination.bullets;
17867            let firstIndex;
17868            let lastIndex;
17869            let midIndex;
17870            if (params.dynamicBullets) {
17871                bulletSize = elementOuterSize(bullets[0], swiper.isHorizontal() ? 'width' : 'height');
17872                el.forEach(subEl => {
17873                    subEl.style[swiper.isHorizontal() ? 'width' : 'height'] = `${bulletSize * (params.dynamicMainBullets + 4)}px`;
17874                });
17875                if (params.dynamicMainBullets > 1 && previousIndex !== undefined) {
17876                    dynamicBulletIndex += current - (previousIndex || 0);
17877                    if (dynamicBulletIndex > params.dynamicMainBullets - 1) {
17878                        dynamicBulletIndex = params.dynamicMainBullets - 1;
17879                    } else if (dynamicBulletIndex < 0) {
17880                        dynamicBulletIndex = 0;
17881                    }
17882                }
17883                firstIndex = Math.max(current - dynamicBulletIndex, 0);
17884                lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
17885                midIndex = (lastIndex + firstIndex) / 2;
17886            }
17887            bullets.forEach(bulletEl => {
17888                const classesToRemove = [...['', '-next', '-next-next', '-prev', '-prev-prev', '-main'].map(suffix => `${params.bulletActiveClass}${suffix}`)].map(s => typeof s === 'string' && s.includes(' ') ? s.split(' ') : s).flat();
17889                bulletEl.classList.remove(...classesToRemove);
17890            });
17891            if (el.length > 1) {
17892                bullets.forEach(bullet => {
17893                    const bulletIndex = elementIndex(bullet);
17894                    if (bulletIndex === current) {
17895                        bullet.classList.add(...params.bulletActiveClass.split(' '));
17896                    } else if (swiper.isElement) {
17897                        bullet.setAttribute('part', 'bullet');
17898                    }
17899                    if (params.dynamicBullets) {
17900                        if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
17901                            bullet.classList.add(...`${params.bulletActiveClass}-main`.split(' '));
17902                        }
17903                        if (bulletIndex === firstIndex) {
17904                            setSideBullets(bullet, 'prev');
17905                        }
17906                        if (bulletIndex === lastIndex) {
17907                            setSideBullets(bullet, 'next');
17908                        }
17909                    }
17910                });
17911            } else {
17912                const bullet = bullets[current];
17913                if (bullet) {
17914                    bullet.classList.add(...params.bulletActiveClass.split(' '));
17915                }
17916                if (swiper.isElement) {
17917                    bullets.forEach((bulletEl, bulletIndex) => {
17918                        bulletEl.setAttribute('part', bulletIndex === current ? 'bullet-active' : 'bullet');
17919                    });
17920                }
17921                if (params.dynamicBullets) {
17922                    const firstDisplayedBullet = bullets[firstIndex];
17923                    const lastDisplayedBullet = bullets[lastIndex];
17924                    for (let i = firstIndex; i <= lastIndex; i += 1) {
17925                        if (bullets[i]) {
17926                            bullets[i].classList.add(...`${params.bulletActiveClass}-main`.split(' '));
17927                        }
17928                    }
17929                    setSideBullets(firstDisplayedBullet, 'prev');
17930                    setSideBullets(lastDisplayedBullet, 'next');
17931                }
17932            }
17933            if (params.dynamicBullets) {
17934                const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
17935                const bulletsOffset = (bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;
17936                const offsetProp = rtl ? 'right' : 'left';
17937                bullets.forEach(bullet => {
17938                    bullet.style[swiper.isHorizontal() ? offsetProp : 'top'] = `${bulletsOffset}px`;
17939                });
17940            }
17941        }
17942        el.forEach((subEl, subElIndex) => {
17943            if (params.type === 'fraction') {
17944                subEl.querySelectorAll(classesToSelector(params.currentClass)).forEach(fractionEl => {
17945                    fractionEl.textContent = params.formatFractionCurrent(current + 1);
17946                });
17947                subEl.querySelectorAll(classesToSelector(params.totalClass)).forEach(totalEl => {
17948                    totalEl.textContent = params.formatFractionTotal(total);
17949                });
17950            }
17951            if (params.type === 'progressbar') {
17952                let progressbarDirection;
17953                if (params.progressbarOpposite) {
17954                    progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
17955                } else {
17956                    progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
17957                }
17958                const scale = (current + 1) / total;
17959                let scaleX = 1;
17960                let scaleY = 1;
17961                if (progressbarDirection === 'horizontal') {
17962                    scaleX = scale;
17963                } else {
17964                    scaleY = scale;
17965                }
17966                subEl.querySelectorAll(classesToSelector(params.progressbarFillClass)).forEach(progressEl => {
17967                    progressEl.style.transform = `translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`;
17968                    progressEl.style.transitionDuration = `${swiper.params.speed}ms`;
17969                });
17970            }
17971            if (params.type === 'custom' && params.renderCustom) {
17972                setInnerHTML(subEl, params.renderCustom(swiper, current + 1, total));
17973                if (subElIndex === 0) emit('paginationRender', subEl);
17974            } else {
17975                if (subElIndex === 0) emit('paginationRender', subEl);
17976                emit('paginationUpdate', subEl);
17977            }
17978            if (swiper.params.watchOverflow && swiper.enabled) {
17979                subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
17980            }
17981        });
17982    }
17983
17984    function render() {
17985        // Render Container
17986        const params = swiper.params.pagination;
17987        if (isPaginationDisabled()) return;
17988        const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.grid && swiper.params.grid.rows > 1 ? swiper.slides.length / Math.ceil(swiper.params.grid.rows) : swiper.slides.length;
17989        let el = swiper.pagination.el;
17990        el = makeElementsArray(el);
17991        let paginationHTML = '';
17992        if (params.type === 'bullets') {
17993            let numberOfBullets = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length;
17994            if (swiper.params.freeMode && swiper.params.freeMode.enabled && numberOfBullets > slidesLength) {
17995                numberOfBullets = slidesLength;
17996            }
17997            for (let i = 0; i < numberOfBullets; i += 1) {
17998                if (params.renderBullet) {
17999                    paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
18000                } else {
18001                    // prettier-ignore
18002                    paginationHTML += `<${params.bulletElement} ${swiper.isElement ? 'part="bullet"' : ''} class="${params.bulletClass}"></${params.bulletElement}>`;
18003                }
18004            }
18005        }
18006        if (params.type === 'fraction') {
18007            if (params.renderFraction) {
18008                paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
18009            } else {
18010                paginationHTML = `<span class="${params.currentClass}"></span>` + ' / ' + `<span class="${params.totalClass}"></span>`;
18011            }
18012        }
18013        if (params.type === 'progressbar') {
18014            if (params.renderProgressbar) {
18015                paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
18016            } else {
18017                paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
18018            }
18019        }
18020        swiper.pagination.bullets = [];
18021        el.forEach(subEl => {
18022            if (params.type !== 'custom') {
18023                setInnerHTML(subEl, paginationHTML || '');
18024            }
18025            if (params.type === 'bullets') {
18026                swiper.pagination.bullets.push(...subEl.querySelectorAll(classesToSelector(params.bulletClass)));
18027            }
18028        });
18029        if (params.type !== 'custom') {
18030            emit('paginationRender', el[0]);
18031        }
18032    }
18033
18034    function init() {
18035        swiper.params.pagination = createElementIfNotDefined(swiper, swiper.originalParams.pagination, swiper.params.pagination, {
18036            el: 'swiper-pagination'
18037        });
18038        const params = swiper.params.pagination;
18039        if (!params.el) return;
18040        let el;
18041        if (typeof params.el === 'string' && swiper.isElement) {
18042            el = swiper.el.querySelector(params.el);
18043        }
18044        if (!el && typeof params.el === 'string') {
18045            el = [...document.querySelectorAll(params.el)];
18046        }
18047        if (!el) {
18048            el = params.el;
18049        }
18050        if (!el || el.length === 0) return;
18051        if (swiper.params.uniqueNavElements && typeof params.el === 'string' && Array.isArray(el) && el.length > 1) {
18052            el = [...swiper.el.querySelectorAll(params.el)];
18053            // check if it belongs to another nested Swiper
18054            if (el.length > 1) {
18055                el = el.find(subEl => {
18056                    if (elementParents(subEl, '.swiper')[0] !== swiper.el) return false;
18057                    return true;
18058                });
18059            }
18060        }
18061        if (Array.isArray(el) && el.length === 1) el = el[0];
18062        Object.assign(swiper.pagination, {
18063            el
18064        });
18065        el = makeElementsArray(el);
18066        el.forEach(subEl => {
18067            if (params.type === 'bullets' && params.clickable) {
18068                subEl.classList.add(...(params.clickableClass || '').split(' '));
18069            }
18070            subEl.classList.add(params.modifierClass + params.type);
18071            subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
18072            if (params.type === 'bullets' && params.dynamicBullets) {
18073                subEl.classList.add(`${params.modifierClass}${params.type}-dynamic`);
18074                dynamicBulletIndex = 0;
18075                if (params.dynamicMainBullets < 1) {
18076                    params.dynamicMainBullets = 1;
18077                }
18078            }
18079            if (params.type === 'progressbar' && params.progressbarOpposite) {
18080                subEl.classList.add(params.progressbarOppositeClass);
18081            }
18082            if (params.clickable) {
18083                subEl.addEventListener('click', onBulletClick);
18084            }
18085            if (!swiper.enabled) {
18086                subEl.classList.add(params.lockClass);
18087            }
18088        });
18089    }
18090
18091    function destroy() {
18092        const params = swiper.params.pagination;
18093        if (isPaginationDisabled()) return;
18094        let el = swiper.pagination.el;
18095        if (el) {
18096            el = makeElementsArray(el);
18097            el.forEach(subEl => {
18098                subEl.classList.remove(params.hiddenClass);
18099                subEl.classList.remove(params.modifierClass + params.type);
18100                subEl.classList.remove(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
18101                if (params.clickable) {
18102                    subEl.classList.remove(...(params.clickableClass || '').split(' '));
18103                    subEl.removeEventListener('click', onBulletClick);
18104                }
18105            });
18106        }
18107        if (swiper.pagination.bullets) swiper.pagination.bullets.forEach(subEl => subEl.classList.remove(...params.bulletActiveClass.split(' ')));
18108    }
18109
18110    on('changeDirection', () => {
18111        if (!swiper.pagination || !swiper.pagination.el) return;
18112        const params = swiper.params.pagination;
18113        let {
18114            el
18115        } = swiper.pagination;
18116        el = makeElementsArray(el);
18117        el.forEach(subEl => {
18118            subEl.classList.remove(params.horizontalClass, params.verticalClass);
18119            subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
18120        });
18121    });
18122    on('init', () => {
18123        if (swiper.params.pagination.enabled === false) {
18124            // eslint-disable-next-line
18125            disable();
18126        } else {
18127            init();
18128            render();
18129            update();
18130        }
18131    });
18132    on('activeIndexChange', () => {
18133        if (typeof swiper.snapIndex === 'undefined') {
18134            update();
18135        }
18136    });
18137    on('snapIndexChange', () => {
18138        update();
18139    });
18140    on('snapGridLengthChange', () => {
18141        render();
18142        update();
18143    });
18144    on('destroy', () => {
18145        destroy();
18146    });
18147    on('enable disable', () => {
18148        let {
18149            el
18150        } = swiper.pagination;
18151        if (el) {
18152            el = makeElementsArray(el);
18153            el.forEach(subEl => subEl.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.pagination.lockClass));
18154        }
18155    });
18156    on('lock unlock', () => {
18157        update();
18158    });
18159    on('click', (_s, e) => {
18160        const targetEl = e.target;
18161        const el = makeElementsArray(swiper.pagination.el);
18162        if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && el && el.length > 0 && !targetEl.classList.contains(swiper.params.pagination.bulletClass)) {
18163            if (swiper.navigation && (swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl || swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl)) return;
18164            const isHidden = el[0].classList.contains(swiper.params.pagination.hiddenClass);
18165            if (isHidden === true) {
18166                emit('paginationShow');
18167            } else {
18168                emit('paginationHide');
18169            }
18170            el.forEach(subEl => subEl.classList.toggle(swiper.params.pagination.hiddenClass));
18171        }
18172    });
18173    const enable = () => {
18174        swiper.el.classList.remove(swiper.params.pagination.paginationDisabledClass);
18175        let {
18176            el
18177        } = swiper.pagination;
18178        if (el) {
18179            el = makeElementsArray(el);
18180            el.forEach(subEl => subEl.classList.remove(swiper.params.pagination.paginationDisabledClass));
18181        }
18182        init();
18183        render();
18184        update();
18185    };
18186    const disable = () => {
18187        swiper.el.classList.add(swiper.params.pagination.paginationDisabledClass);
18188        let {
18189            el
18190        } = swiper.pagination;
18191        if (el) {
18192            el = makeElementsArray(el);
18193            el.forEach(subEl => subEl.classList.add(swiper.params.pagination.paginationDisabledClass));
18194        }
18195        destroy();
18196    };
vendor: 5,721 bytes, lines 18197-18374
18197    Object.assign(swiper.pagination, {
18198        enable,
18199        disable,
18200        render,
18201        update,
18202        init,
18203        destroy
18204    });
18205}
18206
18207function Scrollbar(_ref) {
18208    let {
18209        swiper,
18210        extendParams,
18211        on,
18212        emit
18213    } = _ref;
18214    const document = getDocument();
18215    let isTouched = false;
18216    let timeout = null;
18217    let dragTimeout = null;
18218    let dragStartPos;
18219    let dragSize;
18220    let trackSize;
18221    let divider;
18222    extendParams({
18223        scrollbar: {
18224            el: null,
18225            dragSize: 'auto',
18226            hide: false,
18227            draggable: false,
18228            snapOnRelease: true,
18229            lockClass: 'swiper-scrollbar-lock',
18230            dragClass: 'swiper-scrollbar-drag',
18231            scrollbarDisabledClass: 'swiper-scrollbar-disabled',
18232            horizontalClass: `swiper-scrollbar-horizontal`,
18233            verticalClass: `swiper-scrollbar-vertical`
18234        }
18235    });
18236    swiper.scrollbar = {
18237        el: null,
18238        dragEl: null
18239    };
18240
18241    function setTranslate() {
18242        if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
18243        const {
18244            scrollbar,
18245            rtlTranslate: rtl
18246        } = swiper;
18247        const {
18248            dragEl,
18249            el
18250        } = scrollbar;
18251        const params = swiper.params.scrollbar;
18252        const progress = swiper.params.loop ? swiper.progressLoop : swiper.progress;
18253        let newSize = dragSize;
18254        let newPos = (trackSize - dragSize) * progress;
18255        if (rtl) {
18256            newPos = -newPos;
18257            if (newPos > 0) {
18258                newSize = dragSize - newPos;
18259                newPos = 0;
18260            } else if (-newPos + dragSize > trackSize) {
18261                newSize = trackSize + newPos;
18262            }
18263        } else if (newPos < 0) {
18264            newSize = dragSize + newPos;
18265            newPos = 0;
18266        } else if (newPos + dragSize > trackSize) {
18267            newSize = trackSize - newPos;
18268        }
18269        if (swiper.isHorizontal()) {
18270            dragEl.style.transform = `translate3d(${newPos}px, 0, 0)`;
18271            dragEl.style.width = `${newSize}px`;
18272        } else {
18273            dragEl.style.transform = `translate3d(0px, ${newPos}px, 0)`;
18274            dragEl.style.height = `${newSize}px`;
18275        }
18276        if (params.hide) {
18277            clearTimeout(timeout);
18278            el.style.opacity = 1;
18279            timeout = setTimeout(() => {
18280                el.style.opacity = 0;
18281                el.style.transitionDuration = '400ms';
18282            }, 1000);
18283        }
18284    }
18285
18286    function setTransition(duration) {
18287        if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
18288        swiper.scrollbar.dragEl.style.transitionDuration = `${duration}ms`;
18289    }
18290
18291    function updateSize() {
18292        if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
18293        const {
18294            scrollbar
18295        } = swiper;
18296        const {
18297            dragEl,
18298            el
18299        } = scrollbar;
18300        dragEl.style.width = '';
18301        dragEl.style.height = '';
18302        trackSize = swiper.isHorizontal() ? el.offsetWidth : el.offsetHeight;
18303        divider = swiper.size / (swiper.virtualSize + swiper.params.slidesOffsetBefore - (swiper.params.centeredSlides ? swiper.snapGrid[0] : 0));
18304        if (swiper.params.scrollbar.dragSize === 'auto') {
18305            dragSize = trackSize * divider;
18306        } else {
18307            dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
18308        }
18309        if (swiper.isHorizontal()) {
18310            dragEl.style.width = `${dragSize}px`;
18311        } else {
18312            dragEl.style.height = `${dragSize}px`;
18313        }
18314        if (divider >= 1) {
18315            el.style.display = 'none';
18316        } else {
18317            el.style.display = '';
18318        }
18319        if (swiper.params.scrollbar.hide) {
18320            el.style.opacity = 0;
18321        }
18322        if (swiper.params.watchOverflow && swiper.enabled) {
18323            scrollbar.el.classList[swiper.isLocked ? 'add' : 'remove'](swiper.params.scrollbar.lockClass);
18324        }
18325    }
18326
18327    function getPointerPosition(e) {
18328        return swiper.isHorizontal() ? e.clientX : e.clientY;
18329    }
18330
18331    function setDragPosition(e) {
18332        const {
18333            scrollbar,
18334            rtlTranslate: rtl
18335        } = swiper;
18336        const {
18337            el
18338        } = scrollbar;
18339        let positionRatio;
18340        positionRatio = (getPointerPosition(e) - elementOffset(el)[swiper.isHorizontal() ? 'left' : 'top'] - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize);
18341        positionRatio = Math.max(Math.min(positionRatio, 1), 0);
18342        if (rtl) {
18343            positionRatio = 1 - positionRatio;
18344        }
18345        const position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;
18346        swiper.updateProgress(position);
18347        swiper.setTranslate(position);
18348        swiper.updateActiveIndex();
18349        swiper.updateSlidesClasses();
18350    }
18351
18352    function onDragStart(e) {
18353        const params = swiper.params.scrollbar;
18354        const {
18355            scrollbar,
18356            wrapperEl
18357        } = swiper;
18358        const {
18359            el,
18360            dragEl
18361        } = scrollbar;
18362        isTouched = true;
18363        dragStartPos = e.target === dragEl ? getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null;
18364        e.preventDefault();
18365        e.stopPropagation();
18366        wrapperEl.style.transitionDuration = '100ms';
18367        dragEl.style.transitionDuration = '100ms';
18368        setDragPosition(e);
18369        clearTimeout(dragTimeout);
18370        el.style.transitionDuration = '0ms';
18371        if (params.hide) {
18372            el.style.opacity = 1;
18373        }
18374        if (swiper.params.cssMode) {
vendor: 6,441 bytes, lines 18375-18570
18375            swiper.wrapperEl.style['scroll-snap-type'] = 'none';
18376        }
18377        emit('scrollbarDragStart', e);
18378    }
18379
18380    function onDragMove(e) {
18381        const {
18382            scrollbar,
18383            wrapperEl
18384        } = swiper;
18385        const {
18386            el,
18387            dragEl
18388        } = scrollbar;
18389        if (!isTouched) return;
18390        if (e.preventDefault && e.cancelable) e.preventDefault(); else e.returnValue = false;
18391        setDragPosition(e);
18392        wrapperEl.style.transitionDuration = '0ms';
18393        el.style.transitionDuration = '0ms';
18394        dragEl.style.transitionDuration = '0ms';
18395        emit('scrollbarDragMove', e);
18396    }
18397
18398    function onDragEnd(e) {
18399        const params = swiper.params.scrollbar;
18400        const {
18401            scrollbar,
18402            wrapperEl
18403        } = swiper;
18404        const {
18405            el
18406        } = scrollbar;
18407        if (!isTouched) return;
18408        isTouched = false;
18409        if (swiper.params.cssMode) {
18410            swiper.wrapperEl.style['scroll-snap-type'] = '';
18411            wrapperEl.style.transitionDuration = '';
18412        }
18413        if (params.hide) {
18414            clearTimeout(dragTimeout);
18415            dragTimeout = nextTick(() => {
18416                el.style.opacity = 0;
18417                el.style.transitionDuration = '400ms';
18418            }, 1000);
18419        }
18420        emit('scrollbarDragEnd', e);
18421        if (params.snapOnRelease) {
18422            swiper.slideToClosest();
18423        }
18424    }
18425
18426    function events(method) {
18427        const {
18428            scrollbar,
18429            params
18430        } = swiper;
18431        const el = scrollbar.el;
18432        if (!el) return;
18433        const target = el;
18434        const activeListener = params.passiveListeners ? {
18435            passive: false,
18436            capture: false
18437        } : false;
18438        const passiveListener = params.passiveListeners ? {
18439            passive: true,
18440            capture: false
18441        } : false;
18442        if (!target) return;
18443        const eventMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
18444        target[eventMethod]('pointerdown', onDragStart, activeListener);
18445        document[eventMethod]('pointermove', onDragMove, activeListener);
18446        document[eventMethod]('pointerup', onDragEnd, passiveListener);
18447    }
18448
18449    function enableDraggable() {
18450        if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
18451        events('on');
18452    }
18453
18454    function disableDraggable() {
18455        if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
18456        events('off');
18457    }
18458
18459    function init() {
18460        const {
18461            scrollbar,
18462            el: swiperEl
18463        } = swiper;
18464        swiper.params.scrollbar = createElementIfNotDefined(swiper, swiper.originalParams.scrollbar, swiper.params.scrollbar, {
18465            el: 'swiper-scrollbar'
18466        });
18467        const params = swiper.params.scrollbar;
18468        if (!params.el) return;
18469        let el;
18470        if (typeof params.el === 'string' && swiper.isElement) {
18471            el = swiper.el.querySelector(params.el);
18472        }
18473        if (!el && typeof params.el === 'string') {
18474            el = document.querySelectorAll(params.el);
18475            if (!el.length) return;
18476        } else if (!el) {
18477            el = params.el;
18478        }
18479        if (swiper.params.uniqueNavElements && typeof params.el === 'string' && el.length > 1 && swiperEl.querySelectorAll(params.el).length === 1) {
18480            el = swiperEl.querySelector(params.el);
18481        }
18482        if (el.length > 0) el = el[0];
18483        el.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
18484        let dragEl;
18485        if (el) {
18486            dragEl = el.querySelector(classesToSelector(swiper.params.scrollbar.dragClass));
18487            if (!dragEl) {
18488                dragEl = createElement('div', swiper.params.scrollbar.dragClass);
18489                el.append(dragEl);
18490            }
18491        }
18492        Object.assign(scrollbar, {
18493            el,
18494            dragEl
18495        });
18496        if (params.draggable) {
18497            enableDraggable();
18498        }
18499        if (el) {
18500            el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass));
18501        }
18502    }
18503
18504    function destroy() {
18505        const params = swiper.params.scrollbar;
18506        const el = swiper.scrollbar.el;
18507        if (el) {
18508            el.classList.remove(...classesToTokens(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass));
18509        }
18510        disableDraggable();
18511    }
18512
18513    on('changeDirection', () => {
18514        if (!swiper.scrollbar || !swiper.scrollbar.el) return;
18515        const params = swiper.params.scrollbar;
18516        let {
18517            el
18518        } = swiper.scrollbar;
18519        el = makeElementsArray(el);
18520        el.forEach(subEl => {
18521            subEl.classList.remove(params.horizontalClass, params.verticalClass);
18522            subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass);
18523        });
18524    });
18525    on('init', () => {
18526        if (swiper.params.scrollbar.enabled === false) {
18527            // eslint-disable-next-line
18528            disable();
18529        } else {
18530            init();
18531            updateSize();
18532            setTranslate();
18533        }
18534    });
18535    on('update resize observerUpdate lock unlock changeDirection', () => {
18536        updateSize();
18537    });
18538    on('setTranslate', () => {
18539        setTranslate();
18540    });
18541    on('setTransition', (_s, duration) => {
18542        setTransition(duration);
18543    });
18544    on('enable disable', () => {
18545        const {
18546            el
18547        } = swiper.scrollbar;
18548        if (el) {
18549            el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass));
18550        }
18551    });
18552    on('destroy', () => {
18553        destroy();
18554    });
18555    const enable = () => {
18556        swiper.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
18557        if (swiper.scrollbar.el) {
18558            swiper.scrollbar.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
18559        }
18560        init();
18561        updateSize();
18562        setTranslate();
18563    };
18564    const disable = () => {
18565        swiper.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
18566        if (swiper.scrollbar.el) {
18567            swiper.scrollbar.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass));
18568        }
18569        destroy();
18570    };
vendor: 15,184 bytes, lines 18571-18992
18571    Object.assign(swiper.scrollbar, {
18572        enable,
18573        disable,
18574        updateSize,
18575        setTranslate,
18576        init,
18577        destroy
18578    });
18579}
18580
18581function Parallax(_ref) {
18582    let {
18583        swiper,
18584        extendParams,
18585        on
18586    } = _ref;
18587    extendParams({
18588        parallax: {
18589            enabled: false
18590        }
18591    });
18592    const elementsSelector = '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]';
18593    const setTransform = (el, progress) => {
18594        const {
18595            rtl
18596        } = swiper;
18597        const rtlFactor = rtl ? -1 : 1;
18598        const p = el.getAttribute('data-swiper-parallax') || '0';
18599        let x = el.getAttribute('data-swiper-parallax-x');
18600        let y = el.getAttribute('data-swiper-parallax-y');
18601        const scale = el.getAttribute('data-swiper-parallax-scale');
18602        const opacity = el.getAttribute('data-swiper-parallax-opacity');
18603        const rotate = el.getAttribute('data-swiper-parallax-rotate');
18604        if (x || y) {
18605            x = x || '0';
18606            y = y || '0';
18607        } else if (swiper.isHorizontal()) {
18608            x = p;
18609            y = '0';
18610        } else {
18611            y = p;
18612            x = '0';
18613        }
18614        if (x.indexOf('%') >= 0) {
18615            x = `${parseInt(x, 10) * progress * rtlFactor}%`;
18616        } else {
18617            x = `${x * progress * rtlFactor}px`;
18618        }
18619        if (y.indexOf('%') >= 0) {
18620            y = `${parseInt(y, 10) * progress}%`;
18621        } else {
18622            y = `${y * progress}px`;
18623        }
18624        if (typeof opacity !== 'undefined' && opacity !== null) {
18625            const currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress));
18626            el.style.opacity = currentOpacity;
18627        }
18628        let transform = `translate3d(${x}, ${y}, 0px)`;
18629        if (typeof scale !== 'undefined' && scale !== null) {
18630            const currentScale = scale - (scale - 1) * (1 - Math.abs(progress));
18631            transform += ` scale(${currentScale})`;
18632        }
18633        if (rotate && typeof rotate !== 'undefined' && rotate !== null) {
18634            const currentRotate = rotate * progress * -1;
18635            transform += ` rotate(${currentRotate}deg)`;
18636        }
18637        el.style.transform = transform;
18638    };
18639    const setTranslate = () => {
18640        const {
18641            el,
18642            slides,
18643            progress,
18644            snapGrid,
18645            isElement
18646        } = swiper;
18647        const elements = elementChildren(el, elementsSelector);
18648        if (swiper.isElement) {
18649            elements.push(...elementChildren(swiper.hostEl, elementsSelector));
18650        }
18651        elements.forEach(subEl => {
18652            setTransform(subEl, progress);
18653        });
18654        slides.forEach((slideEl, slideIndex) => {
18655            let slideProgress = slideEl.progress;
18656            if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {
18657                slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1);
18658            }
18659            slideProgress = Math.min(Math.max(slideProgress, -1), 1);
18660            slideEl.querySelectorAll(`${elementsSelector}, [data-swiper-parallax-rotate]`).forEach(subEl => {
18661                setTransform(subEl, slideProgress);
18662            });
18663        });
18664    };
18665    const setTransition = function (duration) {
18666        if (duration === void 0) {
18667            duration = swiper.params.speed;
18668        }
18669        const {
18670            el,
18671            hostEl
18672        } = swiper;
18673        const elements = [...el.querySelectorAll(elementsSelector)];
18674        if (swiper.isElement) {
18675            elements.push(...hostEl.querySelectorAll(elementsSelector));
18676        }
18677        elements.forEach(parallaxEl => {
18678            let parallaxDuration = parseInt(parallaxEl.getAttribute('data-swiper-parallax-duration'), 10) || duration;
18679            if (duration === 0) parallaxDuration = 0;
18680            parallaxEl.style.transitionDuration = `${parallaxDuration}ms`;
18681        });
18682    };
18683    on('beforeInit', () => {
18684        if (!swiper.params.parallax.enabled) return;
18685        swiper.params.watchSlidesProgress = true;
18686        swiper.originalParams.watchSlidesProgress = true;
18687    });
18688    on('init', () => {
18689        if (!swiper.params.parallax.enabled) return;
18690        setTranslate();
18691    });
18692    on('setTranslate', () => {
18693        if (!swiper.params.parallax.enabled) return;
18694        setTranslate();
18695    });
18696    on('setTransition', (_swiper, duration) => {
18697        if (!swiper.params.parallax.enabled) return;
18698        setTransition(duration);
18699    });
18700}
18701
18702function Zoom(_ref) {
18703    let {
18704        swiper,
18705        extendParams,
18706        on,
18707        emit
18708    } = _ref;
18709    const window = getWindow();
18710    extendParams({
18711        zoom: {
18712            enabled: false,
18713            limitToOriginalSize: false,
18714            maxRatio: 3,
18715            minRatio: 1,
18716            panOnMouseMove: false,
18717            toggle: true,
18718            containerClass: 'swiper-zoom-container',
18719            zoomedSlideClass: 'swiper-slide-zoomed'
18720        }
18721    });
18722    swiper.zoom = {
18723        enabled: false
18724    };
18725    let currentScale = 1;
18726    let isScaling = false;
18727    let isPanningWithMouse = false;
18728    let mousePanStart = {
18729        x: 0,
18730        y: 0
18731    };
18732    const mousePanSensitivity = -3; // Negative to invert pan direction
18733    let fakeGestureTouched;
18734    let fakeGestureMoved;
18735    const evCache = [];
18736    const gesture = {
18737        originX: 0,
18738        originY: 0,
18739        slideEl: undefined,
18740        slideWidth: undefined,
18741        slideHeight: undefined,
18742        imageEl: undefined,
18743        imageWrapEl: undefined,
18744        maxRatio: 3
18745    };
18746    const image = {
18747        isTouched: undefined,
18748        isMoved: undefined,
18749        currentX: undefined,
18750        currentY: undefined,
18751        minX: undefined,
18752        minY: undefined,
18753        maxX: undefined,
18754        maxY: undefined,
18755        width: undefined,
18756        height: undefined,
18757        startX: undefined,
18758        startY: undefined,
18759        touchesStart: {},
18760        touchesCurrent: {}
18761    };
18762    const velocity = {
18763        x: undefined,
18764        y: undefined,
18765        prevPositionX: undefined,
18766        prevPositionY: undefined,
18767        prevTime: undefined
18768    };
18769    let scale = 1;
18770    Object.defineProperty(swiper.zoom, 'scale', {
18771        get() {
18772            return scale;
18773        },
18774        set(value) {
18775            if (scale !== value) {
18776                const imageEl = gesture.imageEl;
18777                const slideEl = gesture.slideEl;
18778                emit('zoomChange', value, imageEl, slideEl);
18779            }
18780            scale = value;
18781        }
18782    });
18783
18784    function getDistanceBetweenTouches() {
18785        if (evCache.length < 2) return 1;
18786        const x1 = evCache[0].pageX;
18787        const y1 = evCache[0].pageY;
18788        const x2 = evCache[1].pageX;
18789        const y2 = evCache[1].pageY;
18790        const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
18791        return distance;
18792    }
18793
18794    function getMaxRatio() {
18795        const params = swiper.params.zoom;
18796        const maxRatio = gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio;
18797        if (params.limitToOriginalSize && gesture.imageEl && gesture.imageEl.naturalWidth) {
18798            const imageMaxRatio = gesture.imageEl.naturalWidth / gesture.imageEl.offsetWidth;
18799            return Math.min(imageMaxRatio, maxRatio);
18800        }
18801        return maxRatio;
18802    }
18803
18804    function getScaleOrigin() {
18805        if (evCache.length < 2) return {
18806            x: null,
18807            y: null
18808        };
18809        const box = gesture.imageEl.getBoundingClientRect();
18810        return [(evCache[0].pageX + (evCache[1].pageX - evCache[0].pageX) / 2 - box.x - window.scrollX) / currentScale, (evCache[0].pageY + (evCache[1].pageY - evCache[0].pageY) / 2 - box.y - window.scrollY) / currentScale];
18811    }
18812
18813    function getSlideSelector() {
18814        return swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`;
18815    }
18816
18817    function eventWithinSlide(e) {
18818        const slideSelector = getSlideSelector();
18819        if (e.target.matches(slideSelector)) return true;
18820        if (swiper.slides.filter(slideEl => slideEl.contains(e.target)).length > 0) return true;
18821        return false;
18822    }
18823
18824    function eventWithinZoomContainer(e) {
18825        const selector = `.${swiper.params.zoom.containerClass}`;
18826        if (e.target.matches(selector)) return true;
18827        if ([...swiper.hostEl.querySelectorAll(selector)].filter(containerEl => containerEl.contains(e.target)).length > 0) return true;
18828        return false;
18829    }
18830
18831    // Events
18832    function onGestureStart(e) {
18833        if (e.pointerType === 'mouse') {
18834            evCache.splice(0, evCache.length);
18835        }
18836        if (!eventWithinSlide(e)) return;
18837        const params = swiper.params.zoom;
18838        fakeGestureTouched = false;
18839        fakeGestureMoved = false;
18840        evCache.push(e);
18841        if (evCache.length < 2) {
18842            return;
18843        }
18844        fakeGestureTouched = true;
18845        gesture.scaleStart = getDistanceBetweenTouches();
18846        if (!gesture.slideEl) {
18847            gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
18848            if (!gesture.slideEl) gesture.slideEl = swiper.slides[swiper.activeIndex];
18849            let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
18850            if (imageEl) {
18851                imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
18852            }
18853            gesture.imageEl = imageEl;
18854            if (imageEl) {
18855                gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
18856            } else {
18857                gesture.imageWrapEl = undefined;
18858            }
18859            if (!gesture.imageWrapEl) {
18860                gesture.imageEl = undefined;
18861                return;
18862            }
18863            gesture.maxRatio = getMaxRatio();
18864        }
18865        if (gesture.imageEl) {
18866            const [originX, originY] = getScaleOrigin();
18867            gesture.originX = originX;
18868            gesture.originY = originY;
18869            gesture.imageEl.style.transitionDuration = '0ms';
18870        }
18871        isScaling = true;
18872    }
18873
18874    function onGestureChange(e) {
18875        if (!eventWithinSlide(e)) return;
18876        const params = swiper.params.zoom;
18877        const zoom = swiper.zoom;
18878        const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);
18879        if (pointerIndex >= 0) evCache[pointerIndex] = e;
18880        if (evCache.length < 2) {
18881            return;
18882        }
18883        fakeGestureMoved = true;
18884        gesture.scaleMove = getDistanceBetweenTouches();
18885        if (!gesture.imageEl) {
18886            return;
18887        }
18888        zoom.scale = gesture.scaleMove / gesture.scaleStart * currentScale;
18889        if (zoom.scale > gesture.maxRatio) {
18890            zoom.scale = gesture.maxRatio - 1 + (zoom.scale - gesture.maxRatio + 1) ** 0.5;
18891        }
18892        if (zoom.scale < params.minRatio) {
18893            zoom.scale = params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5;
18894        }
18895        gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
18896    }
18897
18898    function onGestureEnd(e) {
18899        if (!eventWithinSlide(e)) return;
18900        if (e.pointerType === 'mouse' && e.type === 'pointerout') return;
18901        const params = swiper.params.zoom;
18902        const zoom = swiper.zoom;
18903        const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId);
18904        if (pointerIndex >= 0) evCache.splice(pointerIndex, 1);
18905        if (!fakeGestureTouched || !fakeGestureMoved) {
18906            return;
18907        }
18908        fakeGestureTouched = false;
18909        fakeGestureMoved = false;
18910        if (!gesture.imageEl) return;
18911        zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);
18912        gesture.imageEl.style.transitionDuration = `${swiper.params.speed}ms`;
18913        gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
18914        currentScale = zoom.scale;
18915        isScaling = false;
18916        if (zoom.scale > 1 && gesture.slideEl) {
18917            gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
18918        } else if (zoom.scale <= 1 && gesture.slideEl) {
18919            gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
18920        }
18921        if (zoom.scale === 1) {
18922            gesture.originX = 0;
18923            gesture.originY = 0;
18924            gesture.slideEl = undefined;
18925        }
18926    }
18927
18928    let allowTouchMoveTimeout;
18929
18930    function allowTouchMove() {
18931        swiper.touchEventsData.preventTouchMoveFromPointerMove = false;
18932    }
18933
18934    function preventTouchMove() {
18935        clearTimeout(allowTouchMoveTimeout);
18936        swiper.touchEventsData.preventTouchMoveFromPointerMove = true;
18937        allowTouchMoveTimeout = setTimeout(() => {
18938            if (swiper.destroyed) return;
18939            allowTouchMove();
18940        });
18941    }
18942
18943    function onTouchStart(e) {
18944        const device = swiper.device;
18945        if (!gesture.imageEl) return;
18946        if (image.isTouched) return;
18947        if (device.android && e.cancelable) e.preventDefault();
18948        image.isTouched = true;
18949        const event = evCache.length > 0 ? evCache[0] : e;
18950        image.touchesStart.x = event.pageX;
18951        image.touchesStart.y = event.pageY;
18952    }
18953
18954    function onTouchMove(e) {
18955        const isMouseEvent = e.pointerType === 'mouse';
18956        const isMousePan = isMouseEvent && swiper.params.zoom.panOnMouseMove;
18957        if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) {
18958            return;
18959        }
18960        const zoom = swiper.zoom;
18961        if (!gesture.imageEl) {
18962            return;
18963        }
18964        if (!image.isTouched || !gesture.slideEl) {
18965            if (isMousePan) onMouseMove(e);
18966            return;
18967        }
18968        if (isMousePan) {
18969            onMouseMove(e);
18970            return;
18971        }
18972        if (!image.isMoved) {
18973            image.width = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth;
18974            image.height = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight;
18975            image.startX = getTranslate(gesture.imageWrapEl, 'x') || 0;
18976            image.startY = getTranslate(gesture.imageWrapEl, 'y') || 0;
18977            gesture.slideWidth = gesture.slideEl.offsetWidth;
18978            gesture.slideHeight = gesture.slideEl.offsetHeight;
18979            gesture.imageWrapEl.style.transitionDuration = '0ms';
18980        }
18981        // Define if we need image drag
18982        const scaledWidth = image.width * zoom.scale;
18983        const scaledHeight = image.height * zoom.scale;
18984        image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
18985        image.maxX = -image.minX;
18986        image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
18987        image.maxY = -image.minY;
18988        image.touchesCurrent.x = evCache.length > 0 ? evCache[0].pageX : e.pageX;
18989        image.touchesCurrent.y = evCache.length > 0 ? evCache[0].pageY : e.pageY;
18990        const touchesDiff = Math.max(Math.abs(image.touchesCurrent.x - image.touchesStart.x), Math.abs(image.touchesCurrent.y - image.touchesStart.y));
18991        if (touchesDiff > 5) {
18992            swiper.allowClick = false;
vendor: 4,960 bytes, lines 18993-19087
18993        }
18994        if (!image.isMoved && !isScaling) {
18995            if (swiper.isHorizontal() && (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x || Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x)) {
18996                image.isTouched = false;
18997                allowTouchMove();
18998                return;
18999            }
19000            if (!swiper.isHorizontal() && (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y || Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y)) {
19001                image.isTouched = false;
19002                allowTouchMove();
19003                return;
19004            }
19005        }
19006        if (e.cancelable) {
19007            e.preventDefault();
19008        }
19009        e.stopPropagation();
19010        preventTouchMove();
19011        image.isMoved = true;
19012        const scaleRatio = (zoom.scale - currentScale) / (gesture.maxRatio - swiper.params.zoom.minRatio);
19013        const {
19014            originX,
19015            originY
19016        } = gesture;
19017        image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX + scaleRatio * (image.width - originX * 2);
19018        image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY + scaleRatio * (image.height - originY * 2);
19019        if (image.currentX < image.minX) {
19020            image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8;
19021        }
19022        if (image.currentX > image.maxX) {
19023            image.currentX = image.maxX - 1 + (image.currentX - image.maxX + 1) ** 0.8;
19024        }
19025        if (image.currentY < image.minY) {
19026            image.currentY = image.minY + 1 - (image.minY - image.currentY + 1) ** 0.8;
19027        }
19028        if (image.currentY > image.maxY) {
19029            image.currentY = image.maxY - 1 + (image.currentY - image.maxY + 1) ** 0.8;
19030        }
19031
19032        // Velocity
19033        if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x;
19034        if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y;
19035        if (!velocity.prevTime) velocity.prevTime = Date.now();
19036        velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;
19037        velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;
19038        if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0;
19039        if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0;
19040        velocity.prevPositionX = image.touchesCurrent.x;
19041        velocity.prevPositionY = image.touchesCurrent.y;
19042        velocity.prevTime = Date.now();
19043        gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
19044    }
19045
19046    function onTouchEnd() {
19047        const zoom = swiper.zoom;
19048        evCache.length = 0;
19049        if (!gesture.imageEl) return;
19050        if (!image.isTouched || !image.isMoved) {
19051            image.isTouched = false;
19052            image.isMoved = false;
19053            return;
19054        }
19055        image.isTouched = false;
19056        image.isMoved = false;
19057        let momentumDurationX = 300;
19058        let momentumDurationY = 300;
19059        const momentumDistanceX = velocity.x * momentumDurationX;
19060        const newPositionX = image.currentX + momentumDistanceX;
19061        const momentumDistanceY = velocity.y * momentumDurationY;
19062        const newPositionY = image.currentY + momentumDistanceY;
19063
19064        // Fix duration
19065        if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x);
19066        if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y);
19067        const momentumDuration = Math.max(momentumDurationX, momentumDurationY);
19068        image.currentX = newPositionX;
19069        image.currentY = newPositionY;
19070        // Define if we need image drag
19071        const scaledWidth = image.width * zoom.scale;
19072        const scaledHeight = image.height * zoom.scale;
19073        image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0);
19074        image.maxX = -image.minX;
19075        image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0);
19076        image.maxY = -image.minY;
19077        image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);
19078        image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);
19079        gesture.imageWrapEl.style.transitionDuration = `${momentumDuration}ms`;
19080        gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`;
19081    }
19082
19083    function onTransitionEnd() {
19084        const zoom = swiper.zoom;
19085        if (gesture.slideEl && swiper.activeIndex !== swiper.slides.indexOf(gesture.slideEl)) {
19086            if (gesture.imageEl) {
19087                gesture.imageEl.style.transform = 'translate3d(0,
vendor: 44,439 bytes, lines 19087-20292
190870,0) scale(1)';
19088            }
19089            if (gesture.imageWrapEl) {
19090                gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
19091            }
19092            gesture.slideEl.classList.remove(`${swiper.params.zoom.zoomedSlideClass}`);
19093            zoom.scale = 1;
19094            currentScale = 1;
19095            gesture.slideEl = undefined;
19096            gesture.imageEl = undefined;
19097            gesture.imageWrapEl = undefined;
19098            gesture.originX = 0;
19099            gesture.originY = 0;
19100        }
19101    }
19102
19103    function onMouseMove(e) {
19104        // Only pan if zoomed in and mouse panning is enabled
19105        if (currentScale <= 1 || !gesture.imageWrapEl) return;
19106        if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) return;
19107        const currentTransform = window.getComputedStyle(gesture.imageWrapEl).transform;
19108        const matrix = new window.DOMMatrix(currentTransform);
19109        if (!isPanningWithMouse) {
19110            isPanningWithMouse = true;
19111            mousePanStart.x = e.clientX;
19112            mousePanStart.y = e.clientY;
19113            image.startX = matrix.e;
19114            image.startY = matrix.f;
19115            image.width = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth;
19116            image.height = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight;
19117            gesture.slideWidth = gesture.slideEl.offsetWidth;
19118            gesture.slideHeight = gesture.slideEl.offsetHeight;
19119            return;
19120        }
19121        const deltaX = (e.clientX - mousePanStart.x) * mousePanSensitivity;
19122        const deltaY = (e.clientY - mousePanStart.y) * mousePanSensitivity;
19123        const scaledWidth = image.width * currentScale;
19124        const scaledHeight = image.height * currentScale;
19125        const slideWidth = gesture.slideWidth;
19126        const slideHeight = gesture.slideHeight;
19127        const minX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);
19128        const maxX = -minX;
19129        const minY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);
19130        const maxY = -minY;
19131        const newX = Math.max(Math.min(image.startX + deltaX, maxX), minX);
19132        const newY = Math.max(Math.min(image.startY + deltaY, maxY), minY);
19133        gesture.imageWrapEl.style.transitionDuration = '0ms';
19134        gesture.imageWrapEl.style.transform = `translate3d(${newX}px, ${newY}px, 0)`;
19135        mousePanStart.x = e.clientX;
19136        mousePanStart.y = e.clientY;
19137        image.startX = newX;
19138        image.startY = newY;
19139        image.currentX = newX;
19140        image.currentY = newY;
19141    }
19142
19143    function zoomIn(e) {
19144        const zoom = swiper.zoom;
19145        const params = swiper.params.zoom;
19146        if (!gesture.slideEl) {
19147            if (e && e.target) {
19148                gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
19149            }
19150            if (!gesture.slideEl) {
19151                if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
19152                    gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
19153                } else {
19154                    gesture.slideEl = swiper.slides[swiper.activeIndex];
19155                }
19156            }
19157            let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
19158            if (imageEl) {
19159                imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
19160            }
19161            gesture.imageEl = imageEl;
19162            if (imageEl) {
19163                gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
19164            } else {
19165                gesture.imageWrapEl = undefined;
19166            }
19167        }
19168        if (!gesture.imageEl || !gesture.imageWrapEl) return;
19169        if (swiper.params.cssMode) {
19170            swiper.wrapperEl.style.overflow = 'hidden';
19171            swiper.wrapperEl.style.touchAction = 'none';
19172        }
19173        gesture.slideEl.classList.add(`${params.zoomedSlideClass}`);
19174        let touchX;
19175        let touchY;
19176        let offsetX;
19177        let offsetY;
19178        let diffX;
19179        let diffY;
19180        let translateX;
19181        let translateY;
19182        let imageWidth;
19183        let imageHeight;
19184        let scaledWidth;
19185        let scaledHeight;
19186        let translateMinX;
19187        let translateMinY;
19188        let translateMaxX;
19189        let translateMaxY;
19190        let slideWidth;
19191        let slideHeight;
19192        if (typeof image.touchesStart.x === 'undefined' && e) {
19193            touchX = e.pageX;
19194            touchY = e.pageY;
19195        } else {
19196            touchX = image.touchesStart.x;
19197            touchY = image.touchesStart.y;
19198        }
19199        const prevScale = currentScale;
19200        const forceZoomRatio = typeof e === 'number' ? e : null;
19201        if (currentScale === 1 && forceZoomRatio) {
19202            touchX = undefined;
19203            touchY = undefined;
19204            image.touchesStart.x = undefined;
19205            image.touchesStart.y = undefined;
19206        }
19207        const maxRatio = getMaxRatio();
19208        zoom.scale = forceZoomRatio || maxRatio;
19209        currentScale = forceZoomRatio || maxRatio;
19210        if (e && !(currentScale === 1 && forceZoomRatio)) {
19211            slideWidth = gesture.slideEl.offsetWidth;
19212            slideHeight = gesture.slideEl.offsetHeight;
19213            offsetX = elementOffset(gesture.slideEl).left + window.scrollX;
19214            offsetY = elementOffset(gesture.slideEl).top + window.scrollY;
19215            diffX = offsetX + slideWidth / 2 - touchX;
19216            diffY = offsetY + slideHeight / 2 - touchY;
19217            imageWidth = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth;
19218            imageHeight = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight;
19219            scaledWidth = imageWidth * zoom.scale;
19220            scaledHeight = imageHeight * zoom.scale;
19221            translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0);
19222            translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0);
19223            translateMaxX = -translateMinX;
19224            translateMaxY = -translateMinY;
19225            if (prevScale > 0 && forceZoomRatio && typeof image.currentX === 'number' && typeof image.currentY === 'number') {
19226                translateX = image.currentX * zoom.scale / prevScale;
19227                translateY = image.currentY * zoom.scale / prevScale;
19228            } else {
19229                translateX = diffX * zoom.scale;
19230                translateY = diffY * zoom.scale;
19231            }
19232            if (translateX < translateMinX) {
19233                translateX = translateMinX;
19234            }
19235            if (translateX > translateMaxX) {
19236                translateX = translateMaxX;
19237            }
19238            if (translateY < translateMinY) {
19239                translateY = translateMinY;
19240            }
19241            if (translateY > translateMaxY) {
19242                translateY = translateMaxY;
19243            }
19244        } else {
19245            translateX = 0;
19246            translateY = 0;
19247        }
19248        if (forceZoomRatio && zoom.scale === 1) {
19249            gesture.originX = 0;
19250            gesture.originY = 0;
19251        }
19252        image.currentX = translateX;
19253        image.currentY = translateY;
19254        gesture.imageWrapEl.style.transitionDuration = '300ms';
19255        gesture.imageWrapEl.style.transform = `translate3d(${translateX}px, ${translateY}px,0)`;
19256        gesture.imageEl.style.transitionDuration = '300ms';
19257        gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`;
19258    }
19259
19260    function zoomOut() {
19261        const zoom = swiper.zoom;
19262        const params = swiper.params.zoom;
19263        if (!gesture.slideEl) {
19264            if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) {
19265                gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0];
19266            } else {
19267                gesture.slideEl = swiper.slides[swiper.activeIndex];
19268            }
19269            let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`);
19270            if (imageEl) {
19271                imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0];
19272            }
19273            gesture.imageEl = imageEl;
19274            if (imageEl) {
19275                gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0];
19276            } else {
19277                gesture.imageWrapEl = undefined;
19278            }
19279        }
19280        if (!gesture.imageEl || !gesture.imageWrapEl) return;
19281        if (swiper.params.cssMode) {
19282            swiper.wrapperEl.style.overflow = '';
19283            swiper.wrapperEl.style.touchAction = '';
19284        }
19285        zoom.scale = 1;
19286        currentScale = 1;
19287        image.currentX = undefined;
19288        image.currentY = undefined;
19289        image.touchesStart.x = undefined;
19290        image.touchesStart.y = undefined;
19291        gesture.imageWrapEl.style.transitionDuration = '300ms';
19292        gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)';
19293        gesture.imageEl.style.transitionDuration = '300ms';
19294        gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)';
19295        gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`);
19296        gesture.slideEl = undefined;
19297        gesture.originX = 0;
19298        gesture.originY = 0;
19299        if (swiper.params.zoom.panOnMouseMove) {
19300            mousePanStart = {
19301                x: 0,
19302                y: 0
19303            };
19304            if (isPanningWithMouse) {
19305                isPanningWithMouse = false;
19306                image.startX = 0;
19307                image.startY = 0;
19308            }
19309        }
19310    }
19311
19312    // Toggle Zoom
19313    function zoomToggle(e) {
19314        const zoom = swiper.zoom;
19315        if (zoom.scale && zoom.scale !== 1) {
19316            // Zoom Out
19317            zoomOut();
19318        } else {
19319            // Zoom In
19320            zoomIn(e);
19321        }
19322    }
19323
19324    function getListeners() {
19325        const passiveListener = swiper.params.passiveListeners ? {
19326            passive: true,
19327            capture: false
19328        } : false;
19329        const activeListenerWithCapture = swiper.params.passiveListeners ? {
19330            passive: false,
19331            capture: true
19332        } : true;
19333        return {
19334            passiveListener,
19335            activeListenerWithCapture
19336        };
19337    }
19338
19339    // Attach/Detach Events
19340    function enable() {
19341        const zoom = swiper.zoom;
19342        if (zoom.enabled) return;
19343        zoom.enabled = true;
19344        const {
19345            passiveListener,
19346            activeListenerWithCapture
19347        } = getListeners();
19348
19349        // Scale image
19350        swiper.wrapperEl.addEventListener('pointerdown', onGestureStart, passiveListener);
19351        swiper.wrapperEl.addEventListener('pointermove', onGestureChange, activeListenerWithCapture);
19352        ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {
19353            swiper.wrapperEl.addEventListener(eventName, onGestureEnd, passiveListener);
19354        });
19355
19356        // Move image
19357        swiper.wrapperEl.addEventListener('pointermove', onTouchMove, activeListenerWithCapture);
19358    }
19359
19360    function disable() {
19361        const zoom = swiper.zoom;
19362        if (!zoom.enabled) return;
19363        zoom.enabled = false;
19364        const {
19365            passiveListener,
19366            activeListenerWithCapture
19367        } = getListeners();
19368
19369        // Scale image
19370        swiper.wrapperEl.removeEventListener('pointerdown', onGestureStart, passiveListener);
19371        swiper.wrapperEl.removeEventListener('pointermove', onGestureChange, activeListenerWithCapture);
19372        ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => {
19373            swiper.wrapperEl.removeEventListener(eventName, onGestureEnd, passiveListener);
19374        });
19375
19376        // Move image
19377        swiper.wrapperEl.removeEventListener('pointermove', onTouchMove, activeListenerWithCapture);
19378    }
19379
19380    on('init', () => {
19381        if (swiper.params.zoom.enabled) {
19382            enable();
19383        }
19384    });
19385    on('destroy', () => {
19386        disable();
19387    });
19388    on('touchStart', (_s, e) => {
19389        if (!swiper.zoom.enabled) return;
19390        onTouchStart(e);
19391    });
19392    on('touchEnd', (_s, e) => {
19393        if (!swiper.zoom.enabled) return;
19394        onTouchEnd();
19395    });
19396    on('doubleTap', (_s, e) => {
19397        if (!swiper.animating && swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {
19398            zoomToggle(e);
19399        }
19400    });
19401    on('transitionEnd', () => {
19402        if (swiper.zoom.enabled && swiper.params.zoom.enabled) {
19403            onTransitionEnd();
19404        }
19405    });
19406    on('slideChange', () => {
19407        if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) {
19408            onTransitionEnd();
19409        }
19410    });
19411    Object.assign(swiper.zoom, {
19412        enable,
19413        disable,
19414        in: zoomIn,
19415        out: zoomOut,
19416        toggle: zoomToggle
19417    });
19418}
19419
19420/* eslint no-bitwise: ["error", { "allow": [">>"] }] */
19421function Controller(_ref) {
19422    let {
19423        swiper,
19424        extendParams,
19425        on
19426    } = _ref;
19427    extendParams({
19428        controller: {
19429            control: undefined,
19430            inverse: false,
19431            by: 'slide' // or 'container'
19432        }
19433    });
19434
19435    swiper.controller = {
19436        control: undefined
19437    };
19438
19439    function LinearSpline(x, y) {
19440        const binarySearch = function search() {
19441            let maxIndex;
19442            let minIndex;
19443            let guess;
19444            return (array, val) => {
19445                minIndex = -1;
19446                maxIndex = array.length;
19447                while (maxIndex - minIndex > 1) {
19448                    guess = maxIndex + minIndex >> 1;
19449                    if (array[guess] <= val) {
19450                        minIndex = guess;
19451                    } else {
19452                        maxIndex = guess;
19453                    }
19454                }
19455                return maxIndex;
19456            };
19457        }();
19458        this.x = x;
19459        this.y = y;
19460        this.lastIndex = x.length - 1;
19461        // Given an x value (x2), return the expected y2 value:
19462        // (x1,y1) is the known point before given value,
19463        // (x3,y3) is the known point after given value.
19464        let i1;
19465        let i3;
19466        this.interpolate = function interpolate(x2) {
19467            if (!x2) return 0;
19468
19469            // Get the indexes of x1 and x3 (the array indexes before and after given x2):
19470            i3 = binarySearch(this.x, x2);
19471            i1 = i3 - 1;
19472
19473            // We have our indexes i1 & i3, so we can calculate already:
19474            // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
19475            return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1];
19476        };
19477        return this;
19478    }
19479
19480    function getInterpolateFunction(c) {
19481        swiper.controller.spline = swiper.params.loop ? new LinearSpline(swiper.slidesGrid, c.slidesGrid) : new LinearSpline(swiper.snapGrid, c.snapGrid);
19482    }
19483
19484    function setTranslate(_t, byController) {
19485        const controlled = swiper.controller.control;
19486        let multiplier;
19487        let controlledTranslate;
19488        const Swiper = swiper.constructor;
19489
19490        function setControlledTranslate(c) {
19491            if (c.destroyed) return;
19492
19493            // this will create an Interpolate function based on the snapGrids
19494            // x is the Grid of the scrolled scroller and y will be the controlled scroller
19495            // it makes sense to create this only once and recall it for the interpolation
19496            // the function does a lot of value caching for performance
19497            const translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate;
19498            if (swiper.params.controller.by === 'slide') {
19499                getInterpolateFunction(c);
19500                // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
19501                // but it did not work out
19502                controlledTranslate = -swiper.controller.spline.interpolate(-translate);
19503            }
19504            if (!controlledTranslate || swiper.params.controller.by === 'container') {
19505                multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate());
19506                if (Number.isNaN(multiplier) || !Number.isFinite(multiplier)) {
19507                    multiplier = 1;
19508                }
19509                controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate();
19510            }
19511            if (swiper.params.controller.inverse) {
19512                controlledTranslate = c.maxTranslate() - controlledTranslate;
19513            }
19514            c.updateProgress(controlledTranslate);
19515            c.setTranslate(controlledTranslate, swiper);
19516            c.updateActiveIndex();
19517            c.updateSlidesClasses();
19518        }
19519
19520        if (Array.isArray(controlled)) {
19521            for (let i = 0; i < controlled.length; i += 1) {
19522                if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
19523                    setControlledTranslate(controlled[i]);
19524                }
19525            }
19526        } else if (controlled instanceof Swiper && byController !== controlled) {
19527            setControlledTranslate(controlled);
19528        }
19529    }
19530
19531    function setTransition(duration, byController) {
19532        const Swiper = swiper.constructor;
19533        const controlled = swiper.controller.control;
19534        let i;
19535
19536        function setControlledTransition(c) {
19537            if (c.destroyed) return;
19538            c.setTransition(duration, swiper);
19539            if (duration !== 0) {
19540                c.transitionStart();
19541                if (c.params.autoHeight) {
19542                    nextTick(() => {
19543                        c.updateAutoHeight();
19544                    });
19545                }
19546                elementTransitionEnd(c.wrapperEl, () => {
19547                    if (!controlled) return;
19548                    c.transitionEnd();
19549                });
19550            }
19551        }
19552
19553        if (Array.isArray(controlled)) {
19554            for (i = 0; i < controlled.length; i += 1) {
19555                if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
19556                    setControlledTransition(controlled[i]);
19557                }
19558            }
19559        } else if (controlled instanceof Swiper && byController !== controlled) {
19560            setControlledTransition(controlled);
19561        }
19562    }
19563
19564    function removeSpline() {
19565        if (!swiper.controller.control) return;
19566        if (swiper.controller.spline) {
19567            swiper.controller.spline = undefined;
19568            delete swiper.controller.spline;
19569        }
19570    }
19571
19572    on('beforeInit', () => {
19573        if (typeof window !== 'undefined' && (
19574            // eslint-disable-line
19575            typeof swiper.params.controller.control === 'string' || swiper.params.controller.control instanceof HTMLElement)) {
19576            const controlElements = typeof swiper.params.controller.control === 'string' ? [...document.querySelectorAll(swiper.params.controller.control)] : [swiper.params.controller.control];
19577            controlElements.forEach(controlElement => {
19578                if (!swiper.controller.control) swiper.controller.control = [];
19579                if (controlElement && controlElement.swiper) {
19580                    swiper.controller.control.push(controlElement.swiper);
19581                } else if (controlElement) {
19582                    const eventName = `${swiper.params.eventsPrefix}init`;
19583                    const onControllerSwiper = e => {
19584                        swiper.controller.control.push(e.detail[0]);
19585                        swiper.update();
19586                        controlElement.removeEventListener(eventName, onControllerSwiper);
19587                    };
19588                    controlElement.addEventListener(eventName, onControllerSwiper);
19589                }
19590            });
19591            return;
19592        }
19593        swiper.controller.control = swiper.params.controller.control;
19594    });
19595    on('update', () => {
19596        removeSpline();
19597    });
19598    on('resize', () => {
19599        removeSpline();
19600    });
19601    on('observerUpdate', () => {
19602        removeSpline();
19603    });
19604    on('setTranslate', (_s, translate, byController) => {
19605        if (!swiper.controller.control || swiper.controller.control.destroyed) return;
19606        swiper.controller.setTranslate(translate, byController);
19607    });
19608    on('setTransition', (_s, duration, byController) => {
19609        if (!swiper.controller.control || swiper.controller.control.destroyed) return;
19610        swiper.controller.setTransition(duration, byController);
19611    });
19612    Object.assign(swiper.controller, {
19613        setTranslate,
19614        setTransition
19615    });
19616}
19617
19618function A11y(_ref) {
19619    let {
19620        swiper,
19621        extendParams,
19622        on
19623    } = _ref;
19624    extendParams({
19625        a11y: {
19626            enabled: true,
19627            notificationClass: 'swiper-notification',
19628            prevSlideMessage: 'Previous slide',
19629            nextSlideMessage: 'Next slide',
19630            firstSlideMessage: 'This is the first slide',
19631            lastSlideMessage: 'This is the last slide',
19632            paginationBulletMessage: 'Go to slide {{index}}',
19633            slideLabelMessage: '{{index}} / {{slidesLength}}',
19634            containerMessage: null,
19635            containerRoleDescriptionMessage: null,
19636            containerRole: null,
19637            itemRoleDescriptionMessage: null,
19638            slideRole: 'group',
19639            id: null,
19640            scrollOnFocus: true
19641        }
19642    });
19643    swiper.a11y = {
19644        clicked: false
19645    };
19646    let liveRegion = null;
19647    let preventFocusHandler;
19648    let focusTargetSlideEl;
19649    let visibilityChangedTimestamp = new Date().getTime();
19650
19651    function notify(message) {
19652        const notification = liveRegion;
19653        if (notification.length === 0) return;
19654        setInnerHTML(notification, message);
19655    }
19656
19657    function getRandomNumber(size) {
19658        const randomChar = () => Math.round(16 * Math.random()).toString(16);
19659        return 'x'.repeat(size).replace(/x/g, randomChar);
19660    }
19661
19662    function makeElFocusable(el) {
19663        el = makeElementsArray(el);
19664        el.forEach(subEl => {
19665            subEl.setAttribute('tabIndex', '0');
19666        });
19667    }
19668
19669    function makeElNotFocusable(el) {
19670        el = makeElementsArray(el);
19671        el.forEach(subEl => {
19672            subEl.setAttribute('tabIndex', '-1');
19673        });
19674    }
19675
19676    function addElRole(el, role) {
19677        el = makeElementsArray(el);
19678        el.forEach(subEl => {
19679            subEl.setAttribute('role', role);
19680        });
19681    }
19682
19683    function addElRoleDescription(el, description) {
19684        el = makeElementsArray(el);
19685        el.forEach(subEl => {
19686            subEl.setAttribute('aria-roledescription', description);
19687        });
19688    }
19689
19690    function addElControls(el, controls) {
19691        el = makeElementsArray(el);
19692        el.forEach(subEl => {
19693            subEl.setAttribute('aria-controls', controls);
19694        });
19695    }
19696
19697    function addElLabel(el, label) {
19698        el = makeElementsArray(el);
19699        el.forEach(subEl => {
19700            subEl.setAttribute('aria-label', label);
19701        });
19702    }
19703
19704    function addElId(el, id) {
19705        el = makeElementsArray(el);
19706        el.forEach(subEl => {
19707            subEl.setAttribute('id', id);
19708        });
19709    }
19710
19711    function addElLive(el, live) {
19712        el = makeElementsArray(el);
19713        el.forEach(subEl => {
19714            subEl.setAttribute('aria-live', live);
19715        });
19716    }
19717
19718    function disableEl(el) {
19719        el = makeElementsArray(el);
19720        el.forEach(subEl => {
19721            subEl.setAttribute('aria-disabled', true);
19722        });
19723    }
19724
19725    function enableEl(el) {
19726        el = makeElementsArray(el);
19727        el.forEach(subEl => {
19728            subEl.setAttribute('aria-disabled', false);
19729        });
19730    }
19731
19732    function onEnterOrSpaceKey(e) {
19733        if (e.keyCode !== 13 && e.keyCode !== 32) return;
19734        const params = swiper.params.a11y;
19735        const targetEl = e.target;
19736        if (swiper.pagination && swiper.pagination.el && (targetEl === swiper.pagination.el || swiper.pagination.el.contains(e.target))) {
19737            if (!e.target.matches(classesToSelector(swiper.params.pagination.bulletClass))) return;
19738        }
19739        if (swiper.navigation && swiper.navigation.prevEl && swiper.navigation.nextEl) {
19740            const prevEls = makeElementsArray(swiper.navigation.prevEl);
19741            const nextEls = makeElementsArray(swiper.navigation.nextEl);
19742            if (nextEls.includes(targetEl)) {
19743                if (!(swiper.isEnd && !swiper.params.loop)) {
19744                    swiper.slideNext();
19745                }
19746                if (swiper.isEnd) {
19747                    notify(params.lastSlideMessage);
19748                } else {
19749                    notify(params.nextSlideMessage);
19750                }
19751            }
19752            if (prevEls.includes(targetEl)) {
19753                if (!(swiper.isBeginning && !swiper.params.loop)) {
19754                    swiper.slidePrev();
19755                }
19756                if (swiper.isBeginning) {
19757                    notify(params.firstSlideMessage);
19758                } else {
19759                    notify(params.prevSlideMessage);
19760                }
19761            }
19762        }
19763        if (swiper.pagination && targetEl.matches(classesToSelector(swiper.params.pagination.bulletClass))) {
19764            targetEl.click();
19765        }
19766    }
19767
19768    function updateNavigation() {
19769        if (swiper.params.loop || swiper.params.rewind || !swiper.navigation) return;
19770        const {
19771            nextEl,
19772            prevEl
19773        } = swiper.navigation;
19774        if (prevEl) {
19775            if (swiper.isBeginning) {
19776                disableEl(prevEl);
19777                makeElNotFocusable(prevEl);
19778            } else {
19779                enableEl(prevEl);
19780                makeElFocusable(prevEl);
19781            }
19782        }
19783        if (nextEl) {
19784            if (swiper.isEnd) {
19785                disableEl(nextEl);
19786                makeElNotFocusable(nextEl);
19787            } else {
19788                enableEl(nextEl);
19789                makeElFocusable(nextEl);
19790            }
19791        }
19792    }
19793
19794    function hasPagination() {
19795        return swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length;
19796    }
19797
19798    function hasClickablePagination() {
19799        return hasPagination() && swiper.params.pagination.clickable;
19800    }
19801
19802    function updatePagination() {
19803        const params = swiper.params.a11y;
19804        if (!hasPagination()) return;
19805        swiper.pagination.bullets.forEach(bulletEl => {
19806            if (swiper.params.pagination.clickable) {
19807                makeElFocusable(bulletEl);
19808                if (!swiper.params.pagination.renderBullet) {
19809                    addElRole(bulletEl, 'button');
19810                    addElLabel(bulletEl, params.paginationBulletMessage.replace(/\{\{index\}\}/, elementIndex(bulletEl) + 1));
19811                }
19812            }
19813            if (bulletEl.matches(classesToSelector(swiper.params.pagination.bulletActiveClass))) {
19814                bulletEl.setAttribute('aria-current', 'true');
19815            } else {
19816                bulletEl.removeAttribute('aria-current');
19817            }
19818        });
19819    }
19820
19821    const initNavEl = (el, wrapperId, message) => {
19822        makeElFocusable(el);
19823        if (el.tagName !== 'BUTTON') {
19824            addElRole(el, 'button');
19825            el.addEventListener('keydown', onEnterOrSpaceKey);
19826        }
19827        addElLabel(el, message);
19828        addElControls(el, wrapperId);
19829    };
19830    const handlePointerDown = e => {
19831        if (focusTargetSlideEl && focusTargetSlideEl !== e.target && !focusTargetSlideEl.contains(e.target)) {
19832            preventFocusHandler = true;
19833        }
19834        swiper.a11y.clicked = true;
19835    };
19836    const handlePointerUp = () => {
19837        preventFocusHandler = false;
19838        requestAnimationFrame(() => {
19839            requestAnimationFrame(() => {
19840                if (!swiper.destroyed) {
19841                    swiper.a11y.clicked = false;
19842                }
19843            });
19844        });
19845    };
19846    const onVisibilityChange = e => {
19847        visibilityChangedTimestamp = new Date().getTime();
19848    };
19849    const handleFocus = e => {
19850        if (swiper.a11y.clicked || !swiper.params.a11y.scrollOnFocus) return;
19851        if (new Date().getTime() - visibilityChangedTimestamp < 100) return;
19852        const slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`);
19853        if (!slideEl || !swiper.slides.includes(slideEl)) return;
19854        focusTargetSlideEl = slideEl;
19855        const isActive = swiper.slides.indexOf(slideEl) === swiper.activeIndex;
19856        const isVisible = swiper.params.watchSlidesProgress && swiper.visibleSlides && swiper.visibleSlides.includes(slideEl);
19857        if (isActive || isVisible) return;
19858        if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents) return;
19859        if (swiper.isHorizontal()) {
19860            swiper.el.scrollLeft = 0;
19861        } else {
19862            swiper.el.scrollTop = 0;
19863        }
19864        requestAnimationFrame(() => {
19865            if (preventFocusHandler) return;
19866            if (swiper.params.loop) {
19867                swiper.slideToLoop(swiper.getSlideIndexWhenGrid(parseInt(slideEl.getAttribute('data-swiper-slide-index'))), 0);
19868            } else {
19869                swiper.slideTo(swiper.getSlideIndexWhenGrid(swiper.slides.indexOf(slideEl)), 0);
19870            }
19871            preventFocusHandler = false;
19872        });
19873    };
19874    const initSlides = () => {
19875        const params = swiper.params.a11y;
19876        if (params.itemRoleDescriptionMessage) {
19877            addElRoleDescription(swiper.slides, params.itemRoleDescriptionMessage);
19878        }
19879        if (params.slideRole) {
19880            addElRole(swiper.slides, params.slideRole);
19881        }
19882        const slidesLength = swiper.slides.length;
19883        if (params.slideLabelMessage) {
19884            swiper.slides.forEach((slideEl, index) => {
19885                const slideIndex = swiper.params.loop ? parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10) : index;
19886                const ariaLabelMessage = params.slideLabelMessage.replace(/\{\{index\}\}/, slideIndex + 1).replace(/\{\{slidesLength\}\}/, slidesLength);
19887                addElLabel(slideEl, ariaLabelMessage);
19888            });
19889        }
19890    };
19891    const init = () => {
19892        const params = swiper.params.a11y;
19893        swiper.el.append(liveRegion);
19894
19895        // Container
19896        const containerEl = swiper.el;
19897        if (params.containerRoleDescriptionMessage) {
19898            addElRoleDescription(containerEl, params.containerRoleDescriptionMessage);
19899        }
19900        if (params.containerMessage) {
19901            addElLabel(containerEl, params.containerMessage);
19902        }
19903        if (params.containerRole) {
19904            addElRole(containerEl, params.containerRole);
19905        }
19906
19907        // Wrapper
19908        const wrapperEl = swiper.wrapperEl;
19909        const wrapperId = params.id || wrapperEl.getAttribute('id') || `swiper-wrapper-${getRandomNumber(16)}`;
19910        const live = swiper.params.autoplay && swiper.params.autoplay.enabled ? 'off' : 'polite';
19911        addElId(wrapperEl, wrapperId);
19912        addElLive(wrapperEl, live);
19913
19914        // Slide
19915        initSlides();
19916
19917        // Navigation
19918        let {
19919            nextEl,
19920            prevEl
19921        } = swiper.navigation ? swiper.navigation : {};
19922        nextEl = makeElementsArray(nextEl);
19923        prevEl = makeElementsArray(prevEl);
19924        if (nextEl) {
19925            nextEl.forEach(el => initNavEl(el, wrapperId, params.nextSlideMessage));
19926        }
19927        if (prevEl) {
19928            prevEl.forEach(el => initNavEl(el, wrapperId, params.prevSlideMessage));
19929        }
19930
19931        // Pagination
19932        if (hasClickablePagination()) {
19933            const paginationEl = makeElementsArray(swiper.pagination.el);
19934            paginationEl.forEach(el => {
19935                el.addEventListener('keydown', onEnterOrSpaceKey);
19936            });
19937        }
19938
19939        // Tab focus
19940        const document = getDocument();
19941        document.addEventListener('visibilitychange', onVisibilityChange);
19942        swiper.el.addEventListener('focus', handleFocus, true);
19943        swiper.el.addEventListener('focus', handleFocus, true);
19944        swiper.el.addEventListener('pointerdown', handlePointerDown, true);
19945        swiper.el.addEventListener('pointerup', handlePointerUp, true);
19946    };
19947
19948    function destroy() {
19949        if (liveRegion) liveRegion.remove();
19950        let {
19951            nextEl,
19952            prevEl
19953        } = swiper.navigation ? swiper.navigation : {};
19954        nextEl = makeElementsArray(nextEl);
19955        prevEl = makeElementsArray(prevEl);
19956        if (nextEl) {
19957            nextEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey));
19958        }
19959        if (prevEl) {
19960            prevEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey));
19961        }
19962
19963        // Pagination
19964        if (hasClickablePagination()) {
19965            const paginationEl = makeElementsArray(swiper.pagination.el);
19966            paginationEl.forEach(el => {
19967                el.removeEventListener('keydown', onEnterOrSpaceKey);
19968            });
19969        }
19970        const document = getDocument();
19971        document.removeEventListener('visibilitychange', onVisibilityChange);
19972        // Tab focus
19973        if (swiper.el && typeof swiper.el !== 'string') {
19974            swiper.el.removeEventListener('focus', handleFocus, true);
19975            swiper.el.removeEventListener('pointerdown', handlePointerDown, true);
19976            swiper.el.removeEventListener('pointerup', handlePointerUp, true);
19977        }
19978    }
19979
19980    on('beforeInit', () => {
19981        liveRegion = createElement('span', swiper.params.a11y.notificationClass);
19982        liveRegion.setAttribute('aria-live', 'assertive');
19983        liveRegion.setAttribute('aria-atomic', 'true');
19984    });
19985    on('afterInit', () => {
19986        if (!swiper.params.a11y.enabled) return;
19987        init();
19988    });
19989    on('slidesLengthChange snapGridLengthChange slidesGridLengthChange', () => {
19990        if (!swiper.params.a11y.enabled) return;
19991        initSlides();
19992    });
19993    on('fromEdge toEdge afterInit lock unlock', () => {
19994        if (!swiper.params.a11y.enabled) return;
19995        updateNavigation();
19996    });
19997    on('paginationUpdate', () => {
19998        if (!swiper.params.a11y.enabled) return;
19999        updatePagination();
20000    });
20001    on('destroy', () => {
20002        if (!swiper.params.a11y.enabled) return;
20003        destroy();
20004    });
20005}
20006
20007function History(_ref) {
20008    let {
20009        swiper,
20010        extendParams,
20011        on
20012    } = _ref;
20013    extendParams({
20014        history: {
20015            enabled: false,
20016            root: '',
20017            replaceState: false,
20018            key: 'slides',
20019            keepQuery: false
20020        }
20021    });
20022    let initialized = false;
20023    let paths = {};
20024    const slugify = text => {
20025        return text.toString().replace(/\s+/g, '-').replace(/[^\w-]+/g, '').replace(/--+/g, '-').replace(/^-+/, '').replace(/-+$/, '');
20026    };
20027    const getPathValues = urlOverride => {
20028        const window = getWindow();
20029        let location;
20030        if (urlOverride) {
20031            location = new URL(urlOverride);
20032        } else {
20033            location = window.location;
20034        }
20035        const pathArray = location.pathname.slice(1).split('/').filter(part => part !== '');
20036        const total = pathArray.length;
20037        const key = pathArray[total - 2];
20038        const value = pathArray[total - 1];
20039        return {
20040            key,
20041            value
20042        };
20043    };
20044    const setHistory = (key, index) => {
20045        const window = getWindow();
20046        if (!initialized || !swiper.params.history.enabled) return;
20047        let location;
20048        if (swiper.params.url) {
20049            location = new URL(swiper.params.url);
20050        } else {
20051            location = window.location;
20052        }
20053        const slide = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${index}"]`) : swiper.slides[index];
20054        let value = slugify(slide.getAttribute('data-history'));
20055        if (swiper.params.history.root.length > 0) {
20056            let root = swiper.params.history.root;
20057            if (root[root.length - 1] === '/') root = root.slice(0, root.length - 1);
20058            value = `${root}/${key ? `${key}/` : ''}${value}`;
20059        } else if (!location.pathname.includes(key)) {
20060            value = `${key ? `${key}/` : ''}${value}`;
20061        }
20062        if (swiper.params.history.keepQuery) {
20063            value += location.search;
20064        }
20065        const currentState = window.history.state;
20066        if (currentState && currentState.value === value) {
20067            return;
20068        }
20069        if (swiper.params.history.replaceState) {
20070            window.history.replaceState({
20071                value
20072            }, null, value);
20073        } else {
20074            window.history.pushState({
20075                value
20076            }, null, value);
20077        }
20078    };
20079    const scrollToSlide = (speed, value, runCallbacks) => {
20080        if (value) {
20081            for (let i = 0, length = swiper.slides.length; i < length; i += 1) {
20082                const slide = swiper.slides[i];
20083                const slideHistory = slugify(slide.getAttribute('data-history'));
20084                if (slideHistory === value) {
20085                    const index = swiper.getSlideIndex(slide);
20086                    swiper.slideTo(index, speed, runCallbacks);
20087                }
20088            }
20089        } else {
20090            swiper.slideTo(0, speed, runCallbacks);
20091        }
20092    };
20093    const setHistoryPopState = () => {
20094        paths = getPathValues(swiper.params.url);
20095        scrollToSlide(swiper.params.speed, paths.value, false);
20096    };
20097    const init = () => {
20098        const window = getWindow();
20099        if (!swiper.params.history) return;
20100        if (!window.history || !window.history.pushState) {
20101            swiper.params.history.enabled = false;
20102            swiper.params.hashNavigation.enabled = true;
20103            return;
20104        }
20105        initialized = true;
20106        paths = getPathValues(swiper.params.url);
20107        if (!paths.key && !paths.value) {
20108            if (!swiper.params.history.replaceState) {
20109                window.addEventListener('popstate', setHistoryPopState);
20110            }
20111            return;
20112        }
20113        scrollToSlide(0, paths.value, swiper.params.runCallbacksOnInit);
20114        if (!swiper.params.history.replaceState) {
20115            window.addEventListener('popstate', setHistoryPopState);
20116        }
20117    };
20118    const destroy = () => {
20119        const window = getWindow();
20120        if (!swiper.params.history.replaceState) {
20121            window.removeEventListener('popstate', setHistoryPopState);
20122        }
20123    };
20124    on('init', () => {
20125        if (swiper.params.history.enabled) {
20126            init();
20127        }
20128    });
20129    on('destroy', () => {
20130        if (swiper.params.history.enabled) {
20131            destroy();
20132        }
20133    });
20134    on('transitionEnd _freeModeNoMomentumRelease', () => {
20135        if (initialized) {
20136            setHistory(swiper.params.history.key, swiper.activeIndex);
20137        }
20138    });
20139    on('slideChange', () => {
20140        if (initialized && swiper.params.cssMode) {
20141            setHistory(swiper.params.history.key, swiper.activeIndex);
20142        }
20143    });
20144}
20145
20146function HashNavigation(_ref) {
20147    let {
20148        swiper,
20149        extendParams,
20150        emit,
20151        on
20152    } = _ref;
20153    let initialized = false;
20154    const document = getDocument();
20155    const window = getWindow();
20156    extendParams({
20157        hashNavigation: {
20158            enabled: false,
20159            replaceState: false,
20160            watchState: false,
20161            getSlideIndex(_s, hash) {
20162                if (swiper.virtual && swiper.params.virtual.enabled) {
20163                    const slideWithHash = swiper.slides.find(slideEl => slideEl.getAttribute('data-hash') === hash);
20164                    if (!slideWithHash) return 0;
20165                    const index = parseInt(slideWithHash.getAttribute('data-swiper-slide-index'), 10);
20166                    return index;
20167                }
20168                return swiper.getSlideIndex(elementChildren(swiper.slidesEl, `.${swiper.params.slideClass}[data-hash="${hash}"], swiper-slide[data-hash="${hash}"]`)[0]);
20169            }
20170        }
20171    });
20172    const onHashChange = () => {
20173        emit('hashChange');
20174        const newHash = document.location.hash.replace('#', '');
20175        const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex];
20176        const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') : '';
20177        if (newHash !== activeSlideHash) {
20178            const newIndex = swiper.params.hashNavigation.getSlideIndex(swiper, newHash);
20179            if (typeof newIndex === 'undefined' || Number.isNaN(newIndex)) return;
20180            swiper.slideTo(newIndex);
20181        }
20182    };
20183    const setHash = () => {
20184        if (!initialized || !swiper.params.hashNavigation.enabled) return;
20185        const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex];
20186        const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') || activeSlideEl.getAttribute('data-history') : '';
20187        if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) {
20188            window.history.replaceState(null, null, `#${activeSlideHash}` || '');
20189            emit('hashSet');
20190        } else {
20191            document.location.hash = activeSlideHash || '';
20192            emit('hashSet');
20193        }
20194    };
20195    const init = () => {
20196        if (!swiper.params.hashNavigation.enabled || swiper.params.history && swiper.params.history.enabled) return;
20197        initialized = true;
20198        const hash = document.location.hash.replace('#', '');
20199        if (hash) {
20200            const speed = 0;
20201            const index = swiper.params.hashNavigation.getSlideIndex(swiper, hash);
20202            swiper.slideTo(index || 0, speed, swiper.params.runCallbacksOnInit, true);
20203        }
20204        if (swiper.params.hashNavigation.watchState) {
20205            window.addEventListener('hashchange', onHashChange);
20206        }
20207    };
20208    const destroy = () => {
20209        if (swiper.params.hashNavigation.watchState) {
20210            window.removeEventListener('hashchange', onHashChange);
20211        }
20212    };
20213    on('init', () => {
20214        if (swiper.params.hashNavigation.enabled) {
20215            init();
20216        }
20217    });
20218    on('destroy', () => {
20219        if (swiper.params.hashNavigation.enabled) {
20220            destroy();
20221        }
20222    });
20223    on('transitionEnd _freeModeNoMomentumRelease', () => {
20224        if (initialized) {
20225            setHash();
20226        }
20227    });
20228    on('slideChange', () => {
20229        if (initialized && swiper.params.cssMode) {
20230            setHash();
20231        }
20232    });
20233}
20234
20235/* eslint no-underscore-dangle: "off" */
20236
20237/* eslint no-use-before-define: "off" */
20238function Autoplay(_ref) {
20239    let {
20240        swiper,
20241        extendParams,
20242        on,
20243        emit,
20244        params
20245    } = _ref;
20246    swiper.autoplay = {
20247        running: false,
20248        paused: false,
20249        timeLeft: 0
20250    };
20251    extendParams({
20252        autoplay: {
20253            enabled: false,
20254            delay: 3000,
20255            waitForTransition: true,
20256            disableOnInteraction: false,
20257            stopOnLastSlide: false,
20258            reverseDirection: false,
20259            pauseOnMouseEnter: false
20260        }
20261    });
20262    let timeout;
20263    let raf;
20264    let autoplayDelayTotal = params && params.autoplay ? params.autoplay.delay : 3000;
20265    let autoplayDelayCurrent = params && params.autoplay ? params.autoplay.delay : 3000;
20266    let autoplayTimeLeft;
20267    let autoplayStartTime = new Date().getTime();
20268    let wasPaused;
20269    let isTouched;
20270    let pausedByTouch;
20271    let touchStartTimeout;
20272    let slideChanged;
20273    let pausedByInteraction;
20274    let pausedByPointerEnter;
20275
20276    function onTransitionEnd(e) {
20277        if (!swiper || swiper.destroyed || !swiper.wrapperEl) return;
20278        if (e.target !== swiper.wrapperEl) return;
20279        swiper.wrapperEl.removeEventListener('transitionend', onTransitionEnd);
20280        if (pausedByPointerEnter || e.detail && e.detail.bySwiperTouchMove) {
20281            return;
20282        }
20283        resume();
20284    }
20285
20286    const calcTimeLeft = () => {
20287        if (swiper.destroyed || !swiper.autoplay.running) return;
20288        if (swiper.autoplay.paused) {
20289            wasPaused = true;
20290        } else if (wasPaused) {
20291            autoplayDelayCurrent = autoplayTimeLeft;
20292            wasPaused = false;
vendor: 4,153 bytes, lines 20293-20398
20293        }
20294        const timeLeft = swiper.autoplay.paused ? autoplayTimeLeft : autoplayStartTime + autoplayDelayCurrent - new Date().getTime();
20295        swiper.autoplay.timeLeft = timeLeft;
20296        emit('autoplayTimeLeft', timeLeft, timeLeft / autoplayDelayTotal);
20297        raf = requestAnimationFrame(() => {
20298            calcTimeLeft();
20299        });
20300    };
20301    const getSlideDelay = () => {
20302        let activeSlideEl;
20303        if (swiper.virtual && swiper.params.virtual.enabled) {
20304            activeSlideEl = swiper.slides.find(slideEl => slideEl.classList.contains('swiper-slide-active'));
20305        } else {
20306            activeSlideEl = swiper.slides[swiper.activeIndex];
20307        }
20308        if (!activeSlideEl) return undefined;
20309        const currentSlideDelay = parseInt(activeSlideEl.getAttribute('data-swiper-autoplay'), 10);
20310        return currentSlideDelay;
20311    };
20312    const run = delayForce => {
20313        if (swiper.destroyed || !swiper.autoplay.running) return;
20314        cancelAnimationFrame(raf);
20315        calcTimeLeft();
20316        let delay = typeof delayForce === 'undefined' ? swiper.params.autoplay.delay : delayForce;
20317        autoplayDelayTotal = swiper.params.autoplay.delay;
20318        autoplayDelayCurrent = swiper.params.autoplay.delay;
20319        const currentSlideDelay = getSlideDelay();
20320        if (!Number.isNaN(currentSlideDelay) && currentSlideDelay > 0 && typeof delayForce === 'undefined') {
20321            delay = currentSlideDelay;
20322            autoplayDelayTotal = currentSlideDelay;
20323            autoplayDelayCurrent = currentSlideDelay;
20324        }
20325        autoplayTimeLeft = delay;
20326        const speed = swiper.params.speed;
20327        const proceed = () => {
20328            if (!swiper || swiper.destroyed) return;
20329            if (swiper.params.autoplay.reverseDirection) {
20330                if (!swiper.isBeginning || swiper.params.loop || swiper.params.rewind) {
20331                    swiper.slidePrev(speed, true, true);
20332                    emit('autoplay');
20333                } else if (!swiper.params.autoplay.stopOnLastSlide) {
20334                    swiper.slideTo(swiper.slides.length - 1, speed, true, true);
20335                    emit('autoplay');
20336                }
20337            } else {
20338                if (!swiper.isEnd || swiper.params.loop || swiper.params.rewind) {
20339                    swiper.slideNext(speed, true, true);
20340                    emit('autoplay');
20341                } else if (!swiper.params.autoplay.stopOnLastSlide) {
20342                    swiper.slideTo(0, speed, true, true);
20343                    emit('autoplay');
20344                }
20345            }
20346            if (swiper.params.cssMode) {
20347                autoplayStartTime = new Date().getTime();
20348                requestAnimationFrame(() => {
20349                    run();
20350                });
20351            }
20352        };
20353        if (delay > 0) {
20354            clearTimeout(timeout);
20355            timeout = setTimeout(() => {
20356                proceed();
20357            }, delay);
20358        } else {
20359            requestAnimationFrame(() => {
20360                proceed();
20361            });
20362        }
20363
20364        // eslint-disable-next-line
20365        return delay;
20366    };
20367    const start = () => {
20368        autoplayStartTime = new Date().getTime();
20369        swiper.autoplay.running = true;
20370        run();
20371        emit('autoplayStart');
20372    };
20373    const stop = () => {
20374        swiper.autoplay.running = false;
20375        clearTimeout(timeout);
20376        cancelAnimationFrame(raf);
20377        emit('autoplayStop');
20378    };
20379    const pause = (internal, reset) => {
20380        if (swiper.destroyed || !swiper.autoplay.running) return;
20381        clearTimeout(timeout);
20382        if (!internal) {
20383            pausedByInteraction = true;
20384        }
20385        const proceed = () => {
20386            emit('autoplayPause');
20387            if (swiper.params.autoplay.waitForTransition) {
20388                swiper.wrapperEl.addEventListener('transitionend', onTransitionEnd);
20389            } else {
20390                resume();
20391            }
20392        };
20393        swiper.autoplay.paused = true;
20394        if (reset) {
20395            if (slideChanged) {
20396                autoplayTimeLeft = swiper.params.autoplay.delay;
20397            }
20398            slideChanged = false;
vendor: 4,159 bytes, lines 20399-20519
20399            proceed();
20400            return;
20401        }
20402        const delay = autoplayTimeLeft || swiper.params.autoplay.delay;
20403        autoplayTimeLeft = delay - (new Date().getTime() - autoplayStartTime);
20404        if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop) return;
20405        if (autoplayTimeLeft < 0) autoplayTimeLeft = 0;
20406        proceed();
20407    };
20408    const resume = () => {
20409        if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop || swiper.destroyed || !swiper.autoplay.running) return;
20410        autoplayStartTime = new Date().getTime();
20411        if (pausedByInteraction) {
20412            pausedByInteraction = false;
20413            run(autoplayTimeLeft);
20414        } else {
20415            run();
20416        }
20417        swiper.autoplay.paused = false;
20418        emit('autoplayResume');
20419    };
20420    const onVisibilityChange = () => {
20421        if (swiper.destroyed || !swiper.autoplay.running) return;
20422        const document = getDocument();
20423        if (document.visibilityState === 'hidden') {
20424            pausedByInteraction = true;
20425            pause(true);
20426        }
20427        if (document.visibilityState === 'visible') {
20428            resume();
20429        }
20430    };
20431    const onPointerEnter = e => {
20432        if (e.pointerType !== 'mouse') return;
20433        pausedByInteraction = true;
20434        pausedByPointerEnter = true;
20435        if (swiper.animating || swiper.autoplay.paused) return;
20436        pause(true);
20437    };
20438    const onPointerLeave = e => {
20439        if (e.pointerType !== 'mouse') return;
20440        pausedByPointerEnter = false;
20441        if (swiper.autoplay.paused) {
20442            resume();
20443        }
20444    };
20445    const attachMouseEvents = () => {
20446        if (swiper.params.autoplay.pauseOnMouseEnter) {
20447            swiper.el.addEventListener('pointerenter', onPointerEnter);
20448            swiper.el.addEventListener('pointerleave', onPointerLeave);
20449        }
20450    };
20451    const detachMouseEvents = () => {
20452        if (swiper.el && typeof swiper.el !== 'string') {
20453            swiper.el.removeEventListener('pointerenter', onPointerEnter);
20454            swiper.el.removeEventListener('pointerleave', onPointerLeave);
20455        }
20456    };
20457    const attachDocumentEvents = () => {
20458        const document = getDocument();
20459        document.addEventListener('visibilitychange', onVisibilityChange);
20460    };
20461    const detachDocumentEvents = () => {
20462        const document = getDocument();
20463        document.removeEventListener('visibilitychange', onVisibilityChange);
20464    };
20465    on('init', () => {
20466        if (swiper.params.autoplay.enabled) {
20467            attachMouseEvents();
20468            attachDocumentEvents();
20469            start();
20470        }
20471    });
20472    on('destroy', () => {
20473        detachMouseEvents();
20474        detachDocumentEvents();
20475        if (swiper.autoplay.running) {
20476            stop();
20477        }
20478    });
20479    on('_freeModeStaticRelease', () => {
20480        if (pausedByTouch || pausedByInteraction) {
20481            resume();
20482        }
20483    });
20484    on('_freeModeNoMomentumRelease', () => {
20485        if (!swiper.params.autoplay.disableOnInteraction) {
20486            pause(true, true);
20487        } else {
20488            stop();
20489        }
20490    });
20491    on('beforeTransitionStart', (_s, speed, internal) => {
20492        if (swiper.destroyed || !swiper.autoplay.running) return;
20493        if (internal || !swiper.params.autoplay.disableOnInteraction) {
20494            pause(true, true);
20495        } else {
20496            stop();
20497        }
20498    });
20499    on('sliderFirstMove', () => {
20500        if (swiper.destroyed || !swiper.autoplay.running) return;
20501        if (swiper.params.autoplay.disableOnInteraction) {
20502            stop();
20503            return;
20504        }
20505        isTouched = true;
20506        pausedByTouch = false;
20507        pausedByInteraction = false;
20508        touchStartTimeout = setTimeout(() => {
20509            pausedByInteraction = true;
20510            pausedByTouch = true;
20511            pause(true);
20512        }, 200);
20513    });
20514    on('touchEnd', () => {
20515        if (swiper.destroyed || !swiper.autoplay.running || !isTouched) return;
20516        clearTimeout(touchStartTimeout);
20517        clearTimeout(timeout);
20518        if (swiper.params.autoplay.disableOnInteraction) {
20519            pausedByTouch = false;
vendor: 18,788 bytes, lines 20520-20985
20520            isTouched = false;
20521            return;
20522        }
20523        if (pausedByTouch && swiper.params.cssMode) resume();
20524        pausedByTouch = false;
20525        isTouched = false;
20526    });
20527    on('slideChange', () => {
20528        if (swiper.destroyed || !swiper.autoplay.running) return;
20529        slideChanged = true;
20530    });
20531    Object.assign(swiper.autoplay, {
20532        start,
20533        stop,
20534        pause,
20535        resume
20536    });
20537}
20538
20539function Thumb(_ref) {
20540    let {
20541        swiper,
20542        extendParams,
20543        on
20544    } = _ref;
20545    extendParams({
20546        thumbs: {
20547            swiper: null,
20548            multipleActiveThumbs: true,
20549            autoScrollOffset: 0,
20550            slideThumbActiveClass: 'swiper-slide-thumb-active',
20551            thumbsContainerClass: 'swiper-thumbs'
20552        }
20553    });
20554    let initialized = false;
20555    let swiperCreated = false;
20556    swiper.thumbs = {
20557        swiper: null
20558    };
20559
20560    function onThumbClick() {
20561        const thumbsSwiper = swiper.thumbs.swiper;
20562        if (!thumbsSwiper || thumbsSwiper.destroyed) return;
20563        const clickedIndex = thumbsSwiper.clickedIndex;
20564        const clickedSlide = thumbsSwiper.clickedSlide;
20565        if (clickedSlide && clickedSlide.classList.contains(swiper.params.thumbs.slideThumbActiveClass)) return;
20566        if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;
20567        let slideToIndex;
20568        if (thumbsSwiper.params.loop) {
20569            slideToIndex = parseInt(thumbsSwiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
20570        } else {
20571            slideToIndex = clickedIndex;
20572        }
20573        if (swiper.params.loop) {
20574            swiper.slideToLoop(slideToIndex);
20575        } else {
20576            swiper.slideTo(slideToIndex);
20577        }
20578    }
20579
20580    function init() {
20581        const {
20582            thumbs: thumbsParams
20583        } = swiper.params;
20584        if (initialized) return false;
20585        initialized = true;
20586        const SwiperClass = swiper.constructor;
20587        if (thumbsParams.swiper instanceof SwiperClass) {
20588            if (thumbsParams.swiper.destroyed) {
20589                initialized = false;
20590                return false;
20591            }
20592            swiper.thumbs.swiper = thumbsParams.swiper;
20593            Object.assign(swiper.thumbs.swiper.originalParams, {
20594                watchSlidesProgress: true,
20595                slideToClickedSlide: false
20596            });
20597            Object.assign(swiper.thumbs.swiper.params, {
20598                watchSlidesProgress: true,
20599                slideToClickedSlide: false
20600            });
20601            swiper.thumbs.swiper.update();
20602        } else if (isObject(thumbsParams.swiper)) {
20603            const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);
20604            Object.assign(thumbsSwiperParams, {
20605                watchSlidesProgress: true,
20606                slideToClickedSlide: false
20607            });
20608            swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);
20609            swiperCreated = true;
20610        }
20611        swiper.thumbs.swiper.el.classList.add(swiper.params.thumbs.thumbsContainerClass);
20612        swiper.thumbs.swiper.on('tap', onThumbClick);
20613        return true;
20614    }
20615
20616    function update(initial) {
20617        const thumbsSwiper = swiper.thumbs.swiper;
20618        if (!thumbsSwiper || thumbsSwiper.destroyed) return;
20619        const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView;
20620
20621        // Activate thumbs
20622        let thumbsToActivate = 1;
20623        const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
20624        if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
20625            thumbsToActivate = swiper.params.slidesPerView;
20626        }
20627        if (!swiper.params.thumbs.multipleActiveThumbs) {
20628            thumbsToActivate = 1;
20629        }
20630        thumbsToActivate = Math.floor(thumbsToActivate);
20631        thumbsSwiper.slides.forEach(slideEl => slideEl.classList.remove(thumbActiveClass));
20632        if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) {
20633            for (let i = 0; i < thumbsToActivate; i += 1) {
20634                elementChildren(thumbsSwiper.slidesEl, `[data-swiper-slide-index="${swiper.realIndex + i}"]`).forEach(slideEl => {
20635                    slideEl.classList.add(thumbActiveClass);
20636                });
20637            }
20638        } else {
20639            for (let i = 0; i < thumbsToActivate; i += 1) {
20640                if (thumbsSwiper.slides[swiper.realIndex + i]) {
20641                    thumbsSwiper.slides[swiper.realIndex + i].classList.add(thumbActiveClass);
20642                }
20643            }
20644        }
20645        const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
20646        const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
20647        if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
20648            const currentThumbsIndex = thumbsSwiper.activeIndex;
20649            let newThumbsIndex;
20650            let direction;
20651            if (thumbsSwiper.params.loop) {
20652                const newThumbsSlide = thumbsSwiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') === `${swiper.realIndex}`);
20653                newThumbsIndex = thumbsSwiper.slides.indexOf(newThumbsSlide);
20654                direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
20655            } else {
20656                newThumbsIndex = swiper.realIndex;
20657                direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
20658            }
20659            if (useOffset) {
20660                newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
20661            }
20662            if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {
20663                if (thumbsSwiper.params.centeredSlides) {
20664                    if (newThumbsIndex > currentThumbsIndex) {
20665                        newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
20666                    } else {
20667                        newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
20668                    }
20669                } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1) ;
20670                thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
20671            }
20672        }
20673    }
20674
20675    on('beforeInit', () => {
20676        const {
20677            thumbs
20678        } = swiper.params;
20679        if (!thumbs || !thumbs.swiper) return;
20680        if (typeof thumbs.swiper === 'string' || thumbs.swiper instanceof HTMLElement) {
20681            const document = getDocument();
20682            const getThumbsElementAndInit = () => {
20683                const thumbsElement = typeof thumbs.swiper === 'string' ? document.querySelector(thumbs.swiper) : thumbs.swiper;
20684                if (thumbsElement && thumbsElement.swiper) {
20685                    thumbs.swiper = thumbsElement.swiper;
20686                    init();
20687                    update(true);
20688                } else if (thumbsElement) {
20689                    const eventName = `${swiper.params.eventsPrefix}init`;
20690                    const onThumbsSwiper = e => {
20691                        thumbs.swiper = e.detail[0];
20692                        thumbsElement.removeEventListener(eventName, onThumbsSwiper);
20693                        init();
20694                        update(true);
20695                        thumbs.swiper.update();
20696                        swiper.update();
20697                    };
20698                    thumbsElement.addEventListener(eventName, onThumbsSwiper);
20699                }
20700                return thumbsElement;
20701            };
20702            const watchForThumbsToAppear = () => {
20703                if (swiper.destroyed) return;
20704                const thumbsElement = getThumbsElementAndInit();
20705                if (!thumbsElement) {
20706                    requestAnimationFrame(watchForThumbsToAppear);
20707                }
20708            };
20709            requestAnimationFrame(watchForThumbsToAppear);
20710        } else {
20711            init();
20712            update(true);
20713        }
20714    });
20715    on('slideChange update resize observerUpdate', () => {
20716        update();
20717    });
20718    on('setTransition', (_s, duration) => {
20719        const thumbsSwiper = swiper.thumbs.swiper;
20720        if (!thumbsSwiper || thumbsSwiper.destroyed) return;
20721        thumbsSwiper.setTransition(duration);
20722    });
20723    on('beforeDestroy', () => {
20724        const thumbsSwiper = swiper.thumbs.swiper;
20725        if (!thumbsSwiper || thumbsSwiper.destroyed) return;
20726        if (swiperCreated) {
20727            thumbsSwiper.destroy();
20728        }
20729    });
20730    Object.assign(swiper.thumbs, {
20731        init,
20732        update
20733    });
20734}
20735
20736function freeMode(_ref) {
20737    let {
20738        swiper,
20739        extendParams,
20740        emit,
20741        once
20742    } = _ref;
20743    extendParams({
20744        freeMode: {
20745            enabled: false,
20746            momentum: true,
20747            momentumRatio: 1,
20748            momentumBounce: true,
20749            momentumBounceRatio: 1,
20750            momentumVelocityRatio: 1,
20751            sticky: false,
20752            minimumVelocity: 0.02
20753        }
20754    });
20755
20756    function onTouchStart() {
20757        if (swiper.params.cssMode) return;
20758        const translate = swiper.getTranslate();
20759        swiper.setTranslate(translate);
20760        swiper.setTransition(0);
20761        swiper.touchEventsData.velocities.length = 0;
20762        swiper.freeMode.onTouchEnd({
20763            currentPos: swiper.rtl ? swiper.translate : -swiper.translate
20764        });
20765    }
20766
20767    function onTouchMove() {
20768        if (swiper.params.cssMode) return;
20769        const {
20770            touchEventsData: data,
20771            touches
20772        } = swiper;
20773        // Velocity
20774        if (data.velocities.length === 0) {
20775            data.velocities.push({
20776                position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],
20777                time: data.touchStartTime
20778            });
20779        }
20780        data.velocities.push({
20781            position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],
20782            time: now()
20783        });
20784    }
20785
20786    function onTouchEnd(_ref2) {
20787        let {
20788            currentPos
20789        } = _ref2;
20790        if (swiper.params.cssMode) return;
20791        const {
20792            params,
20793            wrapperEl,
20794            rtlTranslate: rtl,
20795            snapGrid,
20796            touchEventsData: data
20797        } = swiper;
20798        // Time diff
20799        const touchEndTime = now();
20800        const timeDiff = touchEndTime - data.touchStartTime;
20801        if (currentPos < -swiper.minTranslate()) {
20802            swiper.slideTo(swiper.activeIndex);
20803            return;
20804        }
20805        if (currentPos > -swiper.maxTranslate()) {
20806            if (swiper.slides.length < snapGrid.length) {
20807                swiper.slideTo(snapGrid.length - 1);
20808            } else {
20809                swiper.slideTo(swiper.slides.length - 1);
20810            }
20811            return;
20812        }
20813        if (params.freeMode.momentum) {
20814            if (data.velocities.length > 1) {
20815                const lastMoveEvent = data.velocities.pop();
20816                const velocityEvent = data.velocities.pop();
20817                const distance = lastMoveEvent.position - velocityEvent.position;
20818                const time = lastMoveEvent.time - velocityEvent.time;
20819                swiper.velocity = distance / time;
20820                swiper.velocity /= 2;
20821                if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) {
20822                    swiper.velocity = 0;
20823                }
20824                // this implies that the user stopped moving a finger then released.
20825                // There would be no events with distance zero, so the last event is stale.
20826                if (time > 150 || now() - lastMoveEvent.time > 300) {
20827                    swiper.velocity = 0;
20828                }
20829            } else {
20830                swiper.velocity = 0;
20831            }
20832            swiper.velocity *= params.freeMode.momentumVelocityRatio;
20833            data.velocities.length = 0;
20834            let momentumDuration = 1000 * params.freeMode.momentumRatio;
20835            const momentumDistance = swiper.velocity * momentumDuration;
20836            let newPosition = swiper.translate + momentumDistance;
20837            if (rtl) newPosition = -newPosition;
20838            let doBounce = false;
20839            let afterBouncePosition;
20840            const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio;
20841            let needsLoopFix;
20842            if (newPosition < swiper.maxTranslate()) {
20843                if (params.freeMode.momentumBounce) {
20844                    if (newPosition + swiper.maxTranslate() < -bounceAmount) {
20845                        newPosition = swiper.maxTranslate() - bounceAmount;
20846                    }
20847                    afterBouncePosition = swiper.maxTranslate();
20848                    doBounce = true;
20849                    data.allowMomentumBounce = true;
20850                } else {
20851                    newPosition = swiper.maxTranslate();
20852                }
20853                if (params.loop && params.centeredSlides) needsLoopFix = true;
20854            } else if (newPosition > swiper.minTranslate()) {
20855                if (params.freeMode.momentumBounce) {
20856                    if (newPosition - swiper.minTranslate() > bounceAmount) {
20857                        newPosition = swiper.minTranslate() + bounceAmount;
20858                    }
20859                    afterBouncePosition = swiper.minTranslate();
20860                    doBounce = true;
20861                    data.allowMomentumBounce = true;
20862                } else {
20863                    newPosition = swiper.minTranslate();
20864                }
20865                if (params.loop && params.centeredSlides) needsLoopFix = true;
20866            } else if (params.freeMode.sticky) {
20867                let nextSlide;
20868                for (let j = 0; j < snapGrid.length; j += 1) {
20869                    if (snapGrid[j] > -newPosition) {
20870                        nextSlide = j;
20871                        break;
20872                    }
20873                }
20874                if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') {
20875                    newPosition = snapGrid[nextSlide];
20876                } else {
20877                    newPosition = snapGrid[nextSlide - 1];
20878                }
20879                newPosition = -newPosition;
20880            }
20881            if (needsLoopFix) {
20882                once('transitionEnd', () => {
20883                    swiper.loopFix();
20884                });
20885            }
20886            // Fix duration
20887            if (swiper.velocity !== 0) {
20888                if (rtl) {
20889                    momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);
20890                } else {
20891                    momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);
20892                }
20893                if (params.freeMode.sticky) {
20894                    // If freeMode.sticky is active and the user ends a swipe with a slow-velocity
20895                    // event, then durations can be 20+ seconds to slide one (or zero!) slides.
20896                    // It's easy to see this when simulating touch with mouse events. To fix this,
20897                    // limit single-slide swipes to the default slide duration. This also has the
20898                    // nice side effect of matching slide speed if the user stopped moving before
20899                    // lifting finger or mouse vs. moving slowly before lifting the finger/mouse.
20900                    // For faster swipes, also apply limits (albeit higher ones).
20901                    const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);
20902                    const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];
20903                    if (moveDistance < currentSlideSize) {
20904                        momentumDuration = params.speed;
20905                    } else if (moveDistance < 2 * currentSlideSize) {
20906                        momentumDuration = params.speed * 1.5;
20907                    } else {
20908                        momentumDuration = params.speed * 2.5;
20909                    }
20910                }
20911            } else if (params.freeMode.sticky) {
20912                swiper.slideToClosest();
20913                return;
20914            }
20915            if (params.freeMode.momentumBounce && doBounce) {
20916                swiper.updateProgress(afterBouncePosition);
20917                swiper.setTransition(momentumDuration);
20918                swiper.setTranslate(newPosition);
20919                swiper.transitionStart(true, swiper.swipeDirection);
20920                swiper.animating = true;
20921                elementTransitionEnd(wrapperEl, () => {
20922                    if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;
20923                    emit('momentumBounce');
20924                    swiper.setTransition(params.speed);
20925                    setTimeout(() => {
20926                        swiper.setTranslate(afterBouncePosition);
20927                        elementTransitionEnd(wrapperEl, () => {
20928                            if (!swiper || swiper.destroyed) return;
20929                            swiper.transitionEnd();
20930                        });
20931                    }, 0);
20932                });
20933            } else if (swiper.velocity) {
20934                emit('_freeModeNoMomentumRelease');
20935                swiper.updateProgress(newPosition);
20936                swiper.setTransition(momentumDuration);
20937                swiper.setTranslate(newPosition);
20938                swiper.transitionStart(true, swiper.swipeDirection);
20939                if (!swiper.animating) {
20940                    swiper.animating = true;
20941                    elementTransitionEnd(wrapperEl, () => {
20942                        if (!swiper || swiper.destroyed) return;
20943                        swiper.transitionEnd();
20944                    });
20945                }
20946            } else {
20947                swiper.updateProgress(newPosition);
20948            }
20949            swiper.updateActiveIndex();
20950            swiper.updateSlidesClasses();
20951        } else if (params.freeMode.sticky) {
20952            swiper.slideToClosest();
20953            return;
20954        } else if (params.freeMode) {
20955            emit('_freeModeNoMomentumRelease');
20956        }
20957        if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) {
20958            emit('_freeModeStaticRelease');
20959            swiper.updateProgress();
20960            swiper.updateActiveIndex();
20961            swiper.updateSlidesClasses();
20962        }
20963    }
20964
20965    Object.assign(swiper, {
20966        freeMode: {
20967            onTouchStart,
20968            onTouchMove,
20969            onTouchEnd
20970        }
20971    });
20972}
20973
20974function Grid(_ref) {
20975    let {
20976        swiper,
20977        extendParams,
20978        on
20979    } = _ref;
20980    extendParams({
20981        grid: {
20982            rows: 1,
20983            fill: 'column'
20984        }
20985    });
vendor: 1,394 bytes, lines 20986-21020
20986    let slidesNumberEvenToRows;
20987    let slidesPerRow;
20988    let numFullColumns;
20989    let wasMultiRow;
20990    const getSpaceBetween = () => {
20991        let spaceBetween = swiper.params.spaceBetween;
20992        if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
20993            spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size;
20994        } else if (typeof spaceBetween === 'string') {
20995            spaceBetween = parseFloat(spaceBetween);
20996        }
20997        return spaceBetween;
20998    };
20999    const initSlides = slides => {
21000        const {
21001            slidesPerView
21002        } = swiper.params;
21003        const {
21004            rows,
21005            fill
21006        } = swiper.params.grid;
21007        const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : slides.length;
21008        numFullColumns = Math.floor(slidesLength / rows);
21009        if (Math.floor(slidesLength / rows) === slidesLength / rows) {
21010            slidesNumberEvenToRows = slidesLength;
21011        } else {
21012            slidesNumberEvenToRows = Math.ceil(slidesLength / rows) * rows;
21013        }
21014        if (slidesPerView !== 'auto' && fill === 'row') {
21015            slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, slidesPerView * rows);
21016        }
21017        slidesPerRow = slidesNumberEvenToRows / rows;
21018    };
21019    const unsetSlides = () => {
21020        if (swiper.slides) {
vendor: 35,619 bytes, lines 21021-21961
21021            swiper.slides.forEach(slide => {
21022                if (slide.swiperSlideGridSet) {
21023                    slide.style.height = '';
21024                    slide.style[swiper.getDirectionLabel('margin-top')] = '';
21025                }
21026            });
21027        }
21028    };
21029    const updateSlide = (i, slide, slides) => {
21030        const {
21031            slidesPerGroup
21032        } = swiper.params;
21033        const spaceBetween = getSpaceBetween();
21034        const {
21035            rows,
21036            fill
21037        } = swiper.params.grid;
21038        const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : slides.length;
21039        // Set slides order
21040        let newSlideOrderIndex;
21041        let column;
21042        let row;
21043        if (fill === 'row' && slidesPerGroup > 1) {
21044            const groupIndex = Math.floor(i / (slidesPerGroup * rows));
21045            const slideIndexInGroup = i - rows * slidesPerGroup * groupIndex;
21046            const columnsInGroup = groupIndex === 0 ? slidesPerGroup : Math.min(Math.ceil((slidesLength - groupIndex * rows * slidesPerGroup) / rows), slidesPerGroup);
21047            row = Math.floor(slideIndexInGroup / columnsInGroup);
21048            column = slideIndexInGroup - row * columnsInGroup + groupIndex * slidesPerGroup;
21049            newSlideOrderIndex = column + row * slidesNumberEvenToRows / rows;
21050            slide.style.order = newSlideOrderIndex;
21051        } else if (fill === 'column') {
21052            column = Math.floor(i / rows);
21053            row = i - column * rows;
21054            if (column > numFullColumns || column === numFullColumns && row === rows - 1) {
21055                row += 1;
21056                if (row >= rows) {
21057                    row = 0;
21058                    column += 1;
21059                }
21060            }
21061        } else {
21062            row = Math.floor(i / slidesPerRow);
21063            column = i - row * slidesPerRow;
21064        }
21065        slide.row = row;
21066        slide.column = column;
21067        slide.style.height = `calc((100% - ${(rows - 1) * spaceBetween}px) / ${rows})`;
21068        slide.style[swiper.getDirectionLabel('margin-top')] = row !== 0 ? spaceBetween && `${spaceBetween}px` : '';
21069        slide.swiperSlideGridSet = true;
21070    };
21071    const updateWrapperSize = (slideSize, snapGrid) => {
21072        const {
21073            centeredSlides,
21074            roundLengths
21075        } = swiper.params;
21076        const spaceBetween = getSpaceBetween();
21077        const {
21078            rows
21079        } = swiper.params.grid;
21080        swiper.virtualSize = (slideSize + spaceBetween) * slidesNumberEvenToRows;
21081        swiper.virtualSize = Math.ceil(swiper.virtualSize / rows) - spaceBetween;
21082        if (!swiper.params.cssMode) {
21083            swiper.wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
21084        }
21085        if (centeredSlides) {
21086            const newSlidesGrid = [];
21087            for (let i = 0; i < snapGrid.length; i += 1) {
21088                let slidesGridItem = snapGrid[i];
21089                if (roundLengths) slidesGridItem = Math.floor(slidesGridItem);
21090                if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem);
21091            }
21092            snapGrid.splice(0, snapGrid.length);
21093            snapGrid.push(...newSlidesGrid);
21094        }
21095    };
21096    const onInit = () => {
21097        wasMultiRow = swiper.params.grid && swiper.params.grid.rows > 1;
21098    };
21099    const onUpdate = () => {
21100        const {
21101            params,
21102            el
21103        } = swiper;
21104        const isMultiRow = params.grid && params.grid.rows > 1;
21105        if (wasMultiRow && !isMultiRow) {
21106            el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
21107            numFullColumns = 1;
21108            swiper.emitContainerClasses();
21109        } else if (!wasMultiRow && isMultiRow) {
21110            el.classList.add(`${params.containerModifierClass}grid`);
21111            if (params.grid.fill === 'column') {
21112                el.classList.add(`${params.containerModifierClass}grid-column`);
21113            }
21114            swiper.emitContainerClasses();
21115        }
21116        wasMultiRow = isMultiRow;
21117    };
21118    on('init', onInit);
21119    on('update', onUpdate);
21120    swiper.grid = {
21121        initSlides,
21122        unsetSlides,
21123        updateSlide,
21124        updateWrapperSize
21125    };
21126}
21127
21128function appendSlide(slides) {
21129    const swiper = this;
21130    const {
21131        params,
21132        slidesEl
21133    } = swiper;
21134    if (params.loop) {
21135        swiper.loopDestroy();
21136    }
21137    const appendElement = slideEl => {
21138        if (typeof slideEl === 'string') {
21139            const tempDOM = document.createElement('div');
21140            setInnerHTML(tempDOM, slideEl);
21141            slidesEl.append(tempDOM.children[0]);
21142            setInnerHTML(tempDOM, '');
21143        } else {
21144            slidesEl.append(slideEl);
21145        }
21146    };
21147    if (typeof slides === 'object' && 'length' in slides) {
21148        for (let i = 0; i < slides.length; i += 1) {
21149            if (slides[i]) appendElement(slides[i]);
21150        }
21151    } else {
21152        appendElement(slides);
21153    }
21154    swiper.recalcSlides();
21155    if (params.loop) {
21156        swiper.loopCreate();
21157    }
21158    if (!params.observer || swiper.isElement) {
21159        swiper.update();
21160    }
21161}
21162
21163function prependSlide(slides) {
21164    const swiper = this;
21165    const {
21166        params,
21167        activeIndex,
21168        slidesEl
21169    } = swiper;
21170    if (params.loop) {
21171        swiper.loopDestroy();
21172    }
21173    let newActiveIndex = activeIndex + 1;
21174    const prependElement = slideEl => {
21175        if (typeof slideEl === 'string') {
21176            const tempDOM = document.createElement('div');
21177            setInnerHTML(tempDOM, slideEl);
21178            slidesEl.prepend(tempDOM.children[0]);
21179            setInnerHTML(tempDOM, '');
21180        } else {
21181            slidesEl.prepend(slideEl);
21182        }
21183    };
21184    if (typeof slides === 'object' && 'length' in slides) {
21185        for (let i = 0; i < slides.length; i += 1) {
21186            if (slides[i]) prependElement(slides[i]);
21187        }
21188        newActiveIndex = activeIndex + slides.length;
21189    } else {
21190        prependElement(slides);
21191    }
21192    swiper.recalcSlides();
21193    if (params.loop) {
21194        swiper.loopCreate();
21195    }
21196    if (!params.observer || swiper.isElement) {
21197        swiper.update();
21198    }
21199    swiper.slideTo(newActiveIndex, 0, false);
21200}
21201
21202function addSlide(index, slides) {
21203    const swiper = this;
21204    const {
21205        params,
21206        activeIndex,
21207        slidesEl
21208    } = swiper;
21209    let activeIndexBuffer = activeIndex;
21210    if (params.loop) {
21211        activeIndexBuffer -= swiper.loopedSlides;
21212        swiper.loopDestroy();
21213        swiper.recalcSlides();
21214    }
21215    const baseLength = swiper.slides.length;
21216    if (index <= 0) {
21217        swiper.prependSlide(slides);
21218        return;
21219    }
21220    if (index >= baseLength) {
21221        swiper.appendSlide(slides);
21222        return;
21223    }
21224    let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer;
21225    const slidesBuffer = [];
21226    for (let i = baseLength - 1; i >= index; i -= 1) {
21227        const currentSlide = swiper.slides[i];
21228        currentSlide.remove();
21229        slidesBuffer.unshift(currentSlide);
21230    }
21231    if (typeof slides === 'object' && 'length' in slides) {
21232        for (let i = 0; i < slides.length; i += 1) {
21233            if (slides[i]) slidesEl.append(slides[i]);
21234        }
21235        newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer;
21236    } else {
21237        slidesEl.append(slides);
21238    }
21239    for (let i = 0; i < slidesBuffer.length; i += 1) {
21240        slidesEl.append(slidesBuffer[i]);
21241    }
21242    swiper.recalcSlides();
21243    if (params.loop) {
21244        swiper.loopCreate();
21245    }
21246    if (!params.observer || swiper.isElement) {
21247        swiper.update();
21248    }
21249    if (params.loop) {
21250        swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
21251    } else {
21252        swiper.slideTo(newActiveIndex, 0, false);
21253    }
21254}
21255
21256function removeSlide(slidesIndexes) {
21257    const swiper = this;
21258    const {
21259        params,
21260        activeIndex
21261    } = swiper;
21262    let activeIndexBuffer = activeIndex;
21263    if (params.loop) {
21264        activeIndexBuffer -= swiper.loopedSlides;
21265        swiper.loopDestroy();
21266    }
21267    let newActiveIndex = activeIndexBuffer;
21268    let indexToRemove;
21269    if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) {
21270        for (let i = 0; i < slidesIndexes.length; i += 1) {
21271            indexToRemove = slidesIndexes[i];
21272            if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
21273            if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
21274        }
21275        newActiveIndex = Math.max(newActiveIndex, 0);
21276    } else {
21277        indexToRemove = slidesIndexes;
21278        if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove();
21279        if (indexToRemove < newActiveIndex) newActiveIndex -= 1;
21280        newActiveIndex = Math.max(newActiveIndex, 0);
21281    }
21282    swiper.recalcSlides();
21283    if (params.loop) {
21284        swiper.loopCreate();
21285    }
21286    if (!params.observer || swiper.isElement) {
21287        swiper.update();
21288    }
21289    if (params.loop) {
21290        swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);
21291    } else {
21292        swiper.slideTo(newActiveIndex, 0, false);
21293    }
21294}
21295
21296function removeAllSlides() {
21297    const swiper = this;
21298    const slidesIndexes = [];
21299    for (let i = 0; i < swiper.slides.length; i += 1) {
21300        slidesIndexes.push(i);
21301    }
21302    swiper.removeSlide(slidesIndexes);
21303}
21304
21305function Manipulation(_ref) {
21306    let {
21307        swiper
21308    } = _ref;
21309    Object.assign(swiper, {
21310        appendSlide: appendSlide.bind(swiper),
21311        prependSlide: prependSlide.bind(swiper),
21312        addSlide: addSlide.bind(swiper),
21313        removeSlide: removeSlide.bind(swiper),
21314        removeAllSlides: removeAllSlides.bind(swiper)
21315    });
21316}
21317
21318function effectInit(params) {
21319    const {
21320        effect,
21321        swiper,
21322        on,
21323        setTranslate,
21324        setTransition,
21325        overwriteParams,
21326        perspective,
21327        recreateShadows,
21328        getEffectParams
21329    } = params;
21330    on('beforeInit', () => {
21331        if (swiper.params.effect !== effect) return;
21332        swiper.classNames.push(`${swiper.params.containerModifierClass}${effect}`);
21333        if (perspective && perspective()) {
21334            swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);
21335        }
21336        const overwriteParamsResult = overwriteParams ? overwriteParams() : {};
21337        Object.assign(swiper.params, overwriteParamsResult);
21338        Object.assign(swiper.originalParams, overwriteParamsResult);
21339    });
21340    on('setTranslate _virtualUpdated', () => {
21341        if (swiper.params.effect !== effect) return;
21342        setTranslate();
21343    });
21344    on('setTransition', (_s, duration) => {
21345        if (swiper.params.effect !== effect) return;
21346        setTransition(duration);
21347    });
21348    on('transitionEnd', () => {
21349        if (swiper.params.effect !== effect) return;
21350        if (recreateShadows) {
21351            if (!getEffectParams || !getEffectParams().slideShadows) return;
21352            // remove shadows
21353            swiper.slides.forEach(slideEl => {
21354                slideEl.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => shadowEl.remove());
21355            });
21356            // create new one
21357            recreateShadows();
21358        }
21359    });
21360    let requireUpdateOnVirtual;
21361    on('virtualUpdate', () => {
21362        if (swiper.params.effect !== effect) return;
21363        if (!swiper.slides.length) {
21364            requireUpdateOnVirtual = true;
21365        }
21366        requestAnimationFrame(() => {
21367            if (requireUpdateOnVirtual && swiper.slides && swiper.slides.length) {
21368                setTranslate();
21369                requireUpdateOnVirtual = false;
21370            }
21371        });
21372    });
21373}
21374
21375function effectTarget(effectParams, slideEl) {
21376    const transformEl = getSlideTransformEl(slideEl);
21377    if (transformEl !== slideEl) {
21378        transformEl.style.backfaceVisibility = 'hidden';
21379        transformEl.style['-webkit-backface-visibility'] = 'hidden';
21380    }
21381    return transformEl;
21382}
21383
21384function effectVirtualTransitionEnd(_ref) {
21385    let {
21386        swiper,
21387        duration,
21388        transformElements,
21389        allSlides
21390    } = _ref;
21391    const {
21392        activeIndex
21393    } = swiper;
21394    const getSlide = el => {
21395        if (!el.parentElement) {
21396            // assume shadow root
21397            const slide = swiper.slides.find(slideEl => slideEl.shadowRoot && slideEl.shadowRoot === el.parentNode);
21398            return slide;
21399        }
21400        return el.parentElement;
21401    };
21402    if (swiper.params.virtualTranslate && duration !== 0) {
21403        let eventTriggered = false;
21404        let transitionEndTarget;
21405        if (allSlides) {
21406            transitionEndTarget = transformElements;
21407        } else {
21408            transitionEndTarget = transformElements.filter(transformEl => {
21409                const el = transformEl.classList.contains('swiper-slide-transform') ? getSlide(transformEl) : transformEl;
21410                return swiper.getSlideIndex(el) === activeIndex;
21411            });
21412        }
21413        transitionEndTarget.forEach(el => {
21414            elementTransitionEnd(el, () => {
21415                if (eventTriggered) return;
21416                if (!swiper || swiper.destroyed) return;
21417                eventTriggered = true;
21418                swiper.animating = false;
21419                const evt = new window.CustomEvent('transitionend', {
21420                    bubbles: true,
21421                    cancelable: true
21422                });
21423                swiper.wrapperEl.dispatchEvent(evt);
21424            });
21425        });
21426    }
21427}
21428
21429function EffectFade(_ref) {
21430    let {
21431        swiper,
21432        extendParams,
21433        on
21434    } = _ref;
21435    extendParams({
21436        fadeEffect: {
21437            crossFade: false
21438        }
21439    });
21440    const setTranslate = () => {
21441        const {
21442            slides
21443        } = swiper;
21444        const params = swiper.params.fadeEffect;
21445        for (let i = 0; i < slides.length; i += 1) {
21446            const slideEl = swiper.slides[i];
21447            const offset = slideEl.swiperSlideOffset;
21448            let tx = -offset;
21449            if (!swiper.params.virtualTranslate) tx -= swiper.translate;
21450            let ty = 0;
21451            if (!swiper.isHorizontal()) {
21452                ty = tx;
21453                tx = 0;
21454            }
21455            const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs(slideEl.progress), 0) : 1 + Math.min(Math.max(slideEl.progress, -1), 0);
21456            const targetEl = effectTarget(params, slideEl);
21457            targetEl.style.opacity = slideOpacity;
21458            targetEl.style.transform = `translate3d(${tx}px, ${ty}px, 0px)`;
21459        }
21460    };
21461    const setTransition = duration => {
21462        const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
21463        transformElements.forEach(el => {
21464            el.style.transitionDuration = `${duration}ms`;
21465        });
21466        effectVirtualTransitionEnd({
21467            swiper,
21468            duration,
21469            transformElements,
21470            allSlides: true
21471        });
21472    };
21473    effectInit({
21474        effect: 'fade',
21475        swiper,
21476        on,
21477        setTranslate,
21478        setTransition,
21479        overwriteParams: () => ({
21480            slidesPerView: 1,
21481            slidesPerGroup: 1,
21482            watchSlidesProgress: true,
21483            spaceBetween: 0,
21484            virtualTranslate: !swiper.params.cssMode
21485        })
21486    });
21487}
21488
21489function EffectCube(_ref) {
21490    let {
21491        swiper,
21492        extendParams,
21493        on
21494    } = _ref;
21495    extendParams({
21496        cubeEffect: {
21497            slideShadows: true,
21498            shadow: true,
21499            shadowOffset: 20,
21500            shadowScale: 0.94
21501        }
21502    });
21503    const createSlideShadows = (slideEl, progress, isHorizontal) => {
21504        let shadowBefore = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
21505        let shadowAfter = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
21506        if (!shadowBefore) {
21507            shadowBefore = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}`.split(' '));
21508            slideEl.append(shadowBefore);
21509        }
21510        if (!shadowAfter) {
21511            shadowAfter = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}`.split(' '));
21512            slideEl.append(shadowAfter);
21513        }
21514        if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
21515        if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
21516    };
21517    const recreateShadows = () => {
21518        // create new ones
21519        const isHorizontal = swiper.isHorizontal();
21520        swiper.slides.forEach(slideEl => {
21521            const progress = Math.max(Math.min(slideEl.progress, 1), -1);
21522            createSlideShadows(slideEl, progress, isHorizontal);
21523        });
21524    };
21525    const setTranslate = () => {
21526        const {
21527            el,
21528            wrapperEl,
21529            slides,
21530            width: swiperWidth,
21531            height: swiperHeight,
21532            rtlTranslate: rtl,
21533            size: swiperSize,
21534            browser
21535        } = swiper;
21536        const r = getRotateFix(swiper);
21537        const params = swiper.params.cubeEffect;
21538        const isHorizontal = swiper.isHorizontal();
21539        const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
21540        let wrapperRotate = 0;
21541        let cubeShadowEl;
21542        if (params.shadow) {
21543            if (isHorizontal) {
21544                cubeShadowEl = swiper.wrapperEl.querySelector('.swiper-cube-shadow');
21545                if (!cubeShadowEl) {
21546                    cubeShadowEl = createElement('div', 'swiper-cube-shadow');
21547                    swiper.wrapperEl.append(cubeShadowEl);
21548                }
21549                cubeShadowEl.style.height = `${swiperWidth}px`;
21550            } else {
21551                cubeShadowEl = el.querySelector('.swiper-cube-shadow');
21552                if (!cubeShadowEl) {
21553                    cubeShadowEl = createElement('div', 'swiper-cube-shadow');
21554                    el.append(cubeShadowEl);
21555                }
21556            }
21557        }
21558        for (let i = 0; i < slides.length; i += 1) {
21559            const slideEl = slides[i];
21560            let slideIndex = i;
21561            if (isVirtual) {
21562                slideIndex = parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10);
21563            }
21564            let slideAngle = slideIndex * 90;
21565            let round = Math.floor(slideAngle / 360);
21566            if (rtl) {
21567                slideAngle = -slideAngle;
21568                round = Math.floor(-slideAngle / 360);
21569            }
21570            const progress = Math.max(Math.min(slideEl.progress, 1), -1);
21571            let tx = 0;
21572            let ty = 0;
21573            let tz = 0;
21574            if (slideIndex % 4 === 0) {
21575                tx = -round * 4 * swiperSize;
21576                tz = 0;
21577            } else if ((slideIndex - 1) % 4 === 0) {
21578                tx = 0;
21579                tz = -round * 4 * swiperSize;
21580            } else if ((slideIndex - 2) % 4 === 0) {
21581                tx = swiperSize + round * 4 * swiperSize;
21582                tz = swiperSize;
21583            } else if ((slideIndex - 3) % 4 === 0) {
21584                tx = -swiperSize;
21585                tz = 3 * swiperSize + swiperSize * 4 * round;
21586            }
21587            if (rtl) {
21588                tx = -tx;
21589            }
21590            if (!isHorizontal) {
21591                ty = tx;
21592                tx = 0;
21593            }
21594            const transform = `rotateX(${r(isHorizontal ? 0 : -slideAngle)}deg) rotateY(${r(isHorizontal ? slideAngle : 0)}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`;
21595            if (progress <= 1 && progress > -1) {
21596                wrapperRotate = slideIndex * 90 + progress * 90;
21597                if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;
21598            }
21599            slideEl.style.transform = transform;
21600            if (params.slideShadows) {
21601                createSlideShadows(slideEl, progress, isHorizontal);
21602            }
21603        }
21604        wrapperEl.style.transformOrigin = `50% 50% -${swiperSize / 2}px`;
21605        wrapperEl.style['-webkit-transform-origin'] = `50% 50% -${swiperSize / 2}px`;
21606        if (params.shadow) {
21607            if (isHorizontal) {
21608                cubeShadowEl.style.transform = `translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${-swiperWidth / 2}px) rotateX(89.99deg) rotateZ(0deg) scale(${params.shadowScale})`;
21609            } else {
21610                const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
21611                const multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
21612                const scale1 = params.shadowScale;
21613                const scale2 = params.shadowScale / multiplier;
21614                const offset = params.shadowOffset;
21615                cubeShadowEl.style.transform = `scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${-swiperHeight / 2 / scale2}px) rotateX(-89.99deg)`;
21616            }
21617        }
21618        const zFactor = (browser.isSafari || browser.isWebView) && browser.needPerspectiveFix ? -swiperSize / 2 : 0;
21619        wrapperEl.style.transform = `translate3d(0px,0,${zFactor}px) rotateX(${r(swiper.isHorizontal() ? 0 : wrapperRotate)}deg) rotateY(${r(swiper.isHorizontal() ? -wrapperRotate : 0)}deg)`;
21620        wrapperEl.style.setProperty('--swiper-cube-translate-z', `${zFactor}px`);
21621    };
21622    const setTransition = duration => {
21623        const {
21624            el,
21625            slides
21626        } = swiper;
21627        slides.forEach(slideEl => {
21628            slideEl.style.transitionDuration = `${duration}ms`;
21629            slideEl.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(subEl => {
21630                subEl.style.transitionDuration = `${duration}ms`;
21631            });
21632        });
21633        if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {
21634            const shadowEl = el.querySelector('.swiper-cube-shadow');
21635            if (shadowEl) shadowEl.style.transitionDuration = `${duration}ms`;
21636        }
21637    };
21638    effectInit({
21639        effect: 'cube',
21640        swiper,
21641        on,
21642        setTranslate,
21643        setTransition,
21644        recreateShadows,
21645        getEffectParams: () => swiper.params.cubeEffect,
21646        perspective: () => true,
21647        overwriteParams: () => ({
21648            slidesPerView: 1,
21649            slidesPerGroup: 1,
21650            watchSlidesProgress: true,
21651            resistanceRatio: 0,
21652            spaceBetween: 0,
21653            centeredSlides: false,
21654            virtualTranslate: true
21655        })
21656    });
21657}
21658
21659function createShadow(suffix, slideEl, side) {
21660    const shadowClass = `swiper-slide-shadow${side ? `-${side}` : ''}${suffix ? ` swiper-slide-shadow-${suffix}` : ''}`;
21661    const shadowContainer = getSlideTransformEl(slideEl);
21662    let shadowEl = shadowContainer.querySelector(`.${shadowClass.split(' ').join('.')}`);
21663    if (!shadowEl) {
21664        shadowEl = createElement('div', shadowClass.split(' '));
21665        shadowContainer.append(shadowEl);
21666    }
21667    return shadowEl;
21668}
21669
21670function EffectFlip(_ref) {
21671    let {
21672        swiper,
21673        extendParams,
21674        on
21675    } = _ref;
21676    extendParams({
21677        flipEffect: {
21678            slideShadows: true,
21679            limitRotation: true
21680        }
21681    });
21682    const createSlideShadows = (slideEl, progress) => {
21683        let shadowBefore = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
21684        let shadowAfter = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
21685        if (!shadowBefore) {
21686            shadowBefore = createShadow('flip', slideEl, swiper.isHorizontal() ? 'left' : 'top');
21687        }
21688        if (!shadowAfter) {
21689            shadowAfter = createShadow('flip', slideEl, swiper.isHorizontal() ? 'right' : 'bottom');
21690        }
21691        if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0);
21692        if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0);
21693    };
21694    const recreateShadows = () => {
21695        // Set shadows
21696        swiper.params.flipEffect;
21697        swiper.slides.forEach(slideEl => {
21698            let progress = slideEl.progress;
21699            if (swiper.params.flipEffect.limitRotation) {
21700                progress = Math.max(Math.min(slideEl.progress, 1), -1);
21701            }
21702            createSlideShadows(slideEl, progress);
21703        });
21704    };
21705    const setTranslate = () => {
21706        const {
21707            slides,
21708            rtlTranslate: rtl
21709        } = swiper;
21710        const params = swiper.params.flipEffect;
21711        const rotateFix = getRotateFix(swiper);
21712        for (let i = 0; i < slides.length; i += 1) {
21713            const slideEl = slides[i];
21714            let progress = slideEl.progress;
21715            if (swiper.params.flipEffect.limitRotation) {
21716                progress = Math.max(Math.min(slideEl.progress, 1), -1);
21717            }
21718            const offset = slideEl.swiperSlideOffset;
21719            const rotate = -180 * progress;
21720            let rotateY = rotate;
21721            let rotateX = 0;
21722            let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset;
21723            let ty = 0;
21724            if (!swiper.isHorizontal()) {
21725                ty = tx;
21726                tx = 0;
21727                rotateX = -rotateY;
21728                rotateY = 0;
21729            } else if (rtl) {
21730                rotateY = -rotateY;
21731            }
21732            slideEl.style.zIndex = -Math.abs(Math.round(progress)) + slides.length;
21733            if (params.slideShadows) {
21734                createSlideShadows(slideEl, progress);
21735            }
21736            const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateFix(rotateX)}deg) rotateY(${rotateFix(rotateY)}deg)`;
21737            const targetEl = effectTarget(params, slideEl);
21738            targetEl.style.transform = transform;
21739        }
21740    };
21741    const setTransition = duration => {
21742        const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
21743        transformElements.forEach(el => {
21744            el.style.transitionDuration = `${duration}ms`;
21745            el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => {
21746                shadowEl.style.transitionDuration = `${duration}ms`;
21747            });
21748        });
21749        effectVirtualTransitionEnd({
21750            swiper,
21751            duration,
21752            transformElements
21753        });
21754    };
21755    effectInit({
21756        effect: 'flip',
21757        swiper,
21758        on,
21759        setTranslate,
21760        setTransition,
21761        recreateShadows,
21762        getEffectParams: () => swiper.params.flipEffect,
21763        perspective: () => true,
21764        overwriteParams: () => ({
21765            slidesPerView: 1,
21766            slidesPerGroup: 1,
21767            watchSlidesProgress: true,
21768            spaceBetween: 0,
21769            virtualTranslate: !swiper.params.cssMode
21770        })
21771    });
21772}
21773
21774function EffectCoverflow(_ref) {
21775    let {
21776        swiper,
21777        extendParams,
21778        on
21779    } = _ref;
21780    extendParams({
21781        coverflowEffect: {
21782            rotate: 50,
21783            stretch: 0,
21784            depth: 100,
21785            scale: 1,
21786            modifier: 1,
21787            slideShadows: true
21788        }
21789    });
21790    const setTranslate = () => {
21791        const {
21792            width: swiperWidth,
21793            height: swiperHeight,
21794            slides,
21795            slidesSizesGrid
21796        } = swiper;
21797        const params = swiper.params.coverflowEffect;
21798        const isHorizontal = swiper.isHorizontal();
21799        const transform = swiper.translate;
21800        const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;
21801        const rotate = isHorizontal ? params.rotate : -params.rotate;
21802        const translate = params.depth;
21803        const r = getRotateFix(swiper);
21804        // Each slide offset from center
21805        for (let i = 0, length = slides.length; i < length; i += 1) {
21806            const slideEl = slides[i];
21807            const slideSize = slidesSizesGrid[i];
21808            const slideOffset = slideEl.swiperSlideOffset;
21809            const centerOffset = (center - slideOffset - slideSize / 2) / slideSize;
21810            const offsetMultiplier = typeof params.modifier === 'function' ? params.modifier(centerOffset) : centerOffset * params.modifier;
21811            let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
21812            let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier;
21813            // var rotateZ = 0
21814            let translateZ = -translate * Math.abs(offsetMultiplier);
21815            let stretch = params.stretch;
21816            // Allow percentage to make a relative stretch for responsive sliders
21817            if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {
21818                stretch = parseFloat(params.stretch) / 100 * slideSize;
21819            }
21820            let translateY = isHorizontal ? 0 : stretch * offsetMultiplier;
21821            let translateX = isHorizontal ? stretch * offsetMultiplier : 0;
21822            let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier);
21823
21824            // Fix for ultra small values
21825            if (Math.abs(translateX) < 0.001) translateX = 0;
21826            if (Math.abs(translateY) < 0.001) translateY = 0;
21827            if (Math.abs(translateZ) < 0.001) translateZ = 0;
21828            if (Math.abs(rotateY) < 0.001) rotateY = 0;
21829            if (Math.abs(rotateX) < 0.001) rotateX = 0;
21830            if (Math.abs(scale) < 0.001) scale = 0;
21831            const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px)  rotateX(${r(rotateX)}deg) rotateY(${r(rotateY)}deg) scale(${scale})`;
21832            const targetEl = effectTarget(params, slideEl);
21833            targetEl.style.transform = slideTransform;
21834            slideEl.style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
21835            if (params.slideShadows) {
21836                // Set shadows
21837                let shadowBeforeEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top');
21838                let shadowAfterEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom');
21839                if (!shadowBeforeEl) {
21840                    shadowBeforeEl = createShadow('coverflow', slideEl, isHorizontal ? 'left' : 'top');
21841                }
21842                if (!shadowAfterEl) {
21843                    shadowAfterEl = createShadow('coverflow', slideEl, isHorizontal ? 'right' : 'bottom');
21844                }
21845                if (shadowBeforeEl) shadowBeforeEl.style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
21846                if (shadowAfterEl) shadowAfterEl.style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;
21847            }
21848        }
21849    };
21850    const setTransition = duration => {
21851        const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
21852        transformElements.forEach(el => {
21853            el.style.transitionDuration = `${duration}ms`;
21854            el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => {
21855                shadowEl.style.transitionDuration = `${duration}ms`;
21856            });
21857        });
21858    };
21859    effectInit({
21860        effect: 'coverflow',
21861        swiper,
21862        on,
21863        setTranslate,
21864        setTransition,
21865        perspective: () => true,
21866        overwriteParams: () => ({
21867            watchSlidesProgress: true
21868        })
21869    });
21870}
21871
21872function EffectCreative(_ref) {
21873    let {
21874        swiper,
21875        extendParams,
21876        on
21877    } = _ref;
21878    extendParams({
21879        creativeEffect: {
21880            limitProgress: 1,
21881            shadowPerProgress: false,
21882            progressMultiplier: 1,
21883            perspective: true,
21884            prev: {
21885                translate: [0, 0, 0],
21886                rotate: [0, 0, 0],
21887                opacity: 1,
21888                scale: 1
21889            },
21890            next: {
21891                translate: [0, 0, 0],
21892                rotate: [0, 0, 0],
21893                opacity: 1,
21894                scale: 1
21895            }
21896        }
21897    });
21898    const getTranslateValue = value => {
21899        if (typeof value === 'string') return value;
21900        return `${value}px`;
21901    };
21902    const setTranslate = () => {
21903        const {
21904            slides,
21905            wrapperEl,
21906            slidesSizesGrid
21907        } = swiper;
21908        const params = swiper.params.creativeEffect;
21909        const {
21910            progressMultiplier: multiplier
21911        } = params;
21912        const isCenteredSlides = swiper.params.centeredSlides;
21913        const rotateFix = getRotateFix(swiper);
21914        if (isCenteredSlides) {
21915            const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0;
21916            wrapperEl.style.transform = `translateX(calc(50% - ${margin}px))`;
21917        }
21918        for (let i = 0; i < slides.length; i += 1) {
21919            const slideEl = slides[i];
21920            const slideProgress = slideEl.progress;
21921            const progress = Math.min(Math.max(slideEl.progress, -params.limitProgress), params.limitProgress);
21922            let originalProgress = progress;
21923            if (!isCenteredSlides) {
21924                originalProgress = Math.min(Math.max(slideEl.originalProgress, -params.limitProgress), params.limitProgress);
21925            }
21926            const offset = slideEl.swiperSlideOffset;
21927            const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];
21928            const r = [0, 0, 0];
21929            let custom = false;
21930            if (!swiper.isHorizontal()) {
21931                t[1] = t[0];
21932                t[0] = 0;
21933            }
21934            let data = {
21935                translate: [0, 0, 0],
21936                rotate: [0, 0, 0],
21937                scale: 1,
21938                opacity: 1
21939            };
21940            if (progress < 0) {
21941                data = params.next;
21942                custom = true;
21943            } else if (progress > 0) {
21944                data = params.prev;
21945                custom = true;
21946            }
21947            // set translate
21948            t.forEach((value, index) => {
21949                t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(progress * multiplier)}))`;
21950            });
21951            // set rotates
21952            r.forEach((value, index) => {
21953                let val = data.rotate[index] * Math.abs(progress * multiplier);
21954                r[index] = val;
21955            });
21956            slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
21957            const translateString = t.join(', ');
21958            const rotateString = `rotateX(${rotateFix(r[0])}deg) rotateY(${rotateFix(r[1])}deg) rotateZ(${rotateFix(r[2])}deg)`;
21959            const scaleString = originalProgress < 0 ? `scale(${1 + (1 - data.scale) * originalProgress * multiplier})` : `scale(${1 - (1 - data.scale) * originalProgress * multiplier})`;
21960            const opacityString = originalProgress < 0 ? 1 + (1 - data.opacity) * originalProgress * multiplier : 1 - (1 - data.opacity) * originalProgress * multiplier;
21961            const transform = `translate3d(${translateString}) ${rotateString}
21961 ${scaleString}`;
21962
21963            // Set shadows
21964            if (custom && data.shadow || !custom) {
21965                let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
21966                if (!shadowEl && data.shadow) {
21967                    shadowEl = createShadow('creative', slideEl);
21968                }
21969                if (shadowEl) {
21970                    const shadowOpacity = params.shadowPerProgress ? progress * (1 / params.limitProgress) : progress;
21971                    shadowEl.style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1);
21972                }
21973            }
21974            const targetEl = effectTarget(params, slideEl);
21975            targetEl.style.transform = transform;
21976            targetEl.style.opacity = opacityString;
21977            if (data.origin) {
21978                targetEl.style.transformOrigin = data.origin;
21979            }
21980        }
21981    };
21982    const setTransition = duration => {
21983        const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
21984        transformElements.forEach(el => {
21985            el.style.transitionDuration = `${duration}ms`;
21986            el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => {
21987                shadowEl.style.transitionDuration = `${duration}ms`;
21988            });
21989        });
21990        effectVirtualTransitionEnd({
21991            swiper,
21992            duration,
21993            transformElements,
21994            allSlides: true
21995        });
21996    };
21997    effectInit({
21998        effect: 'creative',
21999        swiper,
22000        on,
22001        setTranslate,
22002        setTransition,
22003        perspective: () => swiper.params.creativeEffect.perspective,
22004        overwriteParams: () => ({
22005            watchSlidesProgress: true,
22006            virtualTranslate: !swiper.params.cssMode
22007        })
22008    });
22009}
22010
22011function EffectCards(_ref) {
22012    let {
22013        swiper,
22014        extendParams,
22015        on
22016    } = _ref;
22017    extendParams({
22018        cardsEffect: {
22019            slideShadows: true,
22020            rotate: true,
22021            perSlideRotate: 2,
22022            perSlideOffset: 8
22023        }
22024    });
22025    const setTranslate = () => {
22026        const {
22027            slides,
22028            activeIndex,
22029            rtlTranslate: rtl
22030        } = swiper;
22031        const params = swiper.params.cardsEffect;
22032        const {
22033            startTranslate,
22034            isTouched
22035        } = swiper.touchEventsData;
22036        const currentTranslate = rtl ? -swiper.translate : swiper.translate;
22037        for (let i = 0; i < slides.length; i += 1) {
22038            const slideEl = slides[i];
22039            const slideProgress = slideEl.progress;
22040            const progress = Math.min(Math.max(slideProgress, -4), 4);
22041            let offset = slideEl.swiperSlideOffset;
22042            if (swiper.params.centeredSlides && !swiper.params.cssMode) {
22043                swiper.wrapperEl.style.transform = `translateX(${swiper.minTranslate()}px)`;
22044            }
22045            if (swiper.params.centeredSlides && swiper.params.cssMode) {
22046                offset -= slides[0].swiperSlideOffset;
22047            }
22048            let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset;
22049            let tY = 0;
22050            const tZ = -100 * Math.abs(progress);
22051            let scale = 1;
22052            let rotate = -params.perSlideRotate * progress;
22053            let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75;
22054            const slideIndex = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.from + i : i;
22055            const isSwipeToNext = (slideIndex === activeIndex || slideIndex === activeIndex - 1) && progress > 0 && progress < 1 && (isTouched || swiper.params.cssMode) && currentTranslate < startTranslate;
22056            const isSwipeToPrev = (slideIndex === activeIndex || slideIndex === activeIndex + 1) && progress < 0 && progress > -1 && (isTouched || swiper.params.cssMode) && currentTranslate > startTranslate;
22057            if (isSwipeToNext || isSwipeToPrev) {
22058                const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5;
22059                rotate += -28 * progress * subProgress;
22060                scale += -0.5 * subProgress;
22061                tXAdd += 96 * subProgress;
22062                tY = `${-25 * subProgress * Math.abs(progress)}%`;
22063            }
22064            if (progress < 0) {
22065                // next
22066                tX = `calc(${tX}px ${rtl ? '-' : '+'} (${tXAdd * Math.abs(progress)}%))`;
22067            } else if (progress > 0) {
22068                // prev
22069                tX = `calc(${tX}px ${rtl ? '-' : '+'} (-${tXAdd * Math.abs(progress)}%))`;
22070            } else {
22071                tX = `${tX}px`;
22072            }
22073            if (!swiper.isHorizontal()) {
22074                const prevY = tY;
22075                tY = tX;
22076                tX = prevY;
22077            }
22078            const scaleString = progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`;
22079
22080            /* eslint-disable */
22081            const transform = `
22082        translate3d(${tX}, ${tY}, ${tZ}px)
22083        rotateZ(${params.rotate ? rtl ? -rotate : rotate : 0}deg)
22084        scale(${scaleString})
22085      `;
22086            /* eslint-enable */
22087
22088            if (params.slideShadows) {
22089                // Set shadows
22090                let shadowEl = slideEl.querySelector('.swiper-slide-shadow');
22091                if (!shadowEl) {
22092                    shadowEl = createShadow('cards', slideEl);
22093                }
22094                if (shadowEl) shadowEl.style.opacity = Math.min(Math.max((Math.abs(progress) - 0.5) / 0.5, 0), 1);
22095            }
22096            slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
22097            const targetEl = effectTarget(params, slideEl);
22098            targetEl.style.transform = transform;
22099        }
22100    };
22101    const setTransition = duration => {
22102        const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
22103        transformElements.forEach(el => {
22104            el.style.transitionDuration = `${duration}ms`;
22105            el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => {
22106                shadowEl.style.transitionDuration = `${duration}ms`;
22107            });
22108        });
22109        effectVirtualTransitionEnd({
22110            swiper,
22111            duration,
22112            transformElements
22113        });
22114    };
22115    effectInit({
22116        effect: 'cards',
22117        swiper,
22118        on,
22119        setTranslate,
22120        setTransition,
22121        perspective: () => true,
22122        overwriteParams: () => ({
22123            _loopSwapReset: false,
22124            watchSlidesProgress: true,
22125            loopAdditionalSlides: swiper.params.cardsEffect.rotate ? 3 : 2,
22126            centeredSlides: true,
22127            virtualTranslate: !swiper.params.cssMode
22128        })
22129    });
22130}
22131
22132/**
22133 * Swiper 11.2.10
22134 * Most modern mobile touch slider and framework with hardware accelerated transitions
22135 * https://swiperjs.com
22136 *
22137 * Copyright 2014-2025 Vladimir Kharlampidi
22138 *
22139 * Released under the MIT License
22140 *
22141 * Released on: June 28, 2025
22142 */
22143
22144
22145// Swiper Class
22146const modules = [Virtual, Keyboard, Mousewheel, Navigation, Pagination, Scrollbar, Parallax, Zoom, Controller, A11y, History, HashNavigation, Autoplay, Thumb, freeMode, Grid, Manipulation, EffectFade, EffectCube, EffectFlip, EffectCoverflow, EffectCreative, EffectCards];
22147Swiper.use(modules);
22148
22149let peopleSlider;
22150
22151function updateSwiperIfReady(slider) {
22152    if (!slider || !slider.swiper) {
22153        return false;
22154    }
22155
22156    slider.swiper.update();
22157    return true;
22158}
22159
22160function initHomeSliders(root) {
22161    var scope = root && root.querySelectorAll ? root : document;
22162
22163    scope.querySelectorAll(".home__slider").forEach(function (slider) {
22164        if (updateSwiperIfReady(slider)) {
22165            return;
22166        }
22167
22168        var section = slider.closest(".home") || document;
22169
22170        new Swiper(slider, {
22171            slidesPerView: 1,
22172            spaceBetween: 0,
22173            observer: true,
22174            observeParents: true,
22175
22176            pagination: {
22177                el: section.querySelector(".home__pagination"),
22178                clickable: true,
22179            },
22180
22181            navigation: {
22182                prevEl: section.querySelector(".slider-btn_prev"),
22183                nextEl: section.querySelector(".slider-btn_next"),
22184            },
22185        });
22186    });
22187}
22188
22189function calcQuoteSliderHeight(swiper) {
22190    if (!swiper || !swiper.el || swiper.el.offsetWidth <= 0) {
22191        return;
22192    }
22193
22194    var slides = swiper && swiper.slides ? Array.from(swiper.slides) : [];
22195    var maxHeight = 0;
22196
22197    slides.forEach(function(slide) {
22198        $(slide).height("auto");
22199    });
22200
22201    slides.forEach(function(slide) {
22202        var slideHeight = $(slide).outerHeight();
22203
22204        if (slideHeight > maxHeight) {
22205            maxHeight = slideHeight;
22206        }
22207    });
22208
22209    slides.forEach(function(slide) {
22210        $(slide).height(maxHeight);
22211    });
22212}
22213
22214function calcQuoteSliderWidth(root) {
22215    var scope = root && root.querySelectorAll ? root : document;
22216
22217    scope.querySelectorAll(".slider_first .swiper").forEach(function (slider) {
22218        var quote = slider.closest(".slider");
22219
22220        if (!quote || quote.offsetWidth <= 0) {
22221            return;
22222        }
22223
22224        slider.style.width = quote.offsetWidth * (document.documentElement.offsetWidth <= 600 ? 1 : 0.66) - (document.documentElement.offsetWidth <= 600 ? 120 : 0) + "px";
22225    });
22226}
22227
22228function initQuoteSliders(root) {
22229    var scope = root && root.querySelectorAll ? root : document;
22230
22231    calcQuoteSliderWidth(scope);
22232
22233    scope.querySelectorAll(".slider_first .swiper").forEach(function (slider) {
22234        var quote = slider.closest(".slider_first") || document;
22235
22236        if (quote !== document && quote.offsetWidth <= 0) {
22237            return;
22238        }
22239
22240        if (updateSwiperIfReady(slider)) {
22241            calcQuoteSliderHeight(slider.swiper);
22242            return;
22243        }
22244
22245        new Swiper(slider, {
22246            slidesPerView: 1,
22247            spaceBetween: 0,
22248            observer: true,
22249            observeParents: true,
22250
22251            navigation: {
22252                prevEl: quote.querySelector(".slider__slider-btn_prev"),
22253                nextEl: quote.querySelector(".slider__slider-btn_next"),
22254            },
22255
22256            on: {
22257                slideChange: function (swiper) {
22258                    var currentNum = quote.querySelector(".slider__slider-current-num");
22259
22260                    if (currentNum) {
22261                        currentNum.textContent = swiper.realIndex + 1;
22262                    }
22263                },
22264                init: function (swiper) {
22265                    calcQuoteSliderHeight(swiper);
22266                },
22267                resize: function (swiper) {
22268                    calcQuoteSliderWidth(quote);
22269                    calcQuoteSliderHeight(swiper);
22270                }
22271            },
22272        });
22273    });
22274}
22275
22276function initPeoplesSliders(root) {
22277    var scope = root && root.querySelectorAll ? root : document;
22278
22279    scope.querySelectorAll(".peoples__slider").forEach(function (slider) {
22280        if (updateSwiperIfReady(slider)) {
22281            return;
22282        }
22283
22284        var section = slider.closest(".peoples") || document;
22285
22286        new Swiper(slider, {
22287            slidesPerView: 1,
22288            spaceBetween: 0,
22289            observer: true,
22290            observeParents: true,
22291
22292            navigation: {
22293                prevEl: section.querySelector(".slider-btn_prev"),
22294                nextEl: section.querySelector(".slider-btn_next"),
22295            },
22296
22297            breakpoints: {
22298                600: {
22299                    slidesPerView: 2,
22300                },
22301                768: {
22302                    slidesPerView: 4,
22303                },
22304                1280: {
22305                    slidesPerView: 5,
22306                }
22307            },
22308        });
22309    });
22310
22311    scope.querySelectorAll(".peoples__slider-two").forEach(function (slider) {
22312        if (updateSwiperIfReady(slider)) {
22313            return;
22314        }
22315
22316        var section = slider.closest(".peoples") || document;
22317
22318        new Swiper(slider, {
22319            slidesPerView: 1,
22320            spaceBetween: 0,
22321            observer: true,
22322            observeParents: true,
22323
22324            navigation: {
22325                prevEl: section.querySelector(".slider-btn_prev"),
22326                nextEl: section.querySelector(".slider-btn_next"),
22327            },
22328
22329            breakpoints: {
22330                600: {
22331                    slidesPerView: 2,
22332                },
22333                1280: {
22334                    slidesPerView: 3,
22335                }
22336            },
22337        });
22338    });
22339}
22340
22341function initScheduleCalendarSliders() {
22342    var scheduleCalendarSwiperEl = document.querySelector(".calendar__pagination .swiper[data-msdm-schedule-swiper]");
22343    if (scheduleCalendarSwiperEl && !scheduleCalendarSwiperEl.swiper) {
22344        new Swiper(scheduleCalendarSwiperEl, {
22345            slidesPerView: 3,
22346            spaceBetween: 20,
22347            watchOverflow: true,
22348            breakpoints: {
22349                768: {
22350                    slidesPerView: 7,
22351                },
22352            },
22353        });
22354    }
22355
22356    var legacyCalendarSwiperEl = document.querySelector(".calendar__pagination .swiper:not([data-msdm-schedule-swiper])");
22357    if (legacyCalendarSwiperEl && !legacyCalendarSwiperEl.swiper) {
22358        new Swiper(legacyCalendarSwiperEl, {
22359            slidesPerView: 3,
22360            spaceBetween: 20,
22361
22362            breakpoints: {
22363                768: {
22364                    slidesPerView: 7,
22365                },
22366            },
22367
22368            navigation: {
22369                prevEl: ".calendar__slider-btn_prev",
22370                nextEl: ".calendar__slider-btn_next",
22371            },
22372        });
22373    }
22374}
22375
22376function initCalendarPagePagination() {
22377    document.querySelectorAll(".calendar-page__pagination").forEach(function (pagination) {
22378        var calendarPageSwiperEl = pagination.querySelector(".swiper");
22379        if (!calendarPageSwiperEl || calendarPageSwiperEl.swiper) {
22380            return;
22381        }
22382
22383        var calendarPageVisibleSlides = window.innerWidth >
22383= 1200 ? 7 : window.innerWidth >= 900 ? 5 : window.innerWidth >= 600 ? 4 : 2;
22384        var calendarPageSlides = Array.from(calendarPageSwiperEl.querySelectorAll(".calendar-page__date-btn"));
22385        var calendarPageActiveIndexAttr = parseInt(calendarPageSwiperEl.getAttribute("data-active-slide-index"), 10);
22386        var calendarPageActiveIndex = Number.isInteger(calendarPageActiveIndexAttr) ? calendarPageActiveIndexAttr : Math.max(0, calendarPageSlides.findIndex(function (slide) {
22387            return slide.classList.contains("active");
22388        }));
22389        var calendarPageInitialSlide = Math.max(0, calendarPageActiveIndex - Math.floor(calendarPageVisibleSlides / 2));
22390
22391        new Swiper(calendarPageSwiperEl, {
22392            initialSlide: calendarPageInitialSlide,
22393            slidesPerView: 2,
22394            spaceBetween: 20,
22395
22396            breakpoints: {
22397                600: {
22398                    slidesPerView: 4,
22399                    spaceBetween: 10,
22400                },
22401                900: {
22402                    slidesPerView: 5,
22403
22404                },
22405                1200: {
22406                    slidesPerView: 7,
22407                }
22408            },
22409
22410            navigation: {
22411                prevEl: pagination.querySelector(".calendar-page__slider-btn_prev"),
22412                nextEl: pagination.querySelector(".calendar-page__slider-btn_next"),
22413            },
22414        });
22415    });
22416}
22417
22418window.msdmInitCalendarPagePagination = initCalendarPagePagination;
22419
22420function bindPeoplesCompositeRefresh() {
22421    if (window.__msdmPeoplesCompositeRefreshBound) {
22422        return;
22423    }
22424
22425    window.__msdmPeoplesCompositeRefreshBound = true;
22426
22427    document.addEventListener("click", function (event) {
22428        if (!event.target.closest("[data-sliders-tab]")) {
22429            return;
22430        }
22431
22432        window.setTimeout(function () {
22433            initQuoteSliders();
22434        }, 0);
22435    });
22436
22437    window.addEventListener("resize", function () {
22438        initQuoteSliders();
22439        initHomeSliders();
22440        initPeoplesSliders();
22441    });
22442
22443    if (!window.BX || typeof window.BX.addCustomEvent !== "function") {
22444        return;
22445    }
22446
22447    window.BX.addCustomEvent("onFrameDataReceived", function () {
22448        window.setTimeout(function () {
22449            initHomeSliders();
22450            initQuoteSliders();
22451            initPeoplesSliders();
22452            initScheduleCalendarSliders();
22453            initCalendarPagePagination();
22454        }, 0);
22455    });
22456}
22457
22458$(() => {
22459    bindPeoplesCompositeRefresh();
22460
22461    initHomeSliders();
22462
22463    peopleSlider = new Swiper(".people-detail__slider", {
22464        slidesPerView: 1,
22465        spaceBetween: 0,
22466
22467        navigation: {
22468            prevEl: ".people-detail__prev-btn",
22469            nextEl: ".people-detail__next-btn",
22470        },
22471    });
22472
22473    initQuoteSliders();
22474
22475    initScheduleCalendarSliders();
22476    initCalendarPagePagination();
22477
22478    new Swiper(".articles__slider", {
22479        slidesPerView: 3,
22480        spaceBetween: 42,
22481    });
22482
22483    new Swiper(".icon-page__slider .swiper", {
22484        slidesPerView: 1,
22485        spaceBetween: 20,
22486
22487        navigation: {
22488            prevEl: ".icon-page__slider .slider-btn_prev",
22489            nextEl: ".icon-page__slider .slider-btn_next",
22490        },
22491    });
22492
22493    document.querySelectorAll(".icon-section__slider-wrap:not(.icon-section__slider-wrap-second)").forEach(item => {
22494        new Swiper(item.querySelector(".swiper"), {
22495            slidesPerView: 1,
22496            spaceBetween: 50,
22497
22498            navigation: {
22499                prevEl: item.querySelector(".slider-btn_prev"),
22500                nextEl: item.querySelector(".slider-btn_next"),
22501            },
22502
22503            breakpoints: {
22504                991: {
22505                    slidesPerView: 2,
22506                },
22507                1200: {
22508                    slidesPerView: 3,
22509                },
22510            }
22511        });
22512    });
22513
22514    document.querySelectorAll(".icon-section__slider-wrap-second").forEach(item => {
22515        new Swiper(item.querySelector(".swiper"), {
22516            slidesPerView: 1,
22517            spaceBetween: 50,
22518            slidesPerGroup: 1,
22519
22520            navigation: {
22521                prevEl: item.querySelector(".slider-btn_prev"),
22522                nextEl: item.querySelector(".slider-btn_next"),
22523            },
22524
22525            breakpoints: {
22526                991: {
22527                    slidesPerView: 2,
22528                    slidesPerGroup: 1,
22529                },
22530                1200: {
22531                    slidesPerView: 2,
22532                    slidesPerGroup: 1,
22533                },
22534            }
22535        });
22536    });
22537    
22538    initPeoplesSliders();
22539
22540    new Swiper(".questions__slider", {
22541        slidesPerView: 1,
22542        spaceBetween: 50,
22543        slidesPerGroup: 1,
22544        breakpoints: {
22545            1024: {
22546                slidesPerGroup: 2,
22547                slidesPerView: 2,
22548            },
22549            1280: {
22550                slidesPerView: 3,
22551                slidesPerGroup: 3,
22552            }
22553        },
22554
22555        navigation: {
22556            prevEl: ".questions .slider-btn_prev",
22557            nextEl: ".questions .slider-btn_next",
22558        },
22559    });
22560
22561    new Swiper(".service__slider", {
22562        slidesPerView: 3,
22563        spaceBetween: 50,
22564    });
22565
22566    new Swiper(".services__slider", {
22567        slidesPerView: 1,
22568        spaceBetween: 33,
22569        slidesPerGroup: 1,
22570        navigation: {
22571            prevEl: ".services .slider-btn_prev",
22572            nextEl: ".services .slider-btn_next",
22573        },
22574
22575        breakpoints: {
22576            600: {
22577                slidesPerView: 2,
22578                slidesPerGroup: 2,
22579            },
22580            768: {
22581                slidesPerView: 3,
22582                slidesPerGroup: 3,
22583            },
22584            1280: {
22585                slidesPerView: 4,
22586                slidesPerGroup: 4,
22587            }
22588        },
22589    });
22590
22591    new Swiper(".beginners__slider", {
22592        slidesPerView: 3,
22593        spaceBetween: 50,
22594    });
22595
22596    new Swiper(".orthodox-calendar__slider-wrap .swiper", {
22597        slidesPerView: 1,
22598        spaceBetween: 20,
22599        breakpoints: {
22600            600: {
22601                slidesPerView: 3,
22602            },
22603        },
22604
22605        navigation: {
22606            prevEl: ".orthodox-calendar__slider-wrap .slider-btn_prev",
22607            nextEl: ".orthodox-calendar__slider-wrap .slider-btn_next",
22608        },
22609    });
22610
22611    new Swiper("#contacts-s1 .swiper", {
22612        slidesPerView: 1,
22613        spaceBetween: 38,
22614
22615        navigation: {
22616            prevEl: "#contacts-s1 .slider-btn_prev",
22617            nextEl: "#contacts-s1 .slider-btn_next",
22618        },
22619    });
22620
22621    new Swiper("#contacts-s2 .swiper", {
22622        slidesPerView: 1,
22623        spaceBetween: 38,
22624
22625        breakpoints: {
22626            1024: {
22627                slidesPerView: 2,
22628            }
22629        },
22630
22631        navigation: {
22632            prevEl: "#contacts-s2 .slider-btn_prev",
22633            nextEl: "#contacts-s2 .slider-btn_next",
22634        },
22635    });
22636
22637    new Swiper(".c-gallery .swiper", {
22638        slidesPerView: 1,
22639        spaceBetween: 50,
22640        effect: "coverflow",
22641        centeredSlides: true,
22642
22643        navigation: {
22644            prevEl: ".c-gallery .slider-btn_prev",
22645            nextEl: ".c-gallery .slider-btn_next",
22646        },
22647    });
22648
22649    new Swiper(".c-reviews .swiper", {
22650        slidesPerView: 1,
22651        spaceBetween: 50,
22652
22653        breakpoints: {
22654            1024: {
22655                slidesPerView: 2,
22656            }
22657        },
22658
22659        navigation: {
22660            prevEl: ".c-reviews .slider-btn_prev",
22661            nextEl: ".c-reviews .slider-btn_next",
22662        },
22663    });
22664
22665    try {
22666        var el = document.querySelector('.orthodox-calendar__pagination .swiper');
22667        var activeIndex = parseInt(el.getAttribute('data-active-index') || '0', 10);
22668
22669        new Swiper(".orthodox-calendar__pagination .swiper", {
22670            slidesPerView: 1,
22671            spaceBetween: 22,
22672            initialSlide: activeIndex,
22673            centeredSlides: true,
22674            breakpoints: {
22675                768: {
22676                    slidesPerView: 3,
22677                },
22678                1200: {
22679                    slidesPerView: 5,
22680                },
22681            },
22682
22683            navigation: {
22684                prevEl: ".orthodox-calendar__slider-btn_prev",
22685                nextEl: ".orthodox-calendar__slider-btn_next",
22686            },
22687        });
22688    } catch (error) {
22689        console.log(error);
22690    }
22691
22692    if (+$("html").width() < 1280) {
22693        const width = +$("body").width();
22694        $(".calendar__pagination").width(width - 100);
22695    }
22696
22697    const mediaDetailImg = document.querySelector(".media-detail__wrap img");
22698    const mediaDetailLink = document.querySelector(".media-detail__wrap a[data-fslightbox]");
22699    const mediaDetailItems = Array.from(document.querySelectorAll(".media-detail__item"));
22700
22701    if (mediaDetailLink && mediaDetailImg) {
22702        const galleryGroup = "media-detail-gallery";
22703        const gallerySources = [];
22704        const seenSources = new Set();
22705
22706        [mediaDetailImg.getAttribute("src"), ...mediaDetailItems.map((item) => item.querySelector("img")?.getAttribute("src"))].forEach((src) => {
22707            if (!src || seenSources.has(src)) {
22708                return;
22709            }
22710
22711            seenSources.add(src);
22712            gallerySources.push(src);
22713        });
22714
22715        if (gallerySources.length) {
22716            let galleryHolder = document.querySelector("[data-media-detail-gallery-holder]");
22717
22718            if (!galleryHolder) {
22719                galleryHolder = document.createElement("div");
22720                galleryHolder.setAttribute("data-media-detail-gallery-holder", "true");
22721                galleryHolder.style.display = "none";
22722                document.body.appendChild(galleryHolder);
22723            }
22724
22725            galleryHolder.innerHTML = gallerySources.map((src) => `
22726                <a href="${src}" data-fslightbox="${galleryGroup}"></a>
22727            `).join("");
22728
22729            refreshFsLightbox();
22730
22731            const syncMediaDetailImage = (index) => {
22732                const src = gallerySources[index];
22733
22734                if (!src) {
22735                    return;
22736                }
22737
22738                mediaDetailLink.setAttribute("href", src);
22739                mediaDetailImg.setAttribute("src", src);
22740                if (typeof window.msdmRefreshSmartPhoto === "function") {
22741                    window.msdmRefreshSmartPhoto(mediaDetailImg);
22742                }
22743            };
22744
22745            const galleryInstance = window.fsLightboxInstances?.[galleryGroup];
22746
22747            if (galleryInstance) {
22748                const prevOnOpen = galleryInstance.props.onOpen;
22749                const prevOnShow = galleryInstance.props.onShow;
22750                const slideIndexChanger = galleryInstance.core?.slideIndexChanger;
22751                const originalJumpTo = slideIndexChanger?.jumpTo;
22752
22753                galleryInstance.props.onOpen = () => {
22754                    syncMediaDetailImage(galleryInstance.stageIndexes.current);
22755
22756                    if (typeof prevOnOpen === "function") {
22757                        prevOnOpen();
22758                    }
22759                };
22760
22761                galleryInstance.props.onShow = () => {
22762                    syncMediaDetailImage(galleryInstance.stageIndexes.current);
22763
22764                    if (typeof prevOnShow === "function") {
22765                        prevOnShow();
22766                    }
22767                };
22768
22769                if (typeof originalJumpTo === "function") {
22770                    slideIndexChanger.jumpTo = (index) => {
22771                        originalJumpTo(index);
22772                        syncMediaDetailImage(galleryInstance.stageIndexes.current);
22773                    };
22774                }
22775            }
22776
22777            const openMediaGallery = (index) => {
22778                const instance = window.fsLightboxInstances?.[galleryGroup];
22779
22780                if (!instance) {
22781                    return;
22782                }
22783
22784                instance.open(index);
22785            };
22786
22787            mediaDetailLink.onclick = (event) => {
22788                event.preventDefault();
22789
22790                const currentSrc = mediaDetailImg.getAttribute("src");
22791                const currentIndex = Math.max(gallerySources.indexOf(currentSrc), 0);
22792
22793                openMediaGallery(currentIndex);
22794            };
22795
22796            mediaDetailItems.forEach((item) => {
22797                item.onclick = (event) => {
22798                    event.preventDefault();
22799
22800                    const src = item.querySelector("img")?.getAttribute("src");
22801                    const index = gallerySources.indexOf(src);
22802
22803                    if (!src || index < 0) {
22804                        return;
22805                    }
22806
22807                    syncMediaDetailImage(index);
22808
22809                    openMediaGallery(index);
22810                };
22811            });
22812        }
22813    }
22814
22815    $(".people-detail__media-item").on("click", (event) => {
22816        const index = Array.from(document.querySelectorAll(".people-detail__media-item")).findIndex(item => item === event.currentTarget);
22817
22818        if (index === 0 || index) {
22819            peopleSlider.slideTo(index, 500);
22820        }
22821    });
22822
22823});
22824
22825$(() => {
22826
22827    $(".question__open").on("click", (e) => {
22828        const current = $(e.currentTarget);
22829        const index = current.parent().index();
22830
22831        $(".question__open").each(function () {
22832            if ($(this).parent().index() === index) {
22833                $(this).next().slideToggle(300);
22834                $(this).parent().toggleClass("active");
22835            } else {
22836                $(this).next().slideUp(300);
22837                $(this).parent().removeClass("active");
22838            }
22839        });
22840    });
22841
22842    $(".tile_drop-down").on("click", (e) => {
22843        const current = $(e.currentTarget);
22844
22845        $(current).find(".tile__subtitle").slideToggle(300);
22846        $(current).toggleClass("active");
22847
22848        $(".tile_drop-down").not(current).removeClass("active");
22849        $(".tile_drop-down").not(current).find(".tile__subtitle").slideUp(300);
22850    });
22851});
22852
22853document.addEventListener("DOMContentLoaded", function () {
22854    try {
22855        const buildings = document.querySelectorAll('g[id^="здание_"]');
22856        const scrollItem = document.querySelector(".map__scroll-item");
22857        const currentWidth = document.documentElement.offsetWidth;
22858        const isMobile = currentWidth <= 600;
22859        const isDesktop = !isMobile;
22860
22861        let activePair = null;
22862        let activeContent = null;
22863
22864        const resetActivePair = () => {
22865            if (!activePair) return;
22866
22867            activePair.base.style.display = "block";
22868            activePair.detail.style.display = "none";
22869            if (activePair.button) activePair.button.style.display = "none";
22870            activePair = null;
22871        };
22872
22873        const closeActiveContent = () => {
22874            if (!activeContent) return;
22875
22876            activeContent.style.display = "none";
22877            activeContent = null;
22878
22879            if (isMobile) {
22880                unlockBodyScroll();
22881            }
22882        };
22883
22884        buildings.forEach(building => {
22885            const id = building.id;
22886
22887            // Основной слой (без хвоста _xxxxx_)
22888            if (!id.match(/_\d{5,}_/)) {
22889                const detailed = document.querySelector(`g[id^="${id}_"]`);
22890                if (!detailed) return;
22891
22892                const buildingNumberMatch = id.match(/\d+/);
22893                const buildingNumber = buildingNumberMatch ? buildingNumberMatch[0] : null;
22894
22895                const button = buildingNumber ? document.querySelector(`#map-btn-${buildingNumber}`) : null;
22896                const content = buildingNumber ? document.querySelector(`#map-content-${buildingNumber}`) : null;
22897
22898                // Мобильная раскладка: перетаскиваем кнопки и контент внутрь .map__scroll-item
22899                if (button && isMobile) {
22900                    button.className = "map__mobile-btn";
22901                    button.textContent = "";
22902                    scrollItem.append(button);
22903                }
22904
22905                if (content && isMobile) {
22906                    scrollItem.append(content);
22907                }
22908
22909                detailed.style.display = "none";
22910                if (button) button.style.display = "none";
22911                if (content) content.style.display = "none";
22912
22913                const showDetailed = () => {
22914                    resetActivePair();
22915
22916                    building.style.display = "none";
22917                    detailed.style.display = "block";
22918                    if (button) button.style.display = "block";
22919
22920                    activePair = {base: building, detail: detailed, button: button};
22921                };
22922
22923                const hideDetailed = () => {
22924                    building.style.display = "block";
22925                    detailed.style.display = "none";
22926                    if (button) button.style.display = "none";
22927                    if (activePair && activePair.base === building) {
22928                        activePair = null;
22929                    }
22930                };
22931
22932                // Функция открытия попапа (контента)
22933                const openContent = (e) => {
22934                    if (e) {
22935                        e.preventDefault();
22936                        e.stopPropagation();
22937                    }
22938
22939                    if (!content) return;
22940
22941                    closeActiveContent();
22942                    resetActivePair();
22943
22944                    content.style.display = "block";
22945                    activeContent = content;
22946
22947                    if (isMobile) {
22948                        lockBodyScroll();
22949                    }
22950                };
22951
22952                // ====== DESKTOP / HOVER-ЛОГИКА ======
22953                if (isDesktop) {
22954                    building.addEventListener("mouseenter", showDetailed);
22955                    detailed.addEventListener("mouseleave", hideDetailed);
22956
22957                    building.addEventListener("touchstart", (e) => {
22958                        e.preventDefault();
22959                        showDetailed();
22960                    }, {passive: false});
22961
22962                    detailed.addEventListener("touchstart", (e) => {
22963                        e.preventDefault();
22964                        hideDetailed();
22965                    }, {passive: false});
22966                }
22967
22968                // ====== Кнопка (общая для мобилы и десктопа) ======
22969                if (button && content) {
22970                    button.addEventListener("click", (e) => {
22971                        e.preventDefault();
22972                        openContent(e);
22973                    });
22974
22975                    const closeBtn = content.querySelector(".map__content-close");
22976                    if (closeBtn) {
22977                        closeBtn.addEventListener("click", (e) => {
22978                            e.preventDefault();
22979                            closeActiveContent();
22980                        });
22981                    }
22982                }
22983
22984                // ====== МОБИЛЬНАЯ ЛОГИКА: тап по зданию → сразу попап ======
22985                if (isMobile) {
22986                    const TAP_MOVE_THRESHOLD = 10;
22987                    let touchStartX = 0;
22988                    let touchStartY = 0;
22989                    let touchMoved = false;
22990                    let suppressClick = false;
22991
22992                    const handleMobileTap = (e) => {
22993                        e.preventDefault();
22994                        e.stopPropagation();
22995
22996                        showDetailed();
22997                        openContent(e);
22998                    };
22999
23000                    const handleTouchStart = (e) => {
23001                        const touch = e.touches && e.touches[0];
23002                        if (!touch) return;
23003
23004                        touchStartX = touch.clientX;
23005                        touchStartY = touch.clientY;
23006                        touchMoved = false;
23007                    };
23008
23009                    const handleTouchMove = (e) => {
23010                        const touch = e.touches && e.touches[0];
23011                        if (!touch) return;
23012
23013                        if (
23014                            Math.abs(touch.clientX - touchStartX) > TAP_MOVE_THRESHOLD ||
23015                            Math.abs(touch.clientY - touchStartY) > TAP_MOVE_THRESHOLD
23016                        ) {
23017                            touchMoved = true;
23018                        }
23019                    };
23020
23021                    const handleTouchEnd = (e) => {
23022                        if (touchMoved) return;
23023
23024                        suppressClick = true;
23025                        handleMobileTap(e);
23026
23027                        window.setTimeout(() => {
23028                            suppressClick = false;
23029                        }, 350);
23030                    };
23031
23032                    const handleClick = (e) => {
23033                        if (suppressClick) {
23034                            e.preventDefault();
23035                            e.stopPropagation();
23036                            return;
23037                        }
23038
23039                        handleMobileTap(e);
23040                    };
23041
23042                    [building, detailed].forEach((item) => {
23043                        item.addEventListener("touchstart", handleTouchStart, {passive: true, capture: true});
23044                        item.addEventListener("touchmove", handleTouchMove, {passive: true, capture: true});
23045                        item.addEventListener("touchend", handleTouchEnd, {passive: false, capture: true});
23046                        item.addEventListener("click", handleClick, true);
23047                    });
23048                }
23049            }
23050        });
23051
23052        // Сброс при уходе мыши со всего SVG (актуально только для десктопа)
23053        const svg = document.querySelector("svg");
23054        if (svg) {
23055            svg.addEventListener("mouseleave", () => {
23056                resetActivePair();
23057            });
23058        }
23059
23060        // Закрытие контента по клику вне него
23061        document.addEventListener("click", (e) => {
23062            if (
23063                activeContent &&
23064                !activeContent.contains(e.target) &&
23065                !e.target.matches('[id^="map-btn-"]')
23066            ) {
23067                closeActiveContent();
23068            }
23069        });
23070
23071    } catch (error) {
23072        console.log(error);
23073    }
23074
23075    $(".block-header__sort-mobile").on("click", () => {
23076        const filter = document.getElementById("media-filter");
23077        if (!filter || window.innerWidth > 1200) return;
23078
23079        filter.classList.add("is-open");
23080        document.body.classList.add("media-filter-open");
23081    });
23082
23083});
23084
23085
23086document.addEventListener('DOMContentLoaded', () => {
23087    const videoButtons = document.querySelectorAll(".detail__play-btn");
23088
23089    videoButtons.forEach(item => {
23090
23091        item.addEventListener("click", () => {
23092            const video = item.parentElement.querySelector("video");
23093
23094            video.play();
23095            item.remove();
23096        });
23097
23098    });
23099
23100    const inputs = document.querySelectorAll(".audio__input, .audio__sound-input");
23101    const activeColor = "#FFFFFF";
23102    const unactiveColor = "#B2B2B2";
23103
23104    function setWidth(elem) {
23105        const width = (elem.value - elem.min) / (elem.max - elem.min) * 100;
23106        elem.style.background = `linear-gradient(90deg, ${activeColor} ${width}%, ${unactiveColor} ${width}%)`;
23107    }
23108
23109    inputs.forEach(input => {
23110        input.addEventListener("input", (e) => {
23111            setWidth(e.currentTarget);
23112        });
23113        setWidth(input);
23114    });
23115
23116    // Вспомогательная функция для форматирования времени
23117    function formatTime(seconds) {
23118        if (isNaN(seconds) || seconds < 0) {
23119            return '0:00';
23120        }
23121        const minutes = Math.floor(seconds / 60);
23122        const remainingSeconds = Math.floor(seconds % 60);
23123        return `${minutes}:${remainingSeconds < 10 ? '0' : ''}${remainingSeconds}`;
23124    }
23125
23126    // Функция инициализации одного аудио-плеера
23127    function initializeAudioPlayer(playerContainer) {
23128        // 1. Получаем ссылку на реальный аудио-элемент внутри ЭТОГО контейнера
23129        const audio = playerContainer.querySelector('audio');
23130
23131        // Проверка наличия аудио-элемента и его src
23132        if (!audio || !audio.src || audio.src === window.location.href + '#') {
23133            console.warn("Skipping player due to missing audio element or src:", playerContainer);
23134            // Отключаем интерфейс, если аудио недоступно
23135            playerContainer.classList.add('audio--disabled');
23136            playerContainer.querySelectorAll('button, input').forEach(el => el.disabled = true);
23137            return;
23138        }
23139
23140        // 2. Получаем ссылки на элементы управления ИЗ ЭТОГО КОНТЕЙНЕРА
23141        const playBtn = playerContainer.querySelector('.audio__play-btn');
23142        const playIcon = playBtn.querySelector('.icon-play');
23143        const pauseIcon = playBtn.querySelector('.icon-pause');
23144
23145        const startTimeSpan = playerContainer.querySelector('.audio__start-time');
23146        const endTimeSpan = playerContainer.querySelector('.audio__end-time');
23147        const progressBar = playerContainer.querySelector('.audio__input');
23148
23149        const volumeSlider = playerContainer.querySelector('.audio__sound-input');
23150        const soundBtn = playerContainer.querySelector('.audio__sound-btn');
23151        const speakerIcon = soundBtn.querySelector('.icon-speaker');
23152        const mutedIcon = soundBtn.querySelector('.icon-muted');
23153        const audioSound = playerContainer.querySelector('.audio__sound');
23154
23155        const settingsBtn = playerContainer.querySelector('.audio__settings-btn');
23156        const settingsPanel = playerContainer.querySelector('.audio__settings .settings');
23157        // Находим все радиокнопки скорости ВНУТРИ ЭТОГО плеера, независимо от их уникального имени
23158        const speedRadios = playerContainer.querySelectorAll('.settings__checkbox-input[type="radio"]');
23159
23160        let lastVolume = audio.volume; // Сохраняем начальную громкость
23161        let isSeeking = false; // Флаг для отслеживания перемотки
23162
23163        // --- Инициализация плеера ---
23164
23165        // Устанавливаем начальную громкость и ползунок
23166        audio.volume = volumeSlider.value / 100;
23167        lastVolume = audio.volume;
23168
23169        // Устанавливаем начальную скорость воспроизведения (из выбранной радиокнопки)
23170        const initialSpeedRadio = playerContainer.querySelector('.settings__checkbox-input[type="radio"]:checked');
23171        if (initialSpeedRadio) {
23172            audio.playbackRate = parseFloat(initialSpeedRadio.value);
23173        } else {
23174            audio.playbackRate = 1.0; // По умолчанию
23175        }
23176
23177        // Отключаем ползунок прогресса, пока аудио не загружено
23178        progressBar.disabled = true;
23179
23180        // --- Обработчики событий ---
23181
23182        // 1. Кнопка Play/Pause
23183        playBtn.addEventListener('click', () => {
23184            if (audio.paused) {
23185                // Если какой-либо другой плеер играет, поставить его Ð
23185½Ð° паузу
23186                document.querySelectorAll('audio').forEach(otherAudio => {
23187                    if (otherAudio !== audio && !otherAudio.paused) {
23188                        otherAudio.pause();
23189                    }
23190                });
23191                audio.play();
23192            } else {
23193                audio.pause();
23194            }
23195        });
23196
23197        audio.addEventListener('play', () => {
23198            playIcon.style.display = 'none';
23199            pauseIcon.style.display = 'block';
23200        });
23201
23202        audio.addEventListener('pause', () => {
23203            playIcon.style.display = 'block';
23204            pauseIcon.style.display = 'none';
23205        });
23206
23207        audio.addEventListener('ended', () => {
23208            playIcon.style.display = 'block';
23209            pauseIcon.style.display = 'none';
23210            audio.currentTime = 0;
23211            progressBar.value = 0;
23212            startTimeSpan.textContent = '0:00';
23213        });
23214
23215        // 2. Обновление времени и прогресс-бара
23216        audio.addEventListener('loadedmetadata', () => {
23217            endTimeSpan.textContent = formatTime(audio.duration);
23218            progressBar.max = audio.duration;
23219            progressBar.disabled = false;
23220        });
23221
23222        audio.addEventListener('timeupdate', () => {
23223            if (!isSeeking) {
23224                progressBar.value = audio.currentTime;
23225                setWidth(progressBar);
23226            }
23227            startTimeSpan.textContent = formatTime(audio.currentTime);
23228        });
23229
23230        progressBar.addEventListener('mousedown', () => {
23231            isSeeking = true;
23232        });
23233        progressBar.addEventListener('mouseup', () => {
23234            isSeeking = false;
23235            audio.currentTime = progressBar.value;
23236        });
23237        progressBar.addEventListener('input', () => {
23238            startTimeSpan.textContent = formatTime(progressBar.value);
23239        });
23240
23241        // 3. Регулировка громкости
23242        volumeSlider.addEventListener('input', () => {
23243            const newVolume = volumeSlider.value / 100;
23244            audio.volume = newVolume;
23245
23246            if (newVolume === 0) {
23247                audio.muted = true;
23248            } else {
23249                audio.muted = false;
23250                lastVolume = newVolume;
23251            }
23252        });
23253
23254        // 4. Кнопка Mute/Unmute
23255        soundBtn.addEventListener('click', () => {
23256            audioSound.classList.toggle("opened");
23257        });
23258
23259        // Слушаем событие volumechange на аудио-элементе для синхронизации UI
23260        audio.addEventListener('volumechange', () => {
23261            volumeSlider.value = audio.volume * 100;
23262            if (audio.muted || audio.volume === 0) {
23263                speakerIcon.style.display = 'none';
23264                mutedIcon.style.display = 'block';
23265            } else {
23266                speakerIcon.style.display = 'block';
23267                mutedIcon.style.display = 'none';
23268            }
23269        });
23270
23271        // Инициализация иконки звука при загрузке
23272        if (audio.volume === 0 || audio.muted) {
23273            speakerIcon.style.display = 'none';
23274            mutedIcon.style.display = 'block';
23275        } else {
23276            speakerIcon.style.display = 'block';
23277            mutedIcon.style.display = 'none';
23278        }
23279
23280        // 5. Настройки скорости воспроизведения
23281        settingsBtn.addEventListener('click', (e) => {
23282            e.stopPropagation(); // Предотвратить закрытие, если клик по кнопке
23283            settingsPanel.style.display = settingsPanel.style.display === 'block' ? 'none' : 'block';
23284        });
23285
23286        speedRadios.forEach(radio => {
23287            radio.addEventListener('change', (event) => {
23288                const selectedSpeed = parseFloat(event.target.value);
23289                if (!isNaN(selectedSpeed)) {
23290                    document.querySelectorAll('audio').forEach(audio => {
23291                        audio.playbackRate = selectedSpeed;
23292                    });
23293
23294                    console.log(`[Player ${playerContainer.dataset.playerId}] Скорость воспроизведения изменена на: ${selectedSpeed}`);
23295                    settingsPanel.style.display = 'none';
23296                }
23297            });
23298        });
23299
23300        // Закрытие панели настроек при клике вне нее
23301        document.addEventListener('click', (e) => {
23302            // Проверяем, что клик не был внутри текущего плеера и панель настроек открыта
23303            if (!playerContainer.contains(e.target) && settingsPanel.style.display === 'block') {
23304                settingsPanel.style.display = 'none';
23305            }
23306        });
23307    }
23308
23309    // --- Главная логика: найти все плееры и инициализировать их ---
23310    const allAudioPlayerContainers = document.querySelectorAll('.audio');
23311    allAudioPlayerContainers.forEach(container => {
23312        initializeAudioPlayer(container);
23313    });
23314
23315    refreshFsLightbox();
23316
23317});
23318
23319function filter() {
23320    (function () {
23321        if (window.__mediaAjaxInited) return;
23322        window.__mediaAjaxInited = true;
23323
23324        const FILTER_BOX_ID = "media-filter";
23325        const LIST_BOX_ID = "media-list";
23326
23327        let controller = null;
23328        let mobileFilterEventsBound = false;
23329
23330        function isMobileFilterMode() {
23331            return window.innerWidth <= 1200;
23332        }
23333
23334        function getFilterElement() {
23335            return document.getElementById(FILTER_BOX_ID);
23336        }
23337
23338        function openMobileFilterPanel() {
23339            if (!isMobileFilterMode()) return;
23340
23341            const filter = getFilterElement();
23342            if (!filter) return;
23343
23344            filter.classList.add("is-open");
23345            document.body.classList.add("media-filter-open");
23346        }
23347
23348        function closeMobileFilterPanel() {
23349            if (!isMobileFilterMode()) return;
23350
23351            const filter = getFilterElement();
23352            if (!filter) return;
23353
23354            filter.classList.remove("is-open");
23355            document.body.classList.remove("media-filter-open");
23356        }
23357
23358        function closeMediaDropdowns() {
23359            $(".nav-list__sort-wrap .drop-down-wrap").stop(true, true).slideUp(300);
23360        }
23361
23362        function getBoxes() {
23363            return {
23364                filterBox: document.getElementById(FILTER_BOX_ID),
23365                listBox: document.getElementById(LIST_BOX_ID)
23366            };
23367        }
23368
23369        function currentForm() {
23370            return document.querySelector("[data-media-filter-form]");
23371        }
23372
23373        function syncMobileButtonsState() {
23374            const form = currentForm();
23375            if (!form) return;
23376
23377            const clearBtn = form.querySelector("[data-media-filter-clear]");
23378            const applyBtn = form.querySelector("[data-media-filter-apply]");
23379            const actions = form.querySelector(".filter__mobile-actions");
23380            if (!clearBtn || !applyBtn) return;
23381
23382            const hasChecked = form.querySelector('input.checkbox__input[type="checkbox"]:checked');
23383            clearBtn.classList.toggle("is-visible", !!hasChecked);
23384            clearBtn.disabled = !hasChecked;
23385            if (actions) actions.classList.toggle("is-clear-visible", !!hasChecked);
23386            applyBtn.textContent = "Применить";
23387        }
23388
23389        function bindMobileFilterButtons() {
23390            const form = currentForm();
23391            if (!form) return;
23392
23393            const closeBtn = form.querySelector("[data-media-filter-close]");
23394            const applyBtn = form.querySelector("[data-media-filter-apply]");
23395            const clearBtn = form.querySelector("[data-media-filter-clear]");
23396
23397            if (closeBtn && !closeBtn.dataset.mediaFilterBound) {
23398                closeBtn.dataset.mediaFilterBound = "Y";
23399                closeBtn.addEventListener("click", (e) => {
23400                    e.preventDefault();
23401                    closeMobileFilterPanel();
23402                });
23403            }
23404
23405            if (applyBtn && !applyBtn.dataset.mediaFilterBound) {
23406                applyBtn.dataset.mediaFilterBound = "Y";
23407                applyBtn.addEventListener("click", (e) => {
23408                    e.preventDefault();
23409
23410                    if (isMobileFilterMode()) {
23411                        closeMobileFilterPanel();
23412                        return;
23413                    }
23414
23415                    const url = buildUrlFromForm(window.location.href, true);
23416                    closeMobileFilterPanel();
23417                    load(url, true);
23418                });
23419            }
23420
23421            if (clearBtn && !clearBtn.dataset.mediaFilterBound) {
23422                clearBtn.dataset.mediaFilterBound = "Y";
23423                clearBtn.addEventListener("click", (e) => {
23424                    e.preventDefault();
23425
23426                    form.querySelectorAll('input.checkbox__input[type="checkbox"]').forEach((input) => {
23427                        input.checked = false;
23428                    });
23429
23430                    syncMobileButtonsState();
23431                });
23432            }
23433
23434            mobileFilterEventsBound = true;
23435        }
23436
23437        function buildUrlFromForm(baseHref, resetPager) {
23438            const form = currentForm();
23439            const url = new URL(baseHref || window.location.href, window.location.origin);
23440
23441            const fd = new FormData(form);
23442            const params = new URLSearchParams();
23443
23444            for (const [k, v] of fd.entries()) params.append(k, v);
23445
23446            if (resetPager) {
23447                for (const key of Array.from(params.keys())) {
23448                    if (key.startsWith("PAGEN_")) params.delete(key);
23449                }
23450            }
23451
23452            params.set("ajax", "Y");
23453            url.search = params.toString();
23454            return url;
23455        }
23456
23457        function buildUrlWithParam(name, value) {
23458            const url = new URL(window.location.href);
23459
23460            if (!value || value === "0") url.searchParams.delete(name);
23461            else url.searchParams.set(name, value);
23462
23463            // сброс пагинации при смене year/sort/filter
23464            for (const key of Array.from(url.searchParams.keys())) {
23465                if (key.startsWith("PAGEN_")) url.searchParams.delete(key);
23466            }
23467
23468            url.searchParams.set("ajax", "Y");
23469            return url;
23470        }
23471
23472        function cleanAjax(url) {
23473            const clean = new URL(url.toString());
23474            clean.searchParams.delete("ajax");
23475            return clean.toString();
23476        }
23477
23478        function scrollToMediaTop() {
23479            const target = document.querySelector(".media") || document.getElementById(LIST_BOX_ID);
23480            if (!target) return;
23481
23482            const top = window.pageYOffset + target.getBoundingClientRect().top;
23483            window.scrollTo({
23484                top: Math.max(0, top),
23485                behavior: "smooth"
23486            });
23487        }
23488
23489        async function load(url, pushState) {
23490            const {filterBox, listBox} = getBoxes();
23491            if (!filterBox || !listBox) {
23492                // если контейнеров нет — делаем обычный переход
23493                window.location.href = cleanAjax(url);
23494                return;
23495            }
23496
23497            try {
23498                if (controller) controller.abort();
23499                controller = new AbortController();
23500
23501                listBox.classList.add("is-loading");
23502
23503                const res = await fetch(url.toString(), {
23504                    method: "GET",
23505                    credentials: "same-origin",
23506                    headers: {"X-Requested-With": "XMLHttpRequest"},
23507                    signal: controller.signal
23508                });
23509
23510                if (!res.ok) throw new Error("HTTP " + res.status);
23511
23512                const html = await res.text();
23513                const doc = new DOMParser().parseFromString(html, "text/html");
23514
23515                const newFilter = doc.getElementById(FILTER_BOX_ID);
23516                const newList = doc.getElementById(LIST_BOX_ID);
23517
23518                if (newFilter) filterBox.innerHTML = newFilter.innerHTML;
23519                if (newList) listBox.innerHTML = newList.innerHTML;
23520                bindMobileFilterButtons();
23521                syncMobileButtonsState();
23522
23523                if (pushState) history.pushState({}, "", cleanAjax(url));
23524
23525                if (url.searchParams.has("PAGEN_1") || Array.from(url.searchParams.keys()).some((key) => key.startsWith("PAGEN_"))) {
23526                    scrollToMediaTop();
23527                }
23528            } catch (e) {
23529                if (e && e.name === "AbortError") return;
23530                window.location.href = cleanAjax(url);
23531            } finally {
23532                const {listBox: lb2} = getBoxes();
23533                if (lb2) lb2.classList.remove("is-loading");
23534            }
23535        }
23536
23537        // 1) Фильтр: чекбоксы => AJAX
23538        document.addEventListener("change", (e) => {
23539            const t = e.target;
23540            if (!t || !t.classList.contains("checkbox__input")) return;
23541            if (t.disabled) return;
23542
23543            const form = currentForm();
23544            if (!form) return;
23545
23546            syncMobileButtonsState();
23547
23548            // сброс PAGEN_* при смене фильтра
23549            form.querySelectorAll('input[name^="PAGEN_"]').forEach(n => n.remove());
23550
23551            const url = buildUrlFromForm(window.location.href, true);
23552
23553            if (!isMobileFilterMode()) {
23554                closeMobileFilterPanel();
23555            }
23556
23557            load(url, true);
23558        });
23559
23560        document.addEventListener("submit", (e) => {
23561            const form = e.target;
23562            if (!form || !form.matches("[data-media-filter-form]")) return;
23563
23564            e.preventDefault();
23565
23566            if (isMobileFilterMode()) {
23567                closeMobileFilterPanel();
23568                return;
23569            }
23570
23571            const url = buildUrlFromForm(window.location.href, true);
23572            closeMobileFilterPanel();
23573            load(url, true);
23574        });
23575
23576        // 2) Показать все / скрыть (локально, без запроса)
23577        document.addEventListener("click", (e) => {
23578            const openBtn = e.target.closest(".block-header__sort-mobile");
23579            if (openBtn) {
23580                e.preventDefault();
23581                openMobileFilterPanel();
23582                return;
23583            }
23584
23585            const btn = e.target.closest("[data-filter-more]");
23586            if (!btn) return;
23587
23588            const group = btn.closest(".filter__group");
23589            if (!group) return;
23590
23591            const list = group.querySelector("[data-filter-list]");
23592            if (!list) return;
23593
23594            const visible = parseInt(list.getAttribute("data-visible") || "6", 10);
23595            const collapsed = list.getAttribute("data-collapsed") === "1";
23596            const items = Array.from(list.querySelectorAll("li"));
23597
23598            if (collapsed) {
23599                items.forEach(li => li.classList.remove("is-hidden"));
23600                list.setAttribute("data-collapsed", "0");
23601                btn.textContent = "Скрыть";
23602            } else {
23603                items.forEach((li, idx) => {
23604                    if (idx >= visible) li.classList.add("is-hidden");
23605                });
23606                list.setAttribute("data-collapsed", "1");
23607                btn.textContent = "Показать все";
23608            }
23609        });
23610
23611        document.addEventListener("keydown", (e) => {
23612            if (e.key !== "Escape") return;
23613            closeMobileFilterPanel();
23614        });
23615
23616        window.addEventListener("resize", () => {
23617            if (!isMobileFilterMode()) closeMobileFilterPanel();
23618            syncMobileButtonsState();
23619        });
23620
23621        // 3) Пагинация в списке => AJAX
23622        document.addEventListener("click", (e) => {
23623            const a = e.target.closest("#" + LIST_BOX_ID + " a");
23624            if (!a) return;
23625
23626            const href = a.getAttribute("href") || "";
23627            if (!href.includes("PAGEN_")) return;
23628
23629            e.preventDefault();
23630            const url = new URL(href, window.location.origin);
23631            url.searchParams.set("ajax", "Y");
23632            load(url, true);
23633        });
23634
23635        // 4) Year / Sort => AJAX (кнопки в дропдауне)
23636        document.addEventListener("click", (e) => {
23637            const yBtn = e.target.closest("[data-year]");
23638            if (yBtn) {
23639                e.preventDefault();
23640                const year = yBtn.getAttribute("data-year") || "0";
23641                const url = buildUrlWithParam("year", year);
23642                closeMediaDropdowns();
23643                closeMobileFilterPanel();
23644                load(url, true);
23645                return;
23646            }
23647
23648            const sBtn = e.target.closest("[data-sort]");
23649            if (sBtn) {
23650                e.preventDefault();
23651                const sort = sBtn.getAttribute("data-sort") || "new";
23652                const url = buildUrlWithParam("sort", sort);
23653                closeMediaDropdowns();
23654                closeMobileFilterPanel();
23655                load(url, true);
23656                return;
23657            }
23658        });
23659
23660        // 5) Back/Forward
23661        window.addEventListener("popstate", () => {
23662            const url = new URL(window.location.href);
23663            url.searchParams.set("ajax", "Y");
23664            load(url, false);
23665        });
23666
23667        document.addEventListener("DOMContentLoaded", () => {
23668            bindMobileFilterButtons();
23669            syncMobileButtonsState();
23670        });
23671
23672        window.__mediaFilterApi = {
23673            buildUrlFromForm,
23674            cleanAjax,
23675            currentForm,
23676            load,
23677            syncMobileButtonsState
23678        };
23679
23680        if (!mobileFilterEventsBound) {
23681            bindMobileFilterButtons();
23682        }
23683    })();
23684
23685    (function () {
23686        if (window.__mediaChipsInited) return;
23687        window.__mediaChipsInited = true;
23688
23689        const FILTER_BOX_ID = 'media-filter';
23690        const CHIPS_ID = 'media-active-filters';
23691
23692        function esc(s) {
23693            return String(s || '')
23694                .replaceAll('&', '&amp;')
23695                .replaceAll('<', '&lt;')
23696                .replaceAll('>', '&gt;')
23697                .replaceAll('"', '&quot;')
23698                .replaceAll("'", '&#039;');
23699        }
23700
23701        function getUrlParam(name) {
23702            try {
23703                return new URL(window.location.href).searchParams.get(name) || '';
23704            } catch (e) {
23705                return '';
23706            }
23707        }
23708
23709        function getPropTitleForInput(input) {
23710            const group = input.closest('.filter__group');
23711            if (!group) return '';
23712            const t = group.querySelector('.filter__group-title');
23713            return (t ? t.textContent : '').trim();
23714        }
23715
23716        function isMobileActiveFilters() {
23717            return window.innerWidth <= 768;
23718        }
23719
23720        function clearAllFilters() {
23721            const api = window.__mediaFilterApi || null;
23722            const form = api && typeof api.currentForm === 'function' ? api.currentForm(
23722) : document.querySelector('[data-media-filter-form]');
23723            if (!form) return;
23724
23725            form.querySelectorAll('input.checkbox__input[type="checkbox"]').forEach((input) => {
23726                input.checked = false;
23727            });
23728
23729            if (api && typeof api.syncMobileButtonsState === 'function') {
23730                api.syncMobileButtonsState();
23731            }
23732
23733            let url;
23734
23735            if (api && typeof api.buildUrlFromForm === 'function') {
23736                url = api.buildUrlFromForm(window.location.href, true);
23737            } else {
23738                url = new URL(window.location.href);
23739            }
23740
23741            url.searchParams.delete('year');
23742            url.searchParams.delete('sort');
23743            url.searchParams.delete('del_filter');
23744
23745            for (const key of Array.from(url.searchParams.keys())) {
23746                if (key.startsWith('PAGEN_')) url.searchParams.delete(key);
23747            }
23748
23749            url.searchParams.set('ajax', 'Y');
23750
23751            if (api && typeof api.load === 'function') {
23752                api.load(url, true);
23753                return;
23754            }
23755
23756            window.location.href = url.toString();
23757        }
23758
23759        function buildChips() {
23760            const chipsWrap = document.getElementById(CHIPS_ID);
23761            const filterBox = document.getElementById(FILTER_BOX_ID);
23762            if (!chipsWrap || !filterBox) return;
23763
23764            const chips = [];
23765
23766            // 1) Чекбоксы фильтра
23767            const checkedInputs = filterBox.querySelectorAll('input.checkbox__input[type="checkbox"]:checked');
23768            checkedInputs.forEach((input) => {
23769                if (input.disabled) return;
23770
23771                const id = input.id;
23772
23773                const label = id ? filterBox.querySelector('label[for="' + CSS.escape(id) + '"]') : null;
23774                const valueText = ((label ? label.textContent : input.value) || '').trim();
23775                if (!valueText) return;
23776
23777                const propTitle = getPropTitleForInput(input);
23778                const chipText = isMobileActiveFilters()
23779                    ? valueText
23780                    : (propTitle ? (propTitle + ': ' + valueText) : valueText);
23781
23782                chips.push({
23783                    type: 'checkbox',
23784                    id: id,
23785                    text: chipText
23786                });
23787            });
23788
23789            // 2) year/sort как отдельные чипсы (если выбраны)
23790            const year = getUrlParam('year');
23791            if (year && year !== '0') {
23792                chips.push({type: 'year', text: 'Год: ' + year});
23793            }
23794
23795            const sort = getUrlParam('sort');
23796            if (sort === 'popular') {
23797                chips.push({type: 'sort', text: 'Сортировка: Сначала популярные'});
23798            }
23799
23800            if (!chips.length) {
23801                chipsWrap.innerHTML = '';
23802                return;
23803            }
23804
23805            chipsWrap.innerHTML = `
23806            <div class="media-active-filters">
23807                ${isMobileActiveFilters() ? `
23808                    <button type="button" class="media-active-filters__reset" data-chip-reset-all>
23809                        Сбросить
23810                    </button>
23811                ` : ''}
23812                ${chips.map((c) => `
23813                    <button type="button"
23814                            class="media-active-filters__chip"
23815                            data-chip-type="${esc(c.type)}"
23816                            data-chip-id="${esc(c.id || '')}">
23817                        <span class="media-active-filters__text">${esc(c.text)}</span>
23818                        <span class="media-active-filters__x" aria-hidden="true">×</span>
23819                    </button>
23820                `).join('')}
23821            </div>
23822        `;
23823        }
23824
23825        function removeCheckboxChip(inputId) {
23826            const filterBox = document.getElementById(FILTER_BOX_ID);
23827            if (!filterBox || !inputId) return;
23828
23829            const input = filterBox.querySelector('#' + CSS.escape(inputId));
23830            if (!input) return;
23831
23832            input.checked = false;
23833            input.dispatchEvent(new Event('change', {bubbles: true}));
23834        }
23835
23836        function removeYearChip() {
23837            const btn = document.querySelector('[data-year="0"]');
23838            if (btn) btn.click();
23839            else {
23840                const url = new URL(window.location.href);
23841                url.searchParams.delete('year');
23842                window.location.href = url.toString();
23843            }
23844        }
23845
23846        function removeSortChip() {
23847            const btn = document.querySelector('[data-sort="new"]');
23848            if (btn) btn.click();
23849            else {
23850                const url = new URL(window.location.href);
23851                url.searchParams.set('sort', 'new');
23852                window.location.href = url.toString();
23853            }
23854        }
23855
23856        document.addEventListener('click', (e) => {
23857            const resetBtn = e.target.closest('[data-chip-reset-all]');
23858            if (resetBtn) {
23859                e.preventDefault();
23860                clearAllFilters();
23861                return;
23862            }
23863
23864            const chip = e.target.closest('.media-active-filters__chip');
23865            if (!chip) return;
23866
23867            const type = chip.getAttribute('data-chip-type') || '';
23868            const id = chip.getAttribute('data-chip-id') || '';
23869
23870            if (type === 'checkbox') removeCheckboxChip(id);
23871            else if (type === 'year') removeYearChip();
23872            else if (type === 'sort') removeSortChip();
23873        });
23874
23875        function watchFilter() {
23876            const filterBox = document.getElementById(FILTER_BOX_ID);
23877            if (!filterBox) return;
23878
23879            const obs = new MutationObserver(() => buildChips());
23880            obs.observe(filterBox, {childList: true, subtree: true});
23881
23882            filterBox.addEventListener('change', () => buildChips(), true);
23883        }
23884
23885        document.addEventListener('DOMContentLoaded', () => {
23886            buildChips();
23887            watchFilter();
23888        });
23889
23890        window.addEventListener('pageshow', () => {
23891            buildChips();
23892        });
23893    })();
23894}
23895
23896window.addEventListener('DOMContentLoaded', () => {
23897    var popup = document.querySelector('[data-cookie-popup]');
23898    if (!popup) return;
23899
23900    var acceptBtn = popup.querySelector('[data-cookie-accept]');
23901    var necessaryBtn = popup.querySelector('[data-cookie-necessary]');
23902    var rejectBtn = popup.querySelector('[data-cookie-reject]');
23903    var closeBtn = popup.querySelector('[data-cookie-close]');
23904    var storageKey = 'msdm_cookie_consent_v2';
23905    var cookieName = 'msdm_cookie_consent_v2';
23906    var maxAge = 60 * 60 * 24 * 365;
23907    var consentValues = {
23908        accept: true,
23909        necessary: true,
23910        reject: true
23911    };
23912
23913    function hasConsent() {
23914        try {
23915            if (window.localStorage && consentValues[localStorage.getItem(storageKey)]) {
23916                return true;
23917            }
23918        } catch (e) {}
23919
23920        return document.cookie.split(';').some(function (part) {
23921            var cookieValue = part.trim();
23922            return cookieValue.indexOf(cookieName + '=accept') === 0
23923                || cookieValue.indexOf(cookieName + '=necessary') === 0
23924                || cookieValue.indexOf(cookieName + '=reject') === 0;
23925        });
23926    }
23927
23928    function saveConsentToJson(choice) {
23929        try {
23930            var body = JSON.stringify({
23931                consent: choice === 'accept',
23932                choice: choice,
23933                cookie_name: cookieName,
23934                timestamp: new Date().toISOString(),
23935                page: window.location.href,
23936                referrer: document.referrer || '',
23937                user_agent: navigator.userAgent || '',
23938                ip: window.__COOKIE_CONSENT_IP || ''
23939            });
23940
23941            fetch('/cookie-consent.php', {
23942                method: 'POST',
23943                headers: {
23944                    'Content-Type': 'application/json'
23945                },
23946                body: body,
23947                credentials: 'same-origin'
23948            }).catch(function () {});
23949        } catch (e) {}
23950    }
23951
23952    function persistChoice(choice) {
23953        try {
23954            if (window.localStorage) {
23955                localStorage.setItem(storageKey, choice);
23956            }
23957        } catch (e) {}
23958
23959        document.cookie = cookieName + '=' + encodeURIComponent(choice) + '; path=/; max-age=' + maxAge + '; samesite=lax';
23960    }
23961
23962    function hidePopup() {
23963        popup.hidden = true;
23964    }
23965
23966    function choose(choice) {
23967        persistChoice(choice);
23968        saveConsentToJson(choice);
23969        hidePopup();
23970    }
23971
23972    if (hasConsent()) {
23973        hidePopup();
23974        return;
23975    }
23976
23977    popup.hidden = false;
23978
23979    if (acceptBtn) {
23980        acceptBtn.addEventListener('click', function () {
23981            choose('accept');
23982        });
23983    }
23984
23985    if (necessaryBtn) {
23986        necessaryBtn.addEventListener('click', function () {
23987            choose('necessary');
23988        });
23989    }
23990
23991    if (rejectBtn) {
23992        rejectBtn.addEventListener('click', function () {
23993            choose('reject');
23994        });
23995    }
23996
23997    if (closeBtn) {
23998        closeBtn.addEventListener('click', function () {
23999            choose('reject');
24000        });
24001    }
24002});
24003
24004/* End */
24005;
24006; /* Start:"a:4:{s:4:"full";s:59:"/local/templates/msdm/assets/smart-photo.js?179006674614901";s:6:"source";s:43:"/local/templates/msdm/assets/smart-photo.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
24007(function () {
24008    const brotherSelector = '.brother-page__img, .field-item img';
24009    const mediaSelector = '.media-detail__wrap img';
24010    const homeNewsSelector = '.news .news-item__right .news-item__img';
24011    const themeDaySelector = '.theme-day .theme-day__image img';
24012
24013    const hostClass = 'msdm-smart-photo-host';
24014    const mediaHostClass = 'msdm-smart-photo-host_media';
24015    const wrapperClass = 'msdm-smart-photo-wrap';
24016    const imageClass = 'msdm-smart-photo-target';
24017    const backgroundClass = 'msdm-smart-photo-bg';
24018    const observedAttribute = 'data-msdm-smart-photo-observed';
24019    const sizeObservedAttribute = 'data-msdm-smart-photo-size-observed';
24020    const tolerance = 2;
24021    const photoMaxHeight = 700;
24022    let initScheduled = false;
24023
24024    function isSmallForBox(img, boxWidth, boxHeight) {
24025        const naturalWidth = img.naturalWidth || 0;
24026        const naturalHeight = img.naturalHeight || 0;
24027
24028        if (boxWidth <= 0 || boxHeight <= 0 || naturalWidth <= 0 || naturalHeight <= 0) {
24029            return false;
24030        }
24031
24032        return naturalWidth < (boxWidth - tolerance) || naturalHeight < (boxHeight - tolerance);
24033    }
24034
24035    function hasDifferentAspectRatio(img, boxWidth, boxHeight) {
24036        const naturalWidth = img.naturalWidth || 0;
24037        const naturalHeight = img.naturalHeight || 0;
24038
24039        if (boxWidth <= 0 || boxHeight <= 0 || naturalWidth <= 0 || naturalHeight <= 0) {
24040            return false;
24041        }
24042
24043        return Math.abs(1 - ((naturalWidth / naturalHeight) / (boxWidth / boxHeight))) > 0.2;
24044    }
24045
24046    function getBackgroundNode(host) {
24047        let background = Array.from(host.children).find((node) => {
24048            return node.classList && node.classList.contains(backgroundClass);
24049        });
24050
24051        if (!background) {
24052            background = document.createElement('span');
24053            background.className = backgroundClass;
24054            background.setAttribute('aria-hidden', 'true');
24055            host.insertBefore(background, host.firstChild);
24056        }
24057
24058        return background;
24059    }
24060
24061    function resetBrotherImage(img) {
24062        const wrapper = img.parentElement;
24063        if (!wrapper || !wrapper.classList.contains(wrapperClass)) {
24064            return;
24065        }
24066
24067        img.classList.remove(imageClass);
24068        img.style.cssText = img.dataset.msdmOriginalStyle || '';
24069
24070        const background = wrapper.querySelector('.' + backgroundClass);
24071        if (background) {
24072            background.remove();
24073        }
24074
24075        wrapper.before(img);
24076        wrapper.remove();
24077    }
24078
24079    function applyBrotherImage(img) {
24080        if (!(img instanceof HTMLImageElement) || !img.currentSrc) {
24081            return;
24082        }
24083
24084        const existingWrapper = img.parentElement && img.parentElement.classList.contains(wrapperClass)
24085            ? img.parentElement
24086            : null;
24087
24088        if (existingWrapper) {
24089            resetBrotherImage(img);
24090        }
24091
24092        const imageRect = img.getBoundingClientRect();
24093        const boxWidth = Math.round(imageRect.width);
24094        const boxHeight = Math.min(Math.round(imageRect.height), photoMaxHeight);
24095
24096        if (!isSmallForBox(img, boxWidth, boxHeight)) {
24097            return;
24098        }
24099
24100        if (!img.dataset.msdmOriginalStyle) {
24101            img.dataset.msdmOriginalStyle = img.getAttribute('style') || '';
24102        }
24103
24104        const wrapper = document.createElement('span');
24105        wrapper.className = wrapperClass;
24106        img.before(wrapper);
24107        wrapper.appendChild(img);
24108
24109        wrapper.classList.add(hostClass);
24110        wrapper.classList.remove(mediaHostClass);
24111        wrapper.style.width = boxWidth + 'px';
24112        wrapper.style.height = boxHeight + 'px';
24113        wrapper.style.maxHeight = photoMaxHeight + 'px';
24114        wrapper.style.minHeight = boxHeight + 'px';
24115        wrapper.style.marginTop = window.getComputedStyle(img).marginTop;
24116        wrapper.style.marginRight = window.getComputedStyle(img).marginRight;
24117        wrapper.style.marginBottom = window.getComputedStyle(img).marginBottom;
24118        wrapper.style.marginLeft = window.getComputedStyle(img).marginLeft;
24119        wrapper.style.borderRadius = window.getComputedStyle(img).borderRadius;
24120
24121        const background = getBackgroundNode(wrapper);
24122        background.style.backgroundImage = 'url("' + img.currentSrc + '")';
24123
24124        img.classList.add(imageClass);
24125        img.style.margin = '0';
24126        img.style.width = 'auto';
24127        img.style.height = 'auto';
24128        img.style.maxWidth = '100%';
24129        img.style.maxHeight = 'min(100%, ' + photoMaxHeight + 'px)';
24130        img.style.objectFit = 'contain';
24131    }
24132
24133    function resetMediaImage(img) {
24134        const host = img.closest('.media-detail__wrap a');
24135        if (!host) {
24136            return;
24137        }
24138
24139        host.classList.remove(hostClass);
24140        host.style.removeProperty('--msdm-smart-photo-padding-y');
24141        img.classList.remove(imageClass);
24142        img.style.cssText = img.dataset.msdmOriginalStyle || '';
24143
24144        const background = host.querySelector('.' + backgroundClass);
24145        if (background) {
24146            background.remove();
24147        }
24148    }
24149
24150    function applyMediaImage(img) {
24151        if (!(img instanceof HTMLImageElement) || !img.currentSrc) {
24152            return;
24153        }
24154
24155        const wrap = img.closest('.media-detail__wrap');
24156        const host = img.closest('.media-detail__wrap a');
24157        if (!wrap || !host) {
24158            return;
24159        }
24160
24161        const rect = wrap.getBoundingClientRect();
24162        const boxWidth = Math.round(rect.width);
24163        const boxHeight = Math.min(Math.round(rect.height), photoMaxHeight);
24164
24165        if (!isSmallForBox(img, boxWidth, boxHeight)) {
24166            resetMediaImage(img);
24167            return;
24168        }
24169
24170        if (!img.dataset.msdmOriginalStyle) {
24171            img.dataset.msdmOriginalStyle = img.getAttribute('style') || '';
24172        }
24173
24174        host.classList.add(hostClass);
24175        host.classList.add(mediaHostClass);
24176        host.style.setProperty('--msdm-smart-photo-padding-y', '16px');
24177
24178        const background = getBackgroundNode(host);
24179        background.style.backgroundImage = 'url("' + img.currentSrc + '")';
24180
24181        img.classList.add(imageClass);
24182        img.style.margin = '0 auto';
24183        img.style.width = 'auto';
24184        img.style.height = 'auto';
24185        img.style.maxWidth = '100%';
24186        img.style.maxHeight = 'min(calc(100% - 32px), ' + photoMaxHeight + 'px)';
24187        img.style.objectFit = 'contain';
24188    }
24189
24190    function applyHomeNewsImage(img) {
24191        if (!(img instanceof HTMLImageElement) || !img.currentSrc) {
24192            return;
24193        }
24194
24195        const host = img.closest('.news .news-item__right');
24196        if (!host) {
24197            return;
24198        }
24199
24200        const rect = host.getBoundingClientRect();
24201        const boxWidth = Math.round(rect.width);
24202        const boxHeight = Math.round(rect.height);
24203
24204        if (!hasDifferentAspectRatio(img, boxWidth, boxHeight)) {
24205            resetHomeNewsImage(img);
24206            return;
24207        }
24208
24209        if (!img.dataset.msdmOriginalStyle) {
24210            img.dataset.msdmOriginalStyle = img.getAttribute('style') || '';
24211        }
24212
24213        host.classList.add(hostClass, mediaHostClass);
24214        host.style.setProperty('--msdm-smart-photo-padding-y', '16px');
24215
24216        const background = getBackgroundNode(host);
24217        background.style.backgroundImage = 'url("' + img.currentSrc + '")';
24218
24219        img.classList.add(imageClass);
24220        img.style.margin = '0 auto';
24221        img.style.width = 'auto';
24222        img.style.height = 'auto';
24223        img.style.maxWidth = '100%';
24224        img.style.maxHeight = 'calc(100% - 32px)';
24225        img.style.objectFit = 'contain';
24226    }
24227
24228    function resetHomeNewsImage(img) {
24229        const host = img.closest('.news .news-item__right');
24230        if (!host) {
24231            return;
24232        }
24233
24234        host.classList.remove(hostClass, mediaHostClass);
24235        host.style.removeProperty('--msdm-smart-photo-padding-y');
24236        img.classList.remove(imageClass);
24237        img.style.cssText = img.dataset.msdmOriginalStyle || '';
24238
24239        const background = host.querySelector('.' + backgroundClass);
24240        if (background) {
24241            background.remove();
24242        }
24243    }
24244
24245    function applyThemeDayImage(img) {
24246        if (!(img instanceof HTMLImageElement) || !img.currentSrc) {
24247            return;
24248        }
24249
24250        const host = img.closest('.theme-day__image');
24251        if (!host) {
24252            return;
24253        }
24254
24255        const rect = host.getBoundingClientRect();
24256        const boxWidth = Math.round(rect.width);
24257        const boxHeight = Math.round(rect.height);
24258
24259        if (!img.dataset.msdmOriginalStyle) {
24260            img.dataset.msdmOriginalStyle = img.getAttribute('style') || '';
24261        }
24262
24263        host.classList.add(hostClass, mediaHostClass);
24264        host.style.width = '100%';
24265        host.style.height = 'auto';
24266        host.style.removeProperty('aspect-ratio');
24267        host.style.setProperty('--msdm-smart-photo-padding-y', '16px');
24268
24269        const background = getBackgroundNode(host);
24270        background.style.backgroundImage = 'url("' + img.currentSrc + '")';
24271
24272        img.classList.add(imageClass);
24273        img.style.margin = '0 auto';
24274        img.style.width = 'auto';
24275        img.style.height = 'auto';
24276        img.style.maxWidth = '100%';
24277        img.style.maxHeight = 'calc(100% - 32px)';
24278        img.style.aspectRatio = 'auto';
24279        img.style.objectFit = 'contain';
24280    }
24281
24282    function resetThemeDayImage(img) {
24283        const host = img.closest('.theme-day__image');
24284        if (!host) {
24285            return;
24286        }
24287
24288        host.classList.remove(hostClass, mediaHostClass);
24289        host.style.removeProperty('width');
24290        host.style.removeProperty('height');
24291        host.style.removeProperty('--msdm-smart-photo-padding-y');
24292        img.classList.remove(imageClass);
24293        img.style.cssText = img.dataset.msdmOriginalStyle || '';
24294
24295        const background = host.querySelector('.' + backgroundClass);
24296        if (background) {
24297            background.remove();
24298        }
24299    }
24300
24301    function processBrotherImage(img) {
24302        if (!(img instanceof HTMLImageElement)) {
24303            return;
24304        }
24305
24306        if (img.complete) {
24307            applyBrotherImage(img);
24308        } else {
24309            img.addEventListener('load', () => applyBrotherImage(img), {once: true});
24310        }
24311    }
24312
24313    function processMediaImage(img) {
24314        if (!(img instanceof HTMLImageElement)) {
24315            return;
24316        }
24317
24318        observeImageChanges(img, processMediaImage);
24319
24320        if (img.complete) {
24321            applyMediaImage(img);
24322        } else {
24323            img.addEventListener('load', () => applyMediaImage(img), {once: true});
24324        }
24325    }
24326
24327    function processHomeNewsImage(img) {
24328        if (!(img instanceof HTMLImageElement)) {
24329            return;
24330        }
24331
24332        observeImageChanges(img, processHomeNewsImage);
24333        observeImageSize(img, processHomeNewsImage);
24334
24335        if (img.complete) {
24336            applyHomeNewsImage(img);
24337        } else {
24338            img.addEventListener('load', () => applyHomeNewsImage(img), {once: true});
24339        }
24340    }
24341
24342    function processThemeDayImage(img) {
24343        if (!(img instanceof HTMLImageElement)) {
24344            return;
24345        }
24346
24347        observeImageChanges(img, processThemeDayImage);
24348        observeImageSize(img, processThemeDayImage);
24349
24350        if (img.complete) {
24351            applyThemeDayImage(img);
24352        } else {
24353            img.addEventListener('load', () => applyThemeDayImage(img), {once: true});
24354        }
24355    }
24356
24357    function observeImageChanges(img, handler) {
24358        if (img.getAttribute(observedAttribute) === 'true') {
24359            return;
24360        }
24361
24362        const observer = new MutationObserver((mutations) => {
24363            for (const mutation of mutations) {
24364                if (mutation.type === 'attributes') {
24365                    handler(img);
24366                    break;
24367                }
24368            }
24369        });
24370
24371        observer.observe(img, {
24372            attributes: true,
24373            attributeFilter: ['src', 'srcset', 'sizes'],
24374        });
24375
24376        img.setAttribute(observedAttribute, 'true');
24377    }
24378
24379    function observeImageSize(img, handler) {
24380        if (typeof ResizeObserver !== 'function'
24381            || img.getAttribute(sizeObservedAttribute) === 'true') {
24382            return;
24383        }
24384
24385        const host = img.closest('.news .news-item__right, .theme-day__image');
24386        if (!host) {
24387            return;
24388        }
24389
24390        const observer = new ResizeObserver(() => {
24391            requestAnimationFrame(() => handler(img));
24392        });
24393
24394        observer.observe(host);
24395        img.setAttribute(sizeObservedAttribute, 'true');
24396    }
24397
24398    function init() {
24399        document.querySelectorAll(brotherSelector).forEach(processBrotherImage);
24400        document.querySelectorAll(mediaSelector).forEach(processMediaImage);
24401        document.querySelectorAll(homeNewsSelector).forEach(processHomeNewsImage);
24402        document.querySelectorAll(themeDaySelector).forEach(processThemeDayImage);
24403    }
24404
24405    function scheduleInit() {
24406        if (initScheduled) {
24407            return;
24408        }
24409
24410        initScheduled = true;
24411        requestAnimationFrame(() => {
24412            initScheduled = false;
24413            init();
24414        });
24415    }
24416
24417    function hasRelevantNode(nodes) {
24418        return Array.from(nodes).some((node) => {
24419            if (!(node instanceof Element)) {
24420                return false;
24421            }
24422
24423            return node.matches(homeNewsSelector)
24424                || node.matches(themeDaySelector)
24425                || Boolean(node.querySelector(homeNewsSelector))
24426                || Boolean(node.querySelector(themeDaySelector));
24427        });
24428    }
24429
24430    function scheduleMediaRefresh(img) {
24431        if (!(img instanceof HTMLImageElement)) {
24432            return;
24433        }
24434
24435        const refresh = () => processMediaImage(img);
24436        requestAnimationFrame(refresh);
24437        window.setTimeout(refresh, 0);
24438        window.setTimeout(refresh, 80);
24439        window.setTimeout(refresh, 180);
24440    }
24441
24442    window.msdmRefreshSmartPhoto = (target) => {
24443        if (target instanceof HTMLImageElement && target.matches(mediaSelector)) {
24444            scheduleMediaRefresh(target);
24445            return;
24446        }
24447
24448        init();
24449    };
24450
24451    document.addEventListener('DOMContentLoaded', () => {
24452        init();
24453
24454        const observer = new MutationObserver((mutations) => {
24455            if (mutations.some((mutation) => hasRelevantNode(mutation.addedNodes))) {
24456                scheduleInit();
24457            }
24458        });
24459
24460        observer.observe(document.body, {
24461            childList: true,
24462            subtree: true,
24463        });
24464    });
24465    window.addEventListener('resize', scheduleInit);
24466
24467    if (window.BX && BX.addCustomEvent) {
24468        BX.addCustomEvent('onAjaxSuccess', scheduleInit);
24469        BX.addCustomEvent('onFrameDataReceived', scheduleInit);
24470    }
24471})();
24472
24473/* End */
24474;
24475; /* Start:"a:4:{s:4:"full";s:73:"/local/components/msdm/search/templates/.default/script.js?17750242473680";s:6:"source";s:58:"/local/components/msdm/search/templates/.default/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
24476(function () {
24477    function debounce(fn, ms) {
24478        let t = null;
24479        return function (...args) {
24480            clearTimeout(t);
24481            t = setTimeout(() => fn.apply(this, args), ms);
24482        };
24483    }
24484
24485    function qs(root, sel) { return root.querySelector(sel); }
24486
24487    function show(el) { if (el) el.style.display = ''; }
24488    function hide(el) { if (el) el.style.display = 'none'; }
24489
24490    async function request(ajaxUrl, query, signal) {
24491        const url = new URL(ajaxUrl, window.location.origin);
24492        url.searchParams.set('q', query);
24493
24494        const res = await fetch(url.toString(), {
24495            method: 'GET',
24496            credentials: 'same-origin',
24497            headers: { 'X-Requested-With': 'XMLHttpRequest' },
24498            signal
24499        });
24500
24501        if (!res.ok) throw new Error('HTTP ' + res.status);
24502        return res.json();
24503    }
24504
24505    document.addEventListener('DOMContentLoaded', () => {
24506        const root = document.querySelector('[data-search-root]');
24507        if (!root) return;
24508
24509        const ajaxUrl = root.getAttribute('data-ajax') || '';
24510        if (!ajaxUrl) return;
24511
24512        const input   = qs(root, '[data-search-input]');
24513        const example = qs(root, '[data-search-example]');
24514        const err     = qs(root, '[data-search-error]');
24515        const wrap    = qs(root, '[data-search-wrap]');
24516        const itemsEl = qs(root, '[data-search-items]');
24517        const closeBtn = qs(root, '[data-search-close]');
24518
24519        let controller = null;
24520
24521        function resetToExample() {
24522            hide(err);
24523            hide(wrap);
24524            show(example);
24525            if (itemsEl) itemsEl.innerHTML = '';
24526            root.classList.remove('error');
24527        }
24528
24529        function showResults(html) {
24530            hide(example);
24531            hide(err);
24532            show(wrap);
24533            console.log(html)
24534            if (itemsEl) itemsEl.innerHTML = html || '';
24535            root.classList.remove('error');
24536        }
24537
24538        function showError() {
24539            hide(example);
24540            hide(wrap);
24541            show(err);
24542            root.classList.add('error');
24543            if (itemsEl) itemsEl.innerHTML = '';
24544        }
24545
24546        const run = debounce(async () => {
24547            const q = (input ? (input.value || '').trim() : '');
24548
24549            if (q.length < 2) {
24550                if (controller) controller.abort();
24551                resetToExample();
24552                return;
24553            }
24554
24555            try {
24556                if (controller) controller.abort();
24557                controller = new AbortController();
24558
24559                const data = await request(ajaxUrl, q, controller.signal);
24560                const html = (data && data.html) ? data.html : '';
24561
24562                if (html && html.trim()) {
24563                    showResults(html);
24564                } else {
24565                    showError();
24566                }
24567            } catch (e) {
24568                if (e && e.name === 'AbortError') return;
24569                showError();
24570            }
24571        }, 250);
24572
24573        resetToExample();
24574
24575        if (input) {
24576            input.addEventListener('input', run);
24577            input.addEventListener('focus', () => {
24578                const q = (input.value || '').trim();
24579                if (q.length < 2) resetToExample();
24580            });
24581        }
24582
24583        if (closeBtn) {
24584            closeBtn.addEventListener('click', () => {
24585                // как именно закрывать — зависит от твоей логики/оверлея
24586                // минимум: чистим и скрываем результаты
24587                if (input) input.value = '';
24588                resetToExample();
24589            });
24590        }
24591    });
24592})();
24593/* End */
24594;; /* /local/templates/msdm/assets/main-DLCqwHNN.js?1790751964964957*/
24595; /* /local/templates/msdm/assets/smart-photo.js?179006674614901*/
24596; /* /local/components/msdm/search/templates/.default/script.js?17750242473680*/

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.