1var SpinFunctions; 2/******/ (() => { // webpackBootstrap 3/******/ var __webpack_modules__ = ({ 4 5/***/ 58: 6/***/ (() => { 7 8/** 9 * Closest 10 */ 11if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; 12if (!Element.prototype.closest) Element.prototype.closest = function (s) { 13 var el = this; 14 if (!document.documentElement.contains(el)) return null; 15 do { 16 if (el.matches(s)) return el; 17 el = el.parentElement || el.parentNode; 18 } while (el !== null && el.nodeType == 1); 19 return null; 20}; 21 22/***/ }), 23 24/***/ 127: 25/***/ (() => { 26 27/** 28 * Copyright 2016 Google Inc. All Rights Reserved. 29 * 30 * Licensed under the W3C SOFTWARE AND DOCUMENT NOTICE AND LICENSE. 31 * 32 * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document 33 * 34 */ 35(function() { 36'use strict'; 37 38// Exit early if we're not running in a browser. 39if (typeof window !== 'object') { 40 return; 41} 42 43// Exit early if all IntersectionObserver and IntersectionObserverEntry 44// features are natively supported. 45if ('IntersectionObserver' in window && 46 'IntersectionObserverEntry' in window && 47 'intersectionRatio' in window.IntersectionObserverEntry.prototype) { 48 49 // Minimal polyfill for Edge 15's lack of `isIntersecting` 50 // See: https://github.com/w3c/IntersectionObserver/issues/211 51 if (!('isIntersecting' in window.IntersectionObserverEntry.prototype)) { 52 Object.defineProperty(window.IntersectionObserverEntry.prototype, 53 'isIntersecting', { 54 get: function () { 55 return this.intersectionRatio > 0; 56 } 57 }); 58 } 59 return; 60} 61 62 63/** 64 * A local reference to the document. 65 */ 66var document = window.document; 67 68 69/** 70 * An IntersectionObserver registry. This registry exists to hold a strong 71 * reference to IntersectionObserver instances currently observing a target 72 * element. Without this registry, instances without another reference may be 73 * garbage collected. 74 */ 75var registry = []; 76 77 78/** 79 * Creates the global IntersectionObserverEntry constructor. 80 * https://w3c.github.io/IntersectionObserver/#intersection-observer-entry 81 * @param {Object} entry A dictionary of instance properties. 82 * @constructor 83 */ 84function IntersectionObserverEntry(entry) { 85 this.time = entry.time; 86 this.target = entry.target; 87 this.rootBounds = entry.rootBounds; 88 this.boundingClientRect = entry.boundingClientRect; 89 this.intersectionRect = entry.intersectionRect || getEmptyRect(); 90 this.isIntersecting = !!entry.intersectionRect; 91 92 // Calculates the intersection ratio. 93 var targetRect = this.boundingClientRect; 94 var targetArea = targetRect.width * targetRect.height; 95 var intersectionRect = this.intersectionRect; 96 var intersectionArea = intersectionRect.width * intersectionRect.height; 97 98 // Sets intersection ratio. 99 if (targetArea) { 100 // Round the intersection ratio to avoid floating point math issues: 101 // https://github.com/w3c/IntersectionObserver/issues/324 102 this.intersectionRatio = Number((intersectionArea / targetArea).toFixed(4)); 103 } else { 104 // If area is zero and is intersecting, sets to 1, otherwise to 0 105 this.intersectionRatio = this.isIntersecting ? 1 : 0; 106 } 107} 108 109 110/** 111 * Creates the global IntersectionObserver constructor. 112 * https://w3c.github.io/IntersectionObserver/#intersection-observer-interface 113 * @param {Function} callback The function to be invoked after intersection 114 * changes have queued. The function is not invoked if the queue has 115 * been emptied by calling the `takeRecords` method. 116 * @param {Object=} opt_options Optional configuration options. 117 * @constructor 118 */ 119function IntersectionObserver(callback, opt_options) { 120 121 var options = opt_options || {}; 122 123 if (typeof callback != 'function') { 124 throw new Error('callback must be a function'); 125 } 126 127 if (options.root && options.root.nodeType != 1) { 128 throw new Error('root must be an Element'); 129 } 130 131 // Binds and throttles `this._checkForIntersections`. 132 this._checkForIntersections = throttle( 133 this._checkForIntersections.bind(this), this.THROTTLE_TIMEOUT); 134 135 // Private properties. 136 this._callback = callback; 137 this._observationTargets = []; 138 this._queuedEntries = []; 139 this._rootMarginValues = this._parseRootMargin(options.rootMargin); 140 141 // Public properties. 142 this.thresholds = this._initThresholds(options.threshold); 143 this.root = options.root || null; 144 this.rootMargin = this._rootMarginValues.map(function(margin) { 145 return margin.value + margin.unit; 146 }).join(' '); 147} 148 149 150/** 151 * The minimum interval within which the document will be checked for 152 * intersection changes. 153 */ 154IntersectionObserver.prototype.THROTTLE_TIMEOUT = 100; 155 156 157/** 158 * The frequency in which the polyfill polls for intersection changes. 159 * this can be updated on a per instance basis and must be set prior to 160 * calling `observe` on the first target. 161 */ 162IntersectionObserver.prototype.POLL_INTERVAL = null; 163 164/** 165 * Use a mutation observer on the root element 166 * to detect intersection changes. 167 */ 168IntersectionObserver.prototype.USE_MUTATION_OBSERVER = true; 169 170 171/** 172 * Starts observing a target element for intersection changes based on 173 * the thresholds values. 174 * @param {Element} target The DOM element to observe. 175 */ 176IntersectionObserver.prototype.observe = function(target) { 177 var isTargetAlreadyObserved = this._observationTargets.some(function(item) { 178 return item.element == target; 179 }); 180 181 if (isTargetAlreadyObserved) { 182 return; 183 } 184
vendor: 2,303 bytes, lines 185-260
185 if (!(target && target.nodeType == 1)) { 186 throw new Error('target must be an Element'); 187 } 188 189 this._registerInstance(); 190 this._observationTargets.push({element: target, entry: null}); 191 this._monitorIntersections(); 192 this._checkForIntersections(); 193}; 194 195 196/** 197 * Stops observing a target element for intersection changes. 198 * @param {Element} target The DOM element to observe. 199 */ 200IntersectionObserver.prototype.unobserve = function(target) { 201 this._observationTargets = 202 this._observationTargets.filter(function(item) { 203 204 return item.element != target; 205 }); 206 if (!this._observationTargets.length) { 207 this._unmonitorIntersections(); 208 this._unregisterInstance(); 209 } 210}; 211 212 213/** 214 * Stops observing all target elements for intersection changes. 215 */ 216IntersectionObserver.prototype.disconnect = function() { 217 this._observationTargets = []; 218 this._unmonitorIntersections(); 219 this._unregisterInstance(); 220}; 221 222 223/** 224 * Returns any queue entries that have not yet been reported to the 225 * callback and clears the queue. This can be used in conjunction with the 226 * callback to obtain the absolute most up-to-date intersection information. 227 * @return {Array} The currently queued entries. 228 */ 229IntersectionObserver.prototype.takeRecords = function() { 230 var records = this._queuedEntries.slice(); 231 this._queuedEntries = []; 232 return records; 233}; 234 235 236/** 237 * Accepts the threshold value from the user configuration object and 238 * returns a sorted array of unique threshold values. If a value is not 239 * between 0 and 1 and error is thrown. 240 * @private 241 * @param {Array|number=} opt_threshold An optional threshold value or 242 * a list of threshold values, defaulting to [0]. 243 * @return {Array} A sorted list of unique and valid threshold values. 244 */ 245IntersectionObserver.prototype._initThresholds = function(opt_threshold) { 246 var threshold = opt_threshold || [0]; 247 if (!Array.isArray(threshold)) threshold = [threshold]; 248 249 return threshold.sort().filter(function(t, i, a) { 250 if (typeof t != 'number' || isNaN(t) || t < 0 || t > 1) { 251 throw new Error('threshold must be a number between 0 and 1 inclusively'); 252 } 253 return t !== a[i - 1]; 254 }); 255}; 256 257 258/** 259 * Accepts the rootMargin value from the user configuration object 260 * and returns an array of the four margin values as an object c
260ontaining 261 * the value and unit properties. If any of the values are not properly 262 * formatted or use a unit other than px or %, and error is thrown. 263 * @private 264 * @param {string=} opt_rootMargin An optional rootMargin value, 265 * defaulting to '0px'. 266 * @return {Array<Object>} An array of margin objects with the keys 267 * value and unit. 268 */ 269IntersectionObserver.prototype._parseRootMargin = function(opt_rootMargin) { 270 var marginString = opt_rootMargin || '0px'; 271 var margins = marginString.split(/\s+/).map(function(margin) { 272 var parts = /^(-?\d*\.?\d+)(px|%)$/.exec(margin); 273 if (!parts) { 274 throw new Error('rootMargin must be specified in pixels or percent'); 275 } 276 return {value: parseFloat(parts[1]), unit: parts[2]}; 277 }); 278 279 // Handles shorthand. 280 margins[1] = margins[1] || margins[0]; 281 margins[2] = margins[2] || margins[0]; 282 margins[3] = margins[3] || margins[1]; 283 284 return margins; 285}; 286 287 288/** 289 * Starts polling for intersection changes if the polling is not already 290 * happening, and if the page's visibility state is visible. 291 * @private 292 */ 293IntersectionObserver.prototype._monitorIntersections = function() { 294 if (!this._monitoringIntersections) { 295 this._monitoringIntersections = true; 296 297 // If a poll interval is set, use polling instead of listening to 298 // resize and scroll events or DOM mutations. 299 if (this.POLL_INTERVAL) { 300 this._monitoringInterval = setInterval( 301 this._checkForIntersections, this.POLL_INTERVAL); 302 } 303 else { 304 addEvent(window, 'resize', this._checkForIntersections, true); 305 addEvent(document, 'scroll', this._checkForIntersections, true); 306 307 if (this.USE_MUTATION_OBSERVER && 'MutationObserver' in window) { 308 this._domObserver = new MutationObserver(this._checkForIntersections); 309 this._domObserver.observe(document, { 310 attributes: true, 311 childList: true, 312 characterData: true, 313 subtree: true 314 }); 315 } 316 } 317 } 318}; 319 320 321/** 322 * Stops polling for intersection changes. 323 * @private 324 */ 325IntersectionObserver.prototype._unmonitorIntersections = function() { 326 if (this._monitoringIntersections) { 327 this._monitoringIntersections = false; 328 329 clearInterval(this._monitoringInterval); 330 this._monitoringInterval = null; 331 332 removeEvent(window, 'resize', this._checkForIntersections, true); 333 removeEvent(document, 'scroll', this._checkForIntersections, true); 334 335 if (this._domObserver) { 336 this._domObserver.disconnect(); 337 this._domObserver = null; 338 } 339 } 340}; 341 342 343/** 344 * Scans each observation target for intersection changes and adds them 345 * to the internal entries queue. If new entries are found, it 346 * schedules the callback to be invoked. 347 * @private 348 */ 349IntersectionObserver.prototype._checkForIntersections = function() { 350 var rootIsInDom = this._rootIsInDom(); 351 var rootRect = rootIsInDom ? this._getRootRect() : getEmptyRect(); 352 353 this._observationTargets.forEach(function(item) { 354 var target = item.element; 355 var targetRect = getBoundingClientRect(target); 356 var rootContainsTarget = this._rootContainsTarget(target); 357 var oldEntry = item.entry; 358 var intersectionRect = rootIsInDom && rootContainsTarget && 359 this._computeTargetAndRootIntersection(target, rootRect); 360 361 var newEntry = item.entry = new IntersectionObserverEntry({ 362 time: now(), 363 target: target, 364 boundingClientRect: targetRect, 365 rootBounds: rootRect, 366 intersectionRect: intersectionRect 367 }); 368 369 if (!oldEntry) { 370 this._queuedEntries.push(newEntry); 371 } else if (rootIsInDom && rootContainsTarget) { 372 // If the new entry intersection ratio has crossed any of the 373 // thresholds, add a new entry. 374 if (this._hasCrossedThreshold(oldEntry, newEntry)) { 375 this._queuedEntries.push(newEntry); 376 } 377 } else { 378 // If the root is not in the DOM or target is not contained within 379 // root but the previous entry for this target had an intersection, 380 // add a new record indicating removal. 381 if (oldEntry && oldEntry.isIntersecting) { 382 this._queuedEntries.push(newEntry); 383 } 384 } 385 }, this); 386 387 if (this._queuedEntries.length) { 388 this._callback(this.takeRecords(), this); 389 } 390}; 391 392 393/** 394 * Accepts a target and root rect computes the intersection between then 395 * following the algorithm in the spec. 396 * TODO(philipwalton): at this time clip-path is not considered. 397 * https://w3c.github.io/IntersectionObserver/#calculate-intersection-rect-algo 398 * @param {Element} target The target DOM element 399 * @param {Object} rootRect The bounding rect of the root after being 400 * expanded by the rootMargin value. 401 * @return {?Object} The final intersection rect object or undefined if no 402 * intersection is found. 403 * @private 404 */ 405IntersectionObserver.prototype._computeTargetAndRootIntersection = 406 function(target, rootRect) { 407 408 // If the element isn't displayed, an intersection can't happen. 409 if (window.getComputedStyle(target).display == 'none') return; 410 411 var targetRect = getBoundingClientRect(target); 412 var intersectionRect = targetRect; 413 var parent = getParentNode(target); 414 var atRoot = false;
vendor: 8,268 bytes, lines 415-685
415 416 while (!atRoot) { 417 var parentRect = null; 418 var parentComputedStyle = parent.nodeType == 1 ? 419 window.getComputedStyle(parent) : {}; 420 421 // If the parent isn't displayed, an intersection can't happen. 422 if (parentComputedStyle.display == 'none') return; 423 424 if (parent == this.root || parent == document) { 425 atRoot = true; 426 parentRect = rootRect; 427 } else { 428 // If the element has a non-visible overflow, and it's not the <body> 429 // or <html> element, update the intersection rect. 430 // Note: <body> and <html> cannot be clipped to a rect that's not also 431 // the document rect, so no need to compute a new intersection. 432 if (parent != document.body && 433 parent != document.documentElement && 434 parentComputedStyle.overflow != 'visible') { 435 parentRect = getBoundingClientRect(parent); 436 } 437 } 438 439 // If either of the above conditionals set a new parentRect, 440 // calculate new intersection data. 441 if (parentRect) { 442 intersectionRect = computeRectIntersection(parentRect, intersectionRect); 443 444 if (!intersectionRect) break; 445 } 446 parent = getParentNode(parent); 447 } 448 return intersectionRect; 449}; 450 451 452/** 453 * Returns the root rect after being expanded by the rootMargin value. 454 * @return {Object} The expanded root rect. 455 * @private 456 */ 457IntersectionObserver.prototype._getRootRect = function() { 458 var rootRect; 459 if (this.root) { 460 rootRect = getBoundingClientRect(this.root); 461 } else { 462 // Use <html>/<body> instead of window since scroll bars affect size. 463 var html = document.documentElement; 464 var body = document.body; 465 rootRect = { 466 top: 0, 467 left: 0, 468 right: html.clientWidth || body.clientWidth, 469 width: html.clientWidth || body.clientWidth, 470 bottom: html.clientHeight || body.clientHeight, 471 height: html.clientHeight || body.clientHeight 472 }; 473 } 474 return this._expandRectByRootMargin(rootRect); 475}; 476 477 478/** 479 * Accepts a rect and expands it by the rootMargin value. 480 * @param {Object} rect The rect object to expand. 481 * @return {Object} The expanded rect. 482 * @private 483 */ 484IntersectionObserver.prototype._expandRectByRootMargin = function(rect) { 485 var margins = this._rootMarginValues.map(function(margin, i) { 486 return margin.unit == 'px' ? margin.value : 487 margin.value * (i % 2 ? rect.width : rect.height) / 100; 488 }); 489 var newRect = { 490 top: rect.top - margins[0], 491 right: rect.right + margins[1], 492 bottom: rect.bottom + margins[2], 493 left: rect.left - margins[3] 494 }; 495 newRect.width = newRect.right - newRect.left; 496 newRect.height = newRect.bottom - newRect.top; 497 498 return newRect; 499}; 500 501 502/** 503 * Accepts an old and new entry and returns true if at least one of the 504 * threshold values has been crossed. 505 * @param {?IntersectionObserverEntry} oldEntry The previous entry for a 506 * particular target element or null if no previous entry exists. 507 * @param {IntersectionObserverEntry} newEntry The current entry for a 508 * particular target element. 509 * @return {boolean} Returns true if a any threshold has been crossed. 510 * @private 511 */ 512IntersectionObserver.prototype._hasCrossedThreshold = 513 function(oldEntry, newEntry) { 514 515 // To make comparing easier, an entry that has a ratio of 0 516 // but does not actually intersect is given a value of -1 517 var oldRatio = oldEntry && oldEntry.isIntersecting ? 518 oldEntry.intersectionRatio || 0 : -1; 519 var newRatio = newEntry.isIntersecting ? 520 newEntry.intersectionRatio || 0 : -1; 521 522 // Ignore unchanged ratios 523 if (oldRatio === newRatio) return; 524 525 for (var i = 0; i < this.thresholds.length; i++) { 526 var threshold = this.thresholds[i]; 527 528 // Return true if an entry matches a threshold or if the new ratio 529 // and the old ratio are on the opposite sides of a threshold. 530 if (threshold == oldRatio || threshold == newRatio || 531 threshold < oldRatio !== threshold < newRatio) { 532 return true; 533 } 534 } 535}; 536 537 538/** 539 * Returns whether or not the root element is an element and is in the DOM. 540 * @return {boolean} True if the root element is an element and is in the DOM. 541 * @private 542 */ 543IntersectionObserver.prototype._rootIsInDom = function() { 544 return !this.root || containsDeep(document, this.root); 545}; 546 547 548/** 549 * Returns whether or not the target element is a child of root. 550 * @param {Element} target The target element to check. 551 * @return {boolean} True if the target element is a child of root. 552 * @private 553 */ 554IntersectionObserver.prototype._rootContainsTarget = function(target) { 555 return containsDeep(this.root || document, target); 556}; 557 558 559/** 560 * Adds the instance to the global IntersectionObserver registry if it isn't 561 * already present. 562 * @private 563 */ 564IntersectionObserver.prototype._registerInstance = function() { 565 if (registry.indexOf(this) < 0) { 566 registry.push(this); 567 } 568}; 569 570 571/** 572 * Removes the instance from the global IntersectionObserver registry. 573 * @private 574 */ 575IntersectionObserver.prototype._unregisterInstance = function() { 576 var index = registry.indexOf(this); 577 if (index != -1) registry.splice(index, 1); 578}; 579 580 581/** 582 * Returns the result of the performance.now() method or null in browsers 583 * that don't support the API. 584 * @return {number} The elapsed time since the page was requested. 585 */ 586function now() { 587 return window.performance && performance.now && performance.now(); 588} 589 590 591/** 592 * Throttles a function and delays its execution, so it's only called at most 593 * once within a given time period. 594 * @param {Function} fn The function to throttle. 595 * @param {number} timeout The amount of time that must pass before the 596 * function can be called again. 597 * @return {Function} The throttled function. 598 */ 599function throttle(fn, timeout) { 600 var timer = null; 601 return function () { 602 if (!timer) { 603 timer = setTimeout(function() { 604 fn(); 605 timer = null; 606 }, timeout); 607 } 608 }; 609} 610 611 612/** 613 * Adds an event handler to a DOM node ensuring cross-browser compatibility. 614 * @param {Node} node The DOM node to add the event handler to. 615 * @param {string} event The event name. 616 * @param {Function} fn The event handler to add. 617 * @param {boolean} opt_useCapture Optionally adds the even to the capture 618 * phase. Note: this only works in modern browsers. 619 */ 620function addEvent(node, event, fn, opt_useCapture) { 621 if (typeof node.addEventListener == 'function') { 622 node.addEventListener(event, fn, opt_useCapture || false); 623 } 624 else if (typeof node.attachEvent == 'function') { 625 node.attachEvent('on' + event, fn); 626 } 627} 628 629 630/** 631 * Removes a previously added event handler from a DOM node. 632 * @param {Node} node The DOM node to remove the event handler from. 633 * @param {string} event The event name. 634 * @param {Function} fn The event handler to remove. 635 * @param {boolean} opt_useCapture If the event handler was added with this 636 * flag set to true, it should be set to true here in order to remove it. 637 */ 638function removeEvent(node, event, fn, opt_useCapture) { 639 if (typeof node.removeEventListener == 'function') { 640 node.removeEventListener(event, fn, opt_useCapture || false); 641 } 642 else if (typeof node.detatchEvent == 'function') { 643 node.detatchEvent('on' + event, fn); 644 } 645} 646 647 648/** 649 * Returns the intersection between two rect objects. 650 * @param {Object} rect1 The first rect. 651 * @param {Object} rect2 The second rect. 652 * @return {?Object} The intersection rect or undefined if no intersection 653 * is found. 654 */ 655function computeRectIntersection(rect1, rect2) { 656 var top = Math.max(rect1.top, rect2.top); 657 var bottom = Math.min(rect1.bottom, rect2.bottom); 658 var left = Math.max(rect1.left, rect2.left); 659 var right = Math.min(rect1.right, rect2.right); 660 var width = right - left; 661 var height = bottom - top; 662 663 return (width >= 0 && height >= 0) && { 664 top: top, 665 bottom: bottom, 666 left: left, 667 right: right, 668 width: width, 669 height: height 670 }; 671} 672 673 674/** 675 * Shims the native getBoundingClientRect for compatibility with older IE. 676 * @param {Element} el The element whose bounding rect to get. 677 * @return {Object} The (possibly shimmed) rect of the element. 678 */ 679function getBoundingClientRect(el) { 680 var rect; 681 682 try { 683 rect = el.getBoundingClientRect(); 684 } catch (err) { 685 // Ignore Windows 7 IE11 "Unspecified error"
686 // https://github.com/w3c/IntersectionObserver/pull/205 687 } 688 689 if (!rect) return getEmptyRect(); 690 691 // Older IE 692 if (!(rect.width && rect.height)) { 693 rect = { 694 top: rect.top, 695 right: rect.right, 696 bottom: rect.bottom, 697 left: rect.left, 698 width: rect.right - rect.left, 699 height: rect.bottom - rect.top 700 }; 701 } 702 return rect; 703} 704 705 706/** 707 * Returns an empty rect object. An empty rect is returned when an element 708 * is not in the DOM. 709 * @return {Object} The empty rect. 710 */ 711function getEmptyRect() { 712 return { 713 top: 0, 714 bottom: 0, 715 left: 0, 716 right: 0, 717 width: 0, 718 height: 0 719 }; 720} 721 722/** 723 * Checks to see if a parent element contains a child element (including inside 724 * shadow DOM). 725 * @param {Node} parent The parent element. 726 * @param {Node} child The child element. 727 * @return {boolean} True if the parent node contains the child node. 728 */ 729function containsDeep(parent, child) { 730 var node = child; 731 while (node) { 732 if (node == parent) return true; 733 734 node = getParentNode(node); 735 } 736 return false; 737} 738 739 740/** 741 * Gets the parent node of an element or its host element if the parent node 742 * is a shadow root. 743 * @param {Node} node The node whose parent to get. 744 * @return {Node|null} The parent node or null if no parent exists. 745 */ 746function getParentNode(node) { 747 var parent = node.parentNode; 748 749 if (parent && parent.nodeType == 11 && parent.host) { 750 // If the parent is a shadow root, return the host element. 751 return parent.host; 752 } 753 754 if (parent && parent.assignedSlot) { 755 // If the parent is distributed in a <slot>, return the parent of a slot. 756 return parent.assignedSlot.parentNode; 757 } 758 759 return parent; 760} 761 762 763// Exposes the constructors globally. 764window.IntersectionObserver = IntersectionObserver; 765window.IntersectionObserverEntry = IntersectionObserverEntry; 766 767}()); 768 769 770/***/ }), 771 772/***/ 360: 773/***/ (() => { 774 775/* 776CSS Browser Selector js v0.5.3 (July 2, 2013) 777 778-- original -- 779Rafael Lima (http://rafael.adm.br) 780http://rafael.adm.br/css_browser_selector 781License: http://creativecommons.org/licenses/by/2.5/ 782Contributors: http://rafael.adm.br/css_browser_selector#contributors 783-- /original -- 784 785Fork project: http://code.google.com/p/css-browser-selector/ 786Song Hyo-Jin (shj at xenosi.de) 787*/ 788function css_browser_selector(n) { 789 var b = n.toLowerCase(), 790 f = function (c) { 791 return b.indexOf(c) > -1; 792 }, 793 h = "gecko", 794 k = "webkit", 795 p = "safari", 796 j = "chrome", 797 d = "opera", 798 e = "mobile", 799 l = 0, 800 a = window.devicePixelRatio ? (window.devicePixelRatio + "").replace(".", "_") : "1", 801 re = ''; 802 var i = [!/opera|webtv/.test(b) && /msie\s(\d+)/.test(b) && (l = RegExp.$1 * 1) ? "ie ie" + l + (l == 6 || l == 7 ? " ie67 ie678 ie6789" : l == 8 ? " ie678 ie6789" : l == 9 ? " ie6789 ie9m" : l > 9 ? " ie9m" : "") : /firefox\/(\d+)\.(\d+)/.test(b) && (re = RegExp) ? h + " ff ff" + re.$1 + " ff" + re.$1 + "_" + re.$2 : f("gecko/") ? h : f(d) ? d + (/version\/(\d+)/.test(b) ? " " + d + RegExp.$1 : /opera(\s|\/)(\d+)/.test(b) ? " " + d + RegExp.$2 : "") : f("konqueror") ? "konqueror" : f("blackberry") ? e + " blackberry" : f(j) || f("crios") ? k + " " + j : f("iron") ? k + " iron" : !f("cpu os") && f("applewebkit/") ? k + " " + p : f("mozilla/") ? h : "", f("android") ? e + " android" : "", f("tablet") ? "tablet" : "", f("j2me") ? e + " j2me" : f("ipad; u; cpu os") ? e + " chrome android tablet" : f("ipad;u;cpu os") ? e + " chromedef android tablet" : f("iphone") ? e + " ios iphone" : f("ipod") ? e + " ios ipod" : f("ipad") ? e + " ios ipad tablet" : f("mac") ? "mac" : f("darwin") ? "mac" : f("webtv") ? "webtv" : f("win") ? "win" + (f("windows nt 6.0") ? " vista" : "") : f("freebsd") ? "freebsd" : f("x11") || f("linux") ? "linux" : "", a != "1" ? " retina ratio" + a : "", "js portrait"].join(" "); 803 if (window.jQuery && !window.jQuery.browser) { 804 window.jQuery.browser = l ? { 805 msie: 1, 806 version: l 807 } : {}; 808 } 809 return i; 810} 811(function (j, b) { 812 var c = css_browser_selector(navigator.userAgent); 813 var g = j.documentElement; 814 g.className += " " + c; 815 var a = c.replace(/^\s*|\s*$/g, "").split(/ +/); 816 b.CSSBS = 1; 817 for (var f = 0; f < a.length; f++) { 818 b["CSSBS_" + a[f]] = 1; 819 } 820 var e = function (d) { 821 return j.documentElement[d] || j.body[d]; 822 }; 823 if (b.jQuery) { 824 (function (q) { 825 var h = "portrait", 826 k = "landscape"; 827 var i = "smartnarrow", 828 u = "smartwide", 829 x = "tabletnarrow", 830 r = "tabletwide", 831 w = i + " " + u + " " + x + " " + r + " pc"; 832 var v = q(g); 833 var s = 0, 834 o = 0; 835 function d() { 836 if (s != 0) { 837 return; 838 } 839 try { 840 var l = e("clientWidth"), 841 p = e("clientHeight"); 842 if (l > p) { 843 v.removeClass(h).addClass(k); 844 } else { 845 v.removeClass(k).addClass(h); 846 } 847 if (l == o) { 848 return; 849 } 850 o = l; 851 } catch (m) {} 852 s = setTimeout(n, 100); 853 } 854 function n() { 855 try { 856 v.removeClass(w); 857 v.addClass(o <= 360 ? i : o <= 640 ? u : o <= 768 ? x : o <= 1024 ? r : "pc"); 858 } catch (l) {} 859 s = 0; 860 } 861 if (b.CSSBS_ie) { 862 setInterval(d, 1000); 863 } else { 864 q(b).on("resize orientationchange", d).trigger("resize"); 865 } 866 })(b.jQuery); 867 } 868})(document, window); 869if (navigator.userAgent.indexOf("Windows") > -1 && navigator.userAgent.indexOf("rv:11.0") > -1) { 870 $('html').addClass('ie11 ie'); 871} 872 873/***/ }), 874 875/***/ 692:
876/***/ (function(module, exports) { 877 878var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 879 * jQuery JavaScript Library v3.7.1 880 * https://jquery.com/ 881 * 882 * Copyright OpenJS Foundation and other contributors 883 * Released under the MIT license 884 * https://jquery.org/license 885 * 886 * Date: 2023-08-28T13:37Z 887 */ 888( function( global, factory ) { 889 890 "use strict"; 891 892 if ( true
vendor: 284,319 bytes, lines 892-11553
892 && typeof module.exports === "object" ) { 893 894 // For CommonJS and CommonJS-like environments where a proper `window` 895 // is present, execute the factory and get jQuery. 896 // For environments that do not have a `window` with a `document` 897 // (such as Node.js), expose a factory as module.exports. 898 // This accentuates the need for the creation of a real `window`. 899 // e.g. var jQuery = require("jquery")(window); 900 // See ticket trac-14549 for more info. 901 module.exports = global.document ? 902 factory( global, true ) : 903 function( w ) { 904 if ( !w.document ) { 905 throw new Error( "jQuery requires a window with a document" ); 906 } 907 return factory( w ); 908 }; 909 } else { 910 factory( global ); 911 } 912 913// Pass this if window is not defined yet 914} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 915 916// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 917// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 918// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common 919// enough that all such attempts are guarded in a try block. 920"use strict"; 921 922var arr = []; 923 924var getProto = Object.getPrototypeOf; 925 926var slice = arr.slice; 927 928var flat = arr.flat ? function( array ) { 929 return arr.flat.call( array ); 930} : function( array ) { 931 return arr.concat.apply( [], array ); 932}; 933 934 935var push = arr.push; 936 937var indexOf = arr.indexOf; 938 939var class2type = {}; 940 941var toString = class2type.toString; 942 943var hasOwn = class2type.hasOwnProperty; 944 945var fnToString = hasOwn.toString; 946 947var ObjectFunctionString = fnToString.call( Object ); 948 949var support = {}; 950 951var isFunction = function isFunction( obj ) { 952 953 // Support: Chrome <=57, Firefox <=52 954 // In some browsers, typeof returns "function" for HTML <object> elements 955 // (i.e., `typeof document.createElement( "object" ) === "function"`). 956 // We don't want to classify *any* DOM node as a function. 957 // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 958 // Plus for old WebKit, typeof returns "function" for HTML collections 959 // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) 960 return typeof obj === "function" && typeof obj.nodeType !== "number" && 961 typeof obj.item !== "function"; 962 }; 963 964 965var isWindow = function isWindow( obj ) { 966 return obj != null && obj === obj.window; 967 }; 968 969 970var document = window.document; 971 972 973 974 var preservedScriptAttributes = { 975 type: true, 976 src: true, 977 nonce: true, 978 noModule: true 979 }; 980 981 function DOMEval( code, node, doc ) { 982 doc = doc || document; 983 984 var i, val, 985 script = doc.createElement( "script" ); 986 987 script.text = code; 988 if ( node ) { 989 for ( i in preservedScriptAttributes ) { 990 991 // Support: Firefox 64+, Edge 18+ 992 // Some browsers don't support the "nonce" property on scripts. 993 // On the other hand, just using `getAttribute` is not enough as 994 // the `nonce` attribute is reset to an empty string whenever it 995 // becomes browsing-context connected. 996 // See https://github.com/whatwg/html/issues/2369 997 // See https://html.spec.whatwg.org/#nonce-attributes 998 // The `node.getAttribute` check was added for the sake of 999 // `jQuery.globalEval` so that it can fake a nonce-containing node 1000 // via an object. 1001 val = node[ i ] || node.getAttribute && node.getAttribute( i ); 1002 if ( val ) { 1003 script.setAttribute( i, val ); 1004 } 1005 } 1006 } 1007 doc.head.appendChild( script ).parentNode.removeChild( script ); 1008 } 1009 1010 1011function toType( obj ) { 1012 if ( obj == null ) { 1013 return obj + ""; 1014 } 1015 1016 // Support: Android <=2.3 only (functionish RegExp) 1017 return typeof obj === "object" || typeof obj === "function" ? 1018 class2type[ toString.call( obj ) ] || "object" : 1019 typeof obj; 1020} 1021/* global Symbol */ 1022// Defining this global in .eslintrc.json would create a danger of using the global 1023// unguarded in another place, it seems safer to define global only for this module 1024 1025 1026 1027var version = "3.7.1", 1028 1029 rhtmlSuffix = /HTML$/i, 1030 1031 // Define a local copy of jQuery 1032 jQuery = function( selector, context ) { 1033 1034 // The jQuery object is actually just the init constructor 'enhanced' 1035 // Need init if jQuery is called (just allow error to be thrown if not included) 1036 return new jQuery.fn.init( selector, context ); 1037 }; 1038 1039jQuery.fn = jQuery.prototype = { 1040 1041 // The current version of jQuery being used 1042 jquery: version, 1043 1044 constructor: jQuery, 1045 1046 // The default length of a jQuery object is 0 1047 length: 0, 1048 1049 toArray: function() { 1050 return slice.call( this ); 1051 }, 1052 1053 // Get the Nth element in the matched element set OR 1054 // Get the whole matched element set as a clean array 1055 get: function( num ) { 1056 1057 // Return all the elements in a clean array 1058 if ( num == null ) { 1059 return slice.call( this ); 1060 } 1061 1062 // Return just the one element from the set 1063 return num < 0 ? this[ num + this.length ] : this[ num ]; 1064 }, 1065 1066 // Take an array of elements and push it onto the stack 1067 // (returning the new matched element set) 1068 pushStack: function( elems ) { 1069 1070 // Build a new jQuery matched element set 1071 var ret = jQuery.merge( this.constructor(), elems ); 1072 1073 // Add the old object onto the stack (as a reference) 1074 ret.prevObject = this; 1075 1076 // Return the newly-formed element set 1077 return ret; 1078 }, 1079 1080 // Execute a callback for every element in the matched set. 1081 each: function( callback ) { 1082 return jQuery.each( this, callback ); 1083 }, 1084 1085 map: function( callback ) { 1086 return this.pushStack( jQuery.map( this, function( elem, i ) { 1087 return callback.call( elem, i, elem ); 1088 } ) ); 1089 }, 1090 1091 slice: function() { 1092 return this.pushStack( slice.apply( this, arguments ) ); 1093 }, 1094 1095 first: function() { 1096 return this.eq( 0 ); 1097 }, 1098 1099 last: function() { 1100 return this.eq( -1 ); 1101 }, 1102 1103 even: function() { 1104 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 1105 return ( i + 1 ) % 2; 1106 } ) ); 1107 }, 1108 1109 odd: function() { 1110 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 1111 return i % 2; 1112 } ) ); 1113 }, 1114 1115 eq: function( i ) { 1116 var len = this.length, 1117 j = +i + ( i < 0 ? len : 0 ); 1118 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 1119 }, 1120 1121 end: function() { 1122 return this.prevObject || this.constructor(); 1123 }, 1124 1125 // For internal use only. 1126 // Behaves like an Array's method, not like a jQuery method. 1127 push: push, 1128 sort: arr.sort, 1129 splice: arr.splice 1130}; 1131 1132jQuery.extend = jQuery.fn.extend = function() { 1133 var options, name, src, copy, copyIsArray, clone, 1134 target = arguments[ 0 ] || {}, 1135 i = 1, 1136 length = arguments.length, 1137 deep = false; 1138 1139 // Handle a deep copy situation 1140 if ( typeof target === "boolean" ) { 1141 deep = target; 1142 1143 // Skip the boolean and the target 1144 target = arguments[ i ] || {}; 1145 i++; 1146 } 1147 1148 // Handle case when target is a string or something (possible in deep copy) 1149 if ( typeof target !== "object" && !isFunction( target ) ) { 1150 target = {}; 1151 } 1152 1153 // Extend jQuery itself if only one argument is passed 1154 if ( i === length ) { 1155 target = this; 1156 i--; 1157 } 1158 1159 for ( ; i < length; i++ ) { 1160 1161 // Only deal with non-null/undefined values 1162 if ( ( options = arguments[ i ] ) != null ) { 1163 1164 // Extend the base object 1165 for ( name in options ) { 1166 copy = options[ name ]; 1167 1168 // Prevent Object.prototype pollution 1169 // Prevent never-ending loop 1170 if ( name === "__proto__" || target === copy ) { 1171 continue; 1172 } 1173 1174 // Recurse if we're merging plain objects or arrays 1175 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 1176 ( copyIsArray = Array.isArray( copy ) ) ) ) { 1177 src = target[ name ]; 1178 1179 // Ensure proper type for the source value 1180 if ( copyIsArray && !Array.isArray( src ) ) { 1181 clone = []; 1182 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { 1183 clone = {}; 1184 } else { 1185 clone = src; 1186 } 1187 copyIsArray = false; 1188 1189 // Never move original objects, clone them 1190 target[ name ] = jQuery.extend( deep, clone, copy ); 1191 1192 // Don't bring in undefined values 1193 } else if ( copy !== undefined ) { 1194 target[ name ] = copy; 1195 } 1196 } 1197 } 1198 } 1199 1200 // Return the modified object 1201 return target; 1202}; 1203 1204jQuery.extend( { 1205 1206 // Unique for each copy of jQuery on the page 1207 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 1208 1209 // Assume jQuery is ready without the ready module 1210 isReady: true, 1211 1212 error: function( msg ) { 1213 throw new Error( msg ); 1214 }, 1215 1216 noop: function() {}, 1217 1218 isPlainObject: function( obj ) { 1219 var proto, Ctor; 1220 1221 // Detect obvious negatives 1222 // Use toString instead of jQuery.type to catch host objects 1223 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 1224 return false; 1225 } 1226 1227 proto = getProto( obj ); 1228 1229 // Objects with no prototype (e.g., `Object.create( null )`) are plain 1230 if ( !proto ) { 1231 return true; 1232 } 1233 1234 // Objects with prototype are plain iff they were constructed by a global Object function 1235 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 1236 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 1237 }, 1238 1239 isEmptyObject: function( obj ) { 1240 var name; 1241 1242 for ( name in obj ) { 1243 return false; 1244 } 1245 return true; 1246 }, 1247 1248 // Evaluates a script in a provided context; falls back to the global one 1249 // if not specified. 1250 globalEval: function( code, options, doc ) { 1251 DOMEval( code, { nonce: options && options.nonce }, doc ); 1252 }, 1253 1254 each: function( obj, callback ) { 1255 var length, i = 0; 1256 1257 if ( isArrayLike( obj ) ) { 1258 length = obj.length; 1259 for ( ; i < length; i++ ) { 1260 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 1261 break; 1262 } 1263 } 1264 } else { 1265 for ( i in obj ) { 1266 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 1267 break; 1268 } 1269 } 1270 } 1271 1272 return obj; 1273 }, 1274 1275 1276 // Retrieve the text value of an array of DOM nodes 1277 text: function( elem ) { 1278 var node, 1279 ret = "", 1280 i = 0, 1281 nodeType = elem.nodeType; 1282 1283 if ( !nodeType ) { 1284 1285 // If no nodeType, this is expected to be an array 1286 while ( ( node = elem[ i++ ] ) ) { 1287 1288 // Do not traverse comment nodes 1289 ret += jQuery.text( node ); 1290 } 1291 } 1292 if ( nodeType === 1 || nodeType === 11 ) { 1293 return elem.textContent; 1294 } 1295 if ( nodeType === 9 ) { 1296 return elem.documentElement.textContent; 1297 } 1298 if ( nodeType === 3 || nodeType === 4 ) { 1299 return elem.nodeValue; 1300 } 1301 1302 // Do not include comment or processing instruction nodes 1303 1304 return ret; 1305 }, 1306 1307 // results is for internal usage only 1308 makeArray: function( arr, results ) { 1309 var ret = results || []; 1310 1311 if ( arr != null ) { 1312 if ( isArrayLike( Object( arr ) ) ) { 1313 jQuery.merge( ret, 1314 typeof arr === "string" ? 1315 [ arr ] : arr 1316 ); 1317 } else { 1318 push.call( ret, arr ); 1319 } 1320 } 1321 1322 return ret; 1323 }, 1324 1325 inArray: function( elem, arr, i ) { 1326 return arr == null ? -1 : indexOf.call( arr, elem, i ); 1327 }, 1328 1329 isXMLDoc: function( elem ) { 1330 var namespace = elem && elem.namespaceURI, 1331 docElem = elem && ( elem.ownerDocument || elem ).documentElement; 1332 1333 // Assume HTML when documentElement doesn't yet exist, such as inside 1334 // document fragments. 1335 return !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" ); 1336 }, 1337 1338 // Support: Android <=4.0 only, PhantomJS 1 only 1339 // push.apply(_, arraylike) throws on ancient WebKit 1340 merge: function( first, second ) { 1341 var len = +second.length, 1342 j = 0, 1343 i = first.length; 1344 1345 for ( ; j < len; j++ ) { 1346 first[ i++ ] = second[ j ]; 1347 } 1348 1349 first.length = i; 1350 1351 return first; 1352 }, 1353 1354 grep: function( elems, callback, invert ) { 1355 var callbackInverse, 1356 matches = [], 1357 i = 0, 1358 length = elems.length, 1359 callbackExpect = !invert; 1360 1361 // Go through the array, only saving the items 1362 // that pass the validator function 1363 for ( ; i < length; i++ ) { 1364 callbackInverse = !callback( elems[ i ], i ); 1365 if ( callbackInverse !== callbackExpect ) { 1366 matches.push( elems[ i ] ); 1367 } 1368 } 1369 1370 return matches; 1371 }, 1372 1373 // arg is for internal usage only 1374 map: function( elems, callback, arg ) { 1375 var length, value, 1376 i = 0, 1377 ret = []; 1378 1379 // Go through the array, translating each of the items to their new values 1380 if ( isArrayLike( elems ) ) { 1381 length = elems.length; 1382 for ( ; i < length; i++ ) { 1383 value = callback( elems[ i ], i, arg ); 1384 1385 if ( value != null ) { 1386 ret.push( value ); 1387 } 1388 } 1389 1390 // Go through every key on the object, 1391 } else { 1392 for ( i in elems ) { 1393 value = callback( elems[ i ], i, arg ); 1394 1395 if ( value != null ) { 1396 ret.push( value ); 1397 } 1398 } 1399 } 1400 1401 // Flatten any nested arrays 1402 return flat( ret ); 1403 }, 1404 1405 // A global GUID counter for objects 1406 guid: 1, 1407 1408 // jQuery.support is not used in Core but other projects attach their 1409 // properties to it so it needs to exist. 1410 support: support 1411} ); 1412 1413if ( typeof Symbol === "function" ) { 1414 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 1415} 1416 1417// Populate the class2type map 1418jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 1419 function( _i, name ) { 1420 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 1421 } ); 1422 1423function isArrayLike( obj ) { 1424 1425 // Support: real iOS 8.2 only (not reproducible in simulator) 1426 // `in` check used to prevent JIT error (gh-2145) 1427 // hasOwn isn't used here due to false negatives 1428 // regarding Nodelist length in IE 1429 var length = !!obj && "length" in obj && obj.length, 1430 type = toType( obj ); 1431 1432 if ( isFunction( obj ) || isWindow( obj ) ) { 1433 return false; 1434 } 1435 1436 return type === "array" || length === 0 || 1437 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 1438} 1439 1440 1441function nodeName( elem, name ) { 1442 1443 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 1444 1445} 1446var pop = arr.pop; 1447 1448 1449var sort = arr.sort; 1450 1451 1452var splice = arr.splice; 1453 1454 1455var whitespace = "[\\x20\\t\\r\\n\\f]"; 1456 1457 1458var rtrimCSS = new RegExp( 1459 "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", 1460 "g" 1461); 1462 1463 1464 1465 1466// Note: an element does not contain itself 1467jQuery.contains = function( a, b ) { 1468 var bup = b && b.parentNode; 1469 1470 return a === bup || !!( bup && bup.nodeType === 1 && ( 1471 1472 // Support: IE 9 - 11+ 1473 // IE doesn't have `contains` on SVG. 1474 a.contains ? 1475 a.contains( bup ) : 1476 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 1477 ) ); 1478}; 1479 1480 1481 1482 1483// CSS string/identifier serialization 1484// https://drafts.csswg.org/cssom/#common-serializing-idioms 1485var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; 1486 1487function fcssescape( ch, asCodePoint ) { 1488 if ( asCodePoint ) { 1489 1490 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 1491 if ( ch === "\0" ) { 1492 return "\uFFFD"; 1493 } 1494 1495 // Control characters and (dependent upon position) numbers get escaped as code points 1496 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 1497 } 1498 1499 // Other potentially-special ASCII characters get backslash-escaped 1500 return "\\" + ch; 1501} 1502 1503jQuery.escapeSelector = function( sel ) { 1504 return ( sel + "" ).replace( rcssescape, fcssescape ); 1505}; 1506 1507 1508 1509 1510var preferredDoc = document, 1511 pushNative = push; 1512 1513( function() { 1514 1515var i, 1516 Expr, 1517 outermostContext, 1518 sortInput, 1519 hasDuplicate, 1520 push = pushNative, 1521 1522 // Local document vars 1523 document, 1524 documentElement, 1525 documentIsHTML, 1526 rbuggyQSA, 1527 matches, 1528 1529 // Instance-specific data 1530 expando = jQuery.expando, 1531 dirruns = 0, 1532 done = 0, 1533 classCache = createCache(), 1534 tokenCache = createCache(), 1535 compilerCache = createCache(), 1536 nonnativeSelectorCache = createCache(), 1537 sortOrder = function( a, b ) { 1538 if ( a === b ) { 1539 hasDuplicate = true; 1540 } 1541 return 0; 1542 }, 1543 1544 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|" + 1545 "loop|multiple|open|readonly|required|scoped", 1546 1547 // Regular expressions 1548 1549 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram 1550 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + 1551 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", 1552 1553 // Attribute selectors: https://www.w3.org/TR/selectors/#attribute-selectors 1554 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 1555 1556 // Operator (capture 2) 1557 "*([*^$|!~]?=)" + whitespace + 1558 1559 // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" 1560 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + 1561 whitespace + "*\\]", 1562 1563 pseudos = ":(" + identifier + ")(?:\\((" + 1564 1565 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 1566 // 1. quoted (capture 3; capture 4 or capture 5) 1567 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 1568 1569 // 2. simple (capture 6) 1570 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 1571 1572 // 3. anything else (capture 2) 1573 ".*" + 1574 ")\\)|)", 1575 1576 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 1577 rwhitespace = new RegExp( whitespace + "+", "g" ), 1578 1579 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 1580 rleadingCombinator = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + 1581 whitespace + "*" ), 1582 rdescend = new RegExp( whitespace + "|>" ), 1583 1584 rpseudo = new RegExp( pseudos ), 1585 ridentifier = new RegExp( "^" + identifier + "$" ), 1586 1587 matchExpr = { 1588 ID: new RegExp( "^#(" + identifier + ")" ), 1589 CLASS: new RegExp( "^\\.(" + identifier + ")" ), 1590 TAG: new RegExp( "^(" + identifier + "|[*])" ), 1591 ATTR: new RegExp( "^" + attributes ), 1592 PSEUDO: new RegExp( "^" + pseudos ), 1593 CHILD: new RegExp( 1594 "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + 1595 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + 1596 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 1597 bool: new RegExp( "^(?:" + booleans + ")$", "i" ), 1598 1599 // For use in libraries implementing .is() 1600 // We use this for POS matching in `select` 1601 needsContext: new RegExp( "^" + whitespace + 1602 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 1603 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 1604 }, 1605 1606 rinputs = /^(?:input|select|textarea|button)$/i, 1607 rheader = /^h\d$/i, 1608 1609 // Easily-parseable/retrievable ID or TAG or CLASS selectors 1610 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 1611 1612 rsibling = /[+~]/, 1613 1614 // CSS escapes 1615 // https://www.w3.org/TR/CSS21/syndata.html#escaped-characters 1616 runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + 1617 "?|\\\\([^\\r\\n\\f])", "g" ), 1618 funescape = function( escape, nonHex ) { 1619 var high = "0x" + escape.slice( 1 ) - 0x10000; 1620 1621 if ( nonHex ) { 1622 1623 // Strip the backslash prefix from a non-hex escape sequence 1624 return nonHex; 1625 } 1626 1627 // Replace a hexadecimal escape sequence with the encoded Unicode code point 1628 // Support: IE <=11+ 1629 // For values outside the Basic Multilingual Plane (BMP), manually construct a 1630 // surrogate pair 1631 return high < 0 ? 1632 String.fromCharCode( high + 0x10000 ) : 1633 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 1634 }, 1635 1636 // Used for iframes; see `setDocument`. 1637 // Support: IE 9 - 11+, Edge 12 - 18+ 1638 // Removing the function wrapper causes a "Permission Denied" 1639 // error in IE/Edge. 1640 unloadHandler = function() { 1641 setDocument(); 1642 }, 1643 1644 inDisabledFieldset = addCombinator( 1645 function( elem ) { 1646 return elem.disabled === true && nodeName( elem, "fieldset" ); 1647 }, 1648 { dir: "parentNode", next: "legend" } 1649 ); 1650 1651// Support: IE <=9 only 1652// Accessing document.activeElement can throw unexpectedly 1653// https://bugs.jquery.com/ticket/13393 1654function safeActiveElement() { 1655 try { 1656 return document.activeElement; 1657 } catch ( err ) { } 1658} 1659 1660// Optimize for push.apply( _, NodeList ) 1661try { 1662 push.apply( 1663 ( arr = slice.call( preferredDoc.childNodes ) ), 1664 preferredDoc.childNodes 1665 ); 1666 1667 // Support: Android <=4.0 1668 // Detect silently failing push.apply 1669 // eslint-disable-next-line no-unused-expressions 1670 arr[ preferredDoc.childNodes.length ].nodeType; 1671} catch ( e ) { 1672 push = { 1673 apply: function( target, els ) { 1674 pushNative.apply( target, slice.call( els ) ); 1675 }, 1676 call: function( target ) { 1677 pushNative.apply( target, slice.call( arguments, 1 ) ); 1678 } 1679 }; 1680} 1681 1682function find( selector, context, results, seed ) { 1683 var m, i, elem, nid, match, groups, newSelector, 1684 newContext = context && context.ownerDocument, 1685 1686 // nodeType defaults to 9, since context defaults to document 1687 nodeType = context ? context.nodeType : 9; 1688 1689 results = results || []; 1690 1691 // Return early from calls with invalid selector or context 1692 if ( typeof selector !== "string" || !selector || 1693 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 1694 1695 return results; 1696 } 1697 1698 // Try to shortcut find operations (as opposed to filters) in HTML documents 1699 if ( !seed ) { 1700 setDocument( context ); 1701 context = context || document; 1702 1703 if ( documentIsHTML ) { 1704 1705 // If the selector is sufficiently simple, try using a "get*By*" DOM method 1706 // (excepting DocumentFragment context, where the methods don't exist) 1707 if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { 1708 1709 // ID selector 1710 if ( ( m = match[ 1 ] ) ) { 1711 1712 // Document context 1713 if ( nodeType === 9 ) { 1714 if ( ( elem = context.getElementById( m ) ) ) { 1715 1716 // Support: IE 9 only 1717 // getElementById can match elements by name instead of ID 1718 if ( elem.id === m ) { 1719 push.call( results, elem ); 1720 return results; 1721 } 1722 } else { 1723 return results; 1724 } 1725 1726 // Element context 1727 } else { 1728 1729 // Support: IE 9 only 1730 // getElementById can match elements by name instead of ID 1731 if ( newContext && ( elem = newContext.getElementById( m ) ) && 1732 find.contains( context, elem ) && 1733 elem.id === m ) { 1734 1735 push.call( results, elem ); 1736 return results; 1737 } 1738 } 1739 1740 // Type selector 1741 } else if ( match[ 2 ] ) { 1742 push.apply( results, context.getElementsByTagName( selector ) ); 1743 return results; 1744 1745 // Class selector 1746 } else if ( ( m = match[ 3 ] ) && context.getElementsByClassName ) { 1747 push.apply( results, context.getElementsByClassName( m ) ); 1748 return results; 1749 } 1750 } 1751 1752 // Take advantage of querySelectorAll 1753 if ( !nonnativeSelectorCache[ selector + " " ] && 1754 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) ) { 1755 1756 newSelector = selector; 1757 newContext = context; 1758 1759 // qSA considers elements outside a scoping root when evaluating child or 1760 // descendant combinators, which is not what we want. 1761 // In such cases, we work around the behavior by prefixing every selector in the 1762 // list with an ID selector referencing the scope context. 1763 // The technique has to be used as well when a leading combinator is used 1764 // as such selectors are not recognized by querySelectorAll. 1765 // Thanks to Andrew Dupont for this technique. 1766 if ( nodeType === 1 && 1767 ( rdescend.test( selector ) || rleadingCombinator.test( selector ) ) ) { 1768 1769 // Expand context for sibling selectors 1770 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 1771 context; 1772 1773 // We can use :scope instead of the ID hack if the browser 1774 // supports it & if we're not changing the context. 1775 // Support: IE 11+, Edge 17 - 18+ 1776 // IE/Edge sometimes throw a "Permission denied" error when 1777 // strict-comparing two documents; shallow comparisons work. 1778 // eslint-disable-next-line eqeqeq 1779 if ( newContext != context || !support.scope ) { 1780 1781 // Capture the context ID, setting it first if necessary 1782 if ( ( nid = context.getAttribute( "id" ) ) ) { 1783 nid = jQuery.escapeSelector( nid ); 1784 } else { 1785 context.setAttribute( "id", ( nid = expando ) ); 1786 } 1787 } 1788 1789 // Prefix every selector in the list 1790 groups = tokenize( selector ); 1791 i = groups.length; 1792 while ( i-- ) { 1793 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + 1794 toSelector( groups[ i ] ); 1795 } 1796 newSelector = groups.join( "," ); 1797 } 1798 1799 try { 1800 push.apply( results, 1801 newContext.querySelectorAll( newSelector ) 1802 ); 1803 return results; 1804 } catch ( qsaError ) { 1805 nonnativeSelectorCache( selector, true ); 1806 } finally { 1807 if ( nid === expando ) { 1808 context.removeAttribute( "id" ); 1809 } 1810 } 1811 } 1812 } 1813 } 1814 1815 // All others 1816 return select( selector.replace( rtrimCSS, "$1" ), context, results, seed ); 1817} 1818 1819/** 1820 * Create key-value caches of limited size 1821 * @returns {function(string, object)} Returns the Object data after storing it on itself with 1822 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 1823 * deleting the oldest entry 1824 */ 1825function createCache() { 1826 var keys = []; 1827 1828 function cache( key, value ) { 1829 1830 // Use (key + " ") to avoid collision with native prototype properties 1831 // (see https://github.com/jquery/sizzle/issues/157) 1832 if ( keys.push( key + " " ) > Expr.cacheLength ) { 1833 1834 // Only keep the most recent entries 1835 delete cache[ keys.shift() ]; 1836 } 1837 return ( cache[ key + " " ] = value ); 1838 } 1839 return cache; 1840} 1841 1842/** 1843 * Mark a function for special use by jQuery selector module 1844 * @param {Function} fn The function to mark 1845 */ 1846function markFunction( fn ) { 1847 fn[ expando ] = true; 1848 return fn; 1849} 1850 1851/** 1852 * Support testing using an element 1853 * @param {Function} fn Passed the created element and returns a boolean result 1854 */ 1855function assert( fn ) { 1856 var el = document.createElement( "fieldset" ); 1857 1858 try { 1859 return !!fn( el ); 1860 } catch ( e ) { 1861 return false; 1862 } finally { 1863 1864 // Remove from its parent by default 1865 if ( el.parentNode ) { 1866 el.parentNode.removeChild( el ); 1867 } 1868 1869 // release memory in IE 1870 el = null; 1871 } 1872} 1873 1874/** 1875 * Returns a function to use in pseudos for input types 1876 * @param {String} type 1877 */ 1878function createInputPseudo( type ) { 1879 return function( elem ) { 1880 return nodeName( elem, "input" ) && elem.type === type; 1881 }; 1882} 1883 1884/** 1885 * Returns a function to use in pseudos for buttons 1886 * @param {String} type 1887 */ 1888function createButtonPseudo( type ) { 1889 return function( elem ) { 1890 return ( nodeName( elem, "input" ) || nodeName( elem, "button" ) ) && 1891 elem.type === type; 1892 }; 1893} 1894 1895/** 1896 * Returns a function to use in pseudos for :enabled/:disabled 1897 * @param {Boolean} disabled true for :disabled; false for :enabled 1898 */ 1899function createDisabledPseudo( disabled ) { 1900 1901 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 1902 return function( elem ) { 1903 1904 // Only certain elements can match :enabled or :disabled 1905 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 1906 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 1907 if ( "form" in elem ) { 1908 1909 // Check for inherited disabledness on relevant non-disabled elements: 1910 // * listed form-associated elements in a disabled fieldset 1911 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 1912 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 1913 // * option elements in a disabled optgroup 1914 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 1915 // All such elements have a "form" property. 1916 if ( elem.parentNode && elem.disabled === false ) { 1917 1918 // Option elements defer to a parent optgroup if present 1919 if ( "label" in elem ) { 1920 if ( "label" in elem.parentNode ) { 1921 return elem.parentNode.disabled === disabled; 1922 } else { 1923 return elem.disabled === disabled; 1924 } 1925 } 1926 1927 // Support: IE 6 - 11+ 1928 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 1929 return elem.isDisabled === disabled || 1930 1931 // Where there is no isDisabled, check manually 1932 elem.isDisabled !== !disabled && 1933 inDisabledFieldset( elem ) === disabled; 1934 } 1935 1936 return elem.disabled === disabled; 1937 1938 // Try to winnow out elements that can't be disabled before trusting the disabled property. 1939 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 1940 // even exist on them, let alone have a boolean value. 1941 } else if ( "label" in elem ) { 1942 return elem.disabled === disabled; 1943 } 1944 1945 // Remaining elements are neither :enabled nor :disabled 1946 return false; 1947 }; 1948} 1949 1950/** 1951 * Returns a function to use in pseudos for positionals 1952 * @param {Function} fn 1953 */ 1954function createPositionalPseudo( fn ) { 1955 return markFunction( function( argument ) { 1956 argument = +argument; 1957 return markFunction( function( seed, matches ) { 1958 var j, 1959 matchIndexes = fn( [], seed.length, argument ), 1960 i = matchIndexes.length; 1961 1962 // Match elements found at the specified indexes 1963 while ( i-- ) { 1964 if ( seed[ ( j = matchIndexes[ i ] ) ] ) { 1965 seed[ j ] = !( matches[ j ] = seed[ j ] ); 1966 } 1967 } 1968 } ); 1969 } ); 1970} 1971 1972/** 1973 * Checks a node for validity as a jQuery selector context 1974 * @param {Element|Object=} context 1975 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 1976 */ 1977function testContext( context ) { 1978 return context && typeof context.getElementsByTagName !== "undefined" && context; 1979} 1980 1981/** 1982 * Sets document-related variables once based on the current document 1983 * @param {Element|Object} [node] An element or document object to use to set the document 1984 * @returns {Object} Returns the current document 1985 */ 1986function setDocument( node ) { 1987 var subWindow, 1988 doc = node ? node.ownerDocument || node : preferredDoc; 1989 1990 // Return early if doc is invalid or already selected 1991 // Support: IE 11+, Edge 17 - 18+ 1992 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 1993 // two documents; shallow comparisons work. 1994 // eslint-disable-next-line eqeqeq 1995 if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { 1996 return document; 1997 } 1998 1999 // Update global variables 2000 document = doc; 2001 documentElement = document.documentElement; 2002 documentIsHTML = !jQuery.isXMLDoc( document ); 2003 2004 // Support: iOS 7 only, IE 9 - 11+ 2005 // Older browsers didn't support unprefixed `matches`. 2006 matches = documentElement.matches || 2007 documentElement.webkitMatchesSelector || 2008 documentElement.msMatchesSelector; 2009 2010 // Support: IE 9 - 11+, Edge 12 - 18+ 2011 // Accessing iframe documents after unload throws "permission denied" errors 2012 // (see trac-13936). 2013 // Limit the fix to IE & Edge Legacy; despite Edge 15+ implementing `matches`, 2014 // all IE 9+ and Edge Legacy versions implement `msMatchesSelector` as well. 2015 if ( documentElement.msMatchesSelector && 2016 2017 // Support: IE 11+, Edge 17 - 18+ 2018 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2019 // two documents; shallow comparisons work. 2020 // eslint-disable-next-line eqeqeq 2021 preferredDoc != document && 2022 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { 2023 2024 // Support: IE 9 - 11+, Edge 12 - 18+ 2025 subWindow.addEventListener( "unload", unloadHandler ); 2026 } 2027 2028 // Support: IE <10 2029 // Check if getElementById returns elements by name 2030 // The broken getElementById methods don't pick up programmatically-set names, 2031 // so use a roundabout getElementsByName test 2032 support.getById = assert( function( el ) { 2033 documentElement.appendChild( el ).id = jQuery.expando; 2034 return !document.getElementsByName || 2035 !document.getElementsByName( jQuery.expando ).length; 2036 } ); 2037 2038 // Support: IE 9 only 2039 // Check to see if it's possible to do matchesSelector 2040 // on a disconnected node. 2041 support.disconnectedMatch = assert( function( el ) { 2042 return matches.call( el, "*" ); 2043 } ); 2044 2045 // Support: IE 9 - 11+, Edge 12 - 18+ 2046 // IE/Edge don't support the :scope pseudo-class. 2047 support.scope = assert( function() { 2048 return document.querySelectorAll( ":scope" ); 2049 } ); 2050 2051 // Support: Chrome 105 - 111 only, Safari 15.4 - 16.3 only 2052 // Make sure the `:has()` argument is parsed unforgivingly. 2053 // We include `*` in the test to detect buggy implementations that are 2054 // _selectively_ forgiving (specifically when the list includes at least 2055 // one valid selector). 2056 // Note that we treat complete lack of support for `:has()` as if it were 2057 // spec-compliant support, which is fine because use of `:has()` in such 2058 // environments will fail in the qSA path and fall back to jQuery traversal 2059 // anyway. 2060 support.cssHas = assert( function() { 2061 try { 2062 document.querySelector( ":has(*,:jqfake)" ); 2063 return false; 2064 } catch ( e ) { 2065 return true; 2066 } 2067 } ); 2068 2069 // ID filter and find 2070 if ( support.getById ) { 2071 Expr.filter.ID = function( id ) { 2072 var attrId = id.replace( runescape, funescape ); 2073 return function( elem ) { 2074 return elem.getAttribute( "id" ) === attrId; 2075 }; 2076 }; 2077 Expr.find.ID = function( id, context ) { 2078 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 2079 var elem = context.getElementById( id ); 2080 return elem ? [ elem ] : []; 2081 } 2082 }; 2083 } else { 2084 Expr.filter.ID = function( id ) { 2085 var attrId = id.replace( runescape, funescape ); 2086 return function( elem ) { 2087 var node = typeof elem.getAttributeNode !== "undefined" && 2088 elem.getAttributeNode( "id" ); 2089 return node && node.value === attrId; 2090 }; 2091 }; 2092 2093 // Support: IE 6 - 7 only 2094 // getElementById is not reliable as a find shortcut 2095 Expr.find.ID = function( id, context ) { 2096 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 2097 var node, i, elems, 2098 elem = context.getElementById( id ); 2099 2100 if ( elem ) { 2101 2102 // Verify the id attribute 2103 node = elem.getAttributeNode( "id" ); 2104 if ( node && node.value === id ) { 2105 return [ elem ]; 2106 } 2107 2108 // Fall back on getElementsByName 2109 elems = context.getElementsByName( id ); 2110 i = 0; 2111 while ( ( elem = elems[ i++ ] ) ) { 2112 node = elem.getAttributeNode( "id" ); 2113 if ( node && node.value === id ) { 2114 return [ elem ]; 2115 } 2116 } 2117 } 2118 2119 return []; 2120 } 2121 }; 2122 } 2123 2124 // Tag 2125 Expr.find.TAG = function( tag, context ) { 2126 if ( typeof context.getElementsByTagName !== "undefined" ) { 2127 return context.getElementsByTagName( tag ); 2128 2129 // DocumentFragment nodes don't have gEBTN 2130 } else { 2131 return context.querySelectorAll( tag ); 2132 } 2133 }; 2134 2135 // Class 2136 Expr.find.CLASS = function( className, context ) { 2137 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 2138 return context.getElementsByClassName( className ); 2139 } 2140 }; 2141 2142 /* QSA/matchesSelector 2143 ---------------------------------------------------------------------- */ 2144 2145 // QSA and matchesSelector support 2146 2147 rbuggyQSA = []; 2148 2149 // Build QSA regex 2150 // Regex strategy adopted from Diego Perini 2151 assert( function( el ) { 2152 2153 var input; 2154 2155 documentElement.appendChild( el ).innerHTML = 2156 "<a id='" + expando + "' href='' disabled='disabled'></a>" + 2157 "<select id='" + expando + "-\r\\' disabled='disabled'>" + 2158 "<option selected=''></option></select>"; 2159 2160 // Support: iOS <=7 - 8 only 2161 // Boolean attributes and "value" are not treated correctly in some XML documents 2162 if ( !el.querySelectorAll( "[selected]" ).length ) { 2163 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 2164 } 2165 2166 // Support: iOS <=7 - 8 only 2167 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 2168 rbuggyQSA.push( "~=" ); 2169 } 2170 2171 // Support: iOS 8 only 2172 // https://bugs.webkit.org/show_bug.cgi?id=136851 2173 // In-page `selector#id sibling-combinator selector` fails 2174 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 2175 rbuggyQSA.push( ".#.+[+~]" ); 2176 } 2177 2178 // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ 2179 // In some of the document kinds, these selectors wouldn't work natively. 2180 // This is probably OK but for backwards compatibility we want to maintain 2181 // handling them through jQuery traversal in jQuery 3.x. 2182 if ( !el.querySelectorAll( ":checked" ).length ) { 2183 rbuggyQSA.push( ":checked" ); 2184 } 2185 2186 // Support: Windows 8 Native Apps 2187 // The type and name attributes are restricted during .innerHTML assignment 2188 input = document.createElement( "input" ); 2189 input.setAttribute( "type", "hidden" ); 2190 el.appendChild( input ).setAttribute( "name", "D" ); 2191 2192 // Support: IE 9 - 11+ 2193 // IE's :disabled selector does not pick up the children of disabled fieldsets 2194 // Support: Chrome <=105+, Firefox <=104+, Safari <=15.4+ 2195 // In some of the document kinds, these selectors wouldn't work natively. 2196 // This is probably OK but for backwards compatibility we want to maintain 2197 // handling them through jQuery traversal in jQuery 3.x. 2198 documentElement.appendChild( el ).disabled = true; 2199 if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { 2200 rbuggyQSA.push( ":enabled", ":disabled" ); 2201 } 2202 2203 // Support: IE 11+, Edge 15 - 18+ 2204 // IE 11/Edge don't find elements on a `[name='']` query in some cases. 2205 // Adding a temporary attribute to the document before the selection works 2206 // around the issue. 2207 // Interestingly, IE 10 & older don't seem to have the issue. 2208 input = document.createElement( "input" ); 2209 input.setAttribute( "name", "" ); 2210 el.appendChild( input ); 2211 if ( !el.querySelectorAll( "[name='']" ).length ) { 2212 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + 2213 whitespace + "*(?:''|\"\")" ); 2214 } 2215 } ); 2216 2217 if ( !support.cssHas ) { 2218 2219 // Support: Chrome 105 - 110+, Safari 15.4 - 16.3+ 2220 // Our regular `try-catch` mechanism fails to detect natively-unsupported 2221 // pseudo-classes inside `:has()` (such as `:has(:contains("Foo"))`) 2222 // in browsers that parse the `:has()` argument as a forgiving selector list. 2223 // https://drafts.csswg.org/selectors/#relational now requires the argument 2224 // to be parsed unforgivingly, but browsers have not yet fully adjusted. 2225 rbuggyQSA.push( ":has" ); 2226 } 2227 2228 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); 2229 2230 /* Sorting 2231 ---------------------------------------------------------------------- */ 2232 2233 // Document order sorting 2234 sortOrder = function( a, b ) { 2235 2236 // Flag for duplicate removal 2237 if ( a === b ) { 2238 hasDuplicate = true; 2239 return 0; 2240 } 2241 2242 // Sort on method existence if only one input has compareDocumentPosition 2243 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 2244 if ( compare ) { 2245 return compare; 2246 } 2247 2248 // Calculate position if both inputs belong to the same document 2249 // Support: IE 11+, Edge 17 - 18+ 2250 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2251 // two documents; shallow comparisons work. 2252 // eslint-disable-next-line eqeqeq 2253 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? 2254 a.compareDocumentPosition( b ) : 2255 2256 // Otherwise we know they are disconnected 2257 1; 2258 2259 // Disconnected nodes 2260 if ( compare & 1 || 2261 ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { 2262 2263 // Choose the first element that is related to our preferred document 2264 // Support: IE 11+, Edge 17 - 18+ 2265 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2266 // two documents; shallow comparisons work. 2267 // eslint-disable-next-line eqeqeq 2268 if ( a === document || a.ownerDocument == preferredDoc && 2269 find.contains( preferredDoc, a ) ) { 2270 return -1; 2271 } 2272 2273 // Support: IE 11+, Edge 17 - 18+ 2274 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2275 // two documents; shallow comparisons work. 2276 // eslint-disable-next-line eqeqeq 2277 if ( b === document || b.ownerDocument == preferredDoc && 2278 find.contains( preferredDoc, b ) ) { 2279 return 1; 2280 } 2281 2282 // Maintain original order 2283 return sortInput ? 2284 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : 2285 0; 2286 } 2287 2288 return compare & 4 ? -1 : 1; 2289 }; 2290 2291 return document; 2292} 2293 2294find.matches = function( expr, elements ) { 2295 return find( expr, null, null, elements ); 2296}; 2297 2298find.matchesSelector = function( elem, expr ) { 2299 setDocument( elem ); 2300 2301 if ( documentIsHTML && 2302 !nonnativeSelectorCache[ expr + " " ] && 2303 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 2304 2305 try { 2306 var ret = matches.call( elem, expr ); 2307 2308 // IE 9's matchesSelector returns false on disconnected nodes 2309 if ( ret || support.disconnectedMatch || 2310 2311 // As well, disconnected nodes are said to be in a document 2312 // fragment in IE 9 2313 elem.document && elem.document.nodeType !== 11 ) { 2314 return ret; 2315 } 2316 } catch ( e ) { 2317 nonnativeSelectorCache( expr, true ); 2318 } 2319 } 2320 2321 return find( expr, document, null, [ elem ] ).length > 0; 2322}; 2323 2324find.contains = function( context, elem ) { 2325 2326 // Set document vars if needed 2327 // Support: IE 11+, Edge 17 - 18+ 2328 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2329 // two documents; shallow comparisons work. 2330 // eslint-disable-next-line eqeqeq 2331 if ( ( context.ownerDocument || context ) != document ) { 2332 setDocument( context ); 2333 } 2334 return jQuery.contains( context, elem ); 2335}; 2336 2337 2338find.attr = function( elem, name ) { 2339 2340 // Set document vars if needed 2341 // Support: IE 11+, Edge 17 - 18+ 2342 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 2343 // two documents; shallow comparisons work. 2344 // eslint-disable-next-line eqeqeq 2345 if ( ( elem.ownerDocument || elem ) != document ) { 2346 setDocument( elem ); 2347 } 2348 2349 var fn = Expr.attrHandle[ name.toLowerCase() ], 2350 2351 // Don't get fooled by Object.prototype properties (see trac-13807) 2352 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 2353 fn( elem, name, !documentIsHTML ) : 2354 undefined; 2355 2356 if ( val !== undefined ) { 2357 return val; 2358 } 2359 2360 return elem.getAttribute( name ); 2361}; 2362 2363find.error = function( msg ) { 2364 throw new Error( "Syntax error, unrecognized expression: " + msg ); 2365}; 2366 2367/** 2368 * Document sorting and removing duplicates 2369 * @param {ArrayLike} results 2370 */ 2371jQuery.uniqueSort = function( results ) { 2372 var elem, 2373 duplicates = [], 2374 j = 0, 2375 i = 0; 2376 2377 // Unless we *know* we can detect duplicates, assume their presence 2378 // 2379 // Support: Android <=4.0+ 2380 // Testing for detecting duplicates is unpredictable so instead assume we can't 2381 // depend on duplicate detection in all browsers without a stable sort. 2382 hasDuplicate = !support.sortStable; 2383 sortInput = !support.sortStable && slice.call( results, 0 ); 2384 sort.call( results, sortOrder ); 2385 2386 if ( hasDuplicate ) { 2387 while ( ( elem = results[ i++ ] ) ) { 2388 if ( elem === results[ i ] ) { 2389 j = duplicates.push( i ); 2390 } 2391 } 2392 while ( j-- ) { 2393 splice.call( results, duplicates[ j ], 1 ); 2394 } 2395 } 2396 2397 // Clear input after sorting to release objects 2398 // See https://github.com/jquery/sizzle/pull/225 2399 sortInput = null; 2400 2401 return results; 2402}; 2403 2404jQuery.fn.uniqueSort = function() { 2405 return this.pushStack( jQuery.uniqueSort( slice.apply( this ) ) ); 2406}; 2407 2408Expr = jQuery.expr = { 2409 2410 // Can be adjusted by the user 2411 cacheLength: 50, 2412 2413 createPseudo: markFunction, 2414 2415 match: matchExpr, 2416 2417 attrHandle: {}, 2418 2419 find: {}, 2420 2421 relative: { 2422 ">": { dir: "parentNode", first: true }, 2423 " ": { dir: "parentNode" }, 2424 "+": { dir: "previousSibling", first: true }, 2425 "~": { dir: "previousSibling" } 2426 }, 2427 2428 preFilter: { 2429 ATTR: function( match ) { 2430 match[ 1 ] = match[ 1 ].replace( runescape, funescape ); 2431 2432 // Move the given value to match[3] whether quoted or unquoted 2433 match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" ) 2434 .replace( runescape, funescape ); 2435 2436 if ( match[ 2 ] === "~=" ) { 2437 match[ 3 ] = " " + match[ 3 ] + " "; 2438 } 2439 2440 return match.slice( 0, 4 ); 2441 }, 2442 2443 CHILD: function( match ) { 2444 2445 /* matches from matchExpr["CHILD"] 2446 1 type (only|nth|...) 2447 2 what (child|of-type) 2448 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 2449 4 xn-component of xn+y argument ([+-]?\d*n|) 2450 5 sign of xn-component 2451 6 x of xn-component 2452 7 sign of y-component 2453 8 y of y-component 2454 */ 2455 match[ 1 ] = match[ 1 ].toLowerCase(); 2456 2457 if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { 2458 2459 // nth-* requires argument 2460 if ( !match[ 3 ] ) { 2461 find.error( match[ 0 ] ); 2462 } 2463 2464 // numeric x and y parameters for Expr.filter.CHILD 2465 // remember that false/true cast respectively to 0/1 2466 match[ 4 ] = +( match[ 4 ] ? 2467 match[ 5 ] + ( match[ 6 ] || 1 ) : 2468 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) 2469 ); 2470 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); 2471 2472 // other types prohibit arguments 2473 } else if ( match[ 3 ] ) { 2474 find.error( match[ 0 ] ); 2475 } 2476 2477 return match; 2478 }, 2479 2480 PSEUDO: function( match ) { 2481 var excess, 2482 unquoted = !match[ 6 ] && match[ 2 ]; 2483 2484 if ( matchExpr.CHILD.test( match[ 0 ] ) ) { 2485 return null; 2486 } 2487 2488 // Accept quoted arguments as-is 2489 if ( match[ 3 ] ) { 2490 match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; 2491 2492 // Strip excess characters from unquoted arguments 2493 } else if ( unquoted && rpseudo.test( unquoted ) && 2494 2495 // Get excess from tokenize (recursively) 2496 ( excess = tokenize( unquoted, true ) ) && 2497 2498 // advance to the next closing parenthesis 2499 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { 2500 2501 // excess is a negative index 2502 match[ 0 ] = match[ 0 ].slice( 0, excess ); 2503 match[ 2 ] = unquoted.slice( 0, excess ); 2504 } 2505 2506 // Return only captures needed by the pseudo filter method (type and argument) 2507 return match.slice( 0, 3 ); 2508 } 2509 }, 2510 2511 filter: { 2512 2513 TAG: function( nodeNameSelector ) { 2514 var expectedNodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 2515 return nodeNameSelector === "*" ? 2516 function() { 2517 return true; 2518 } : 2519 function( elem ) { 2520 return nodeName( elem, expectedNodeName ); 2521 }; 2522 }, 2523 2524 CLASS: function( className ) { 2525 var pattern = classCache[ className + " " ]; 2526 2527 return pattern || 2528 ( pattern = new RegExp( "(^|" + whitespace + ")" + className + 2529 "(" + whitespace + "|$)" ) ) && 2530 classCache( className, function( elem ) { 2531 return pattern.test( 2532 typeof elem.className === "string" && elem.className || 2533 typeof elem.getAttribute !== "undefined" && 2534 elem.getAttribute( "class" ) || 2535 "" 2536 ); 2537 } ); 2538 }, 2539 2540 ATTR: function( name, operator, check ) { 2541 return function( elem ) { 2542 var result = find.attr( elem, name ); 2543 2544 if ( result == null ) { 2545 return operator === "!="; 2546 } 2547 if ( !operator ) { 2548 return true; 2549 } 2550 2551 result += ""; 2552 2553 if ( operator === "=" ) { 2554 return result === check; 2555 } 2556 if ( operator === "!=" ) { 2557 return result !== check; 2558 } 2559 if ( operator === "^=" ) { 2560 return check && result.indexOf( check ) === 0; 2561 } 2562 if ( operator === "*=" ) { 2563 return check && result.indexOf( check ) > -1; 2564 } 2565 if ( operator === "$=" ) { 2566 return check && result.slice( -check.length ) === check; 2567 } 2568 if ( operator === "~=" ) { 2569 return ( " " + result.replace( rwhitespace, " " ) + " " ) 2570 .indexOf( check ) > -1; 2571 } 2572 if ( operator === "|=" ) { 2573 return result === check || result.slice( 0, check.length + 1 ) === check + "-"; 2574 } 2575 2576 return false; 2577 }; 2578 }, 2579 2580 CHILD: function( type, what, _argument, first, last ) { 2581 var simple = type.slice( 0, 3 ) !== "nth", 2582 forward = type.slice( -4 ) !== "last", 2583 ofType = what === "of-type"; 2584 2585 return first === 1 && last === 0 ? 2586 2587 // Shortcut for :nth-*(n) 2588 function( elem ) { 2589 return !!elem.parentNode; 2590 } : 2591 2592 function( elem, _context, xml ) { 2593 var cache, outerCache, node, nodeIndex, start, 2594 dir = simple !== forward ? "nextSibling" : "previousSibling", 2595 parent = elem.parentNode, 2596 name = ofType && elem.nodeName.toLowerCase(), 2597 useCache = !xml && !ofType, 2598 diff = false; 2599 2600 if ( parent ) { 2601 2602 // :(first|last|only)-(child|of-type) 2603 if ( simple ) { 2604 while ( dir ) { 2605 node = elem; 2606 while ( ( node = node[ dir ] ) ) { 2607 if ( ofType ? 2608 nodeName( node, name ) : 2609 node.nodeType === 1 ) { 2610 2611 return false; 2612 } 2613 } 2614 2615 // Reverse direction for :only-* (if we haven't yet done so) 2616 start = dir = type === "only" && !start && "nextSibling"; 2617 } 2618 return true; 2619 } 2620 2621 start = [ forward ? parent.firstChild : parent.lastChild ]; 2622 2623 // non-xml :nth-child(...) stores cache data on `parent` 2624 if ( forward && useCache ) { 2625 2626 // Seek `elem` from a previously-cached index 2627 outerCache = parent[ expando ] || ( parent[ expando ] = {} ); 2628 cache = outerCache[ type ] || []; 2629 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 2630 diff = nodeIndex && cache[ 2 ]; 2631 node = nodeIndex && parent.childNodes[ nodeIndex ]; 2632 2633 while ( ( node = ++nodeIndex && node && node[ dir ] || 2634 2635 // Fallback to seeking `elem` from the start 2636 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 2637 2638 // When found, cache indexes on `parent` and break 2639 if ( node.nodeType === 1 && ++diff && node === elem ) { 2640 outerCache[ type ] = [ dirruns, nodeIndex, diff ]; 2641 break; 2642 } 2643 } 2644 2645 } else { 2646 2647 // Use previously-cached element index if available 2648 if ( useCache ) { 2649 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 2650 cache = outerCache[ type ] || []; 2651 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 2652 diff = nodeIndex; 2653 } 2654 2655 // xml :nth-child(...) 2656 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 2657 if ( diff === false ) { 2658 2659 // Use the same loop as above to seek `elem` from the start 2660 while ( ( node = ++nodeIndex && node && node[ dir ] || 2661 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 2662 2663 if ( ( ofType ? 2664 nodeName( node, name ) : 2665 node.nodeType === 1 ) && 2666 ++diff ) { 2667 2668 // Cache the index of each encountered element 2669 if ( useCache ) { 2670 outerCache = node[ expando ] || 2671 ( node[ expando ] = {} ); 2672 outerCache[ type ] = [ dirruns, diff ]; 2673 } 2674 2675 if ( node === elem ) { 2676 break; 2677 } 2678 } 2679 } 2680 } 2681 } 2682 2683 // Incorporate the offset, then check against cycle size 2684 diff -= last; 2685 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 2686 } 2687 }; 2688 }, 2689 2690 PSEUDO: function( pseudo, argument ) { 2691 2692 // pseudo-class names are case-insensitive 2693 // https://www.w3.org/TR/selectors/#pseudo-classes 2694 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 2695 // Remember that setFilters inherits from pseudos 2696 var args, 2697 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 2698 find.error( "unsupported pseudo: " + pseudo ); 2699 2700 // The user may use createPseudo to indicate that 2701 // arguments are needed to create the filter function 2702 // just as jQuery does 2703 if ( fn[ expando ] ) { 2704 return fn( argument ); 2705 } 2706 2707 // But maintain support for old signatures 2708 if ( fn.length > 1 ) { 2709 args = [ pseudo, pseudo, "", argument ]; 2710 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 2711 markFunction( function( seed, matches ) { 2712 var idx, 2713 matched = fn( seed, argument ), 2714 i = matched.length; 2715 while ( i-- ) { 2716 idx = indexOf.call( seed, matched[ i ] ); 2717 seed[ idx ] = !( matches[ idx ] = matched[ i ] ); 2718 } 2719 } ) : 2720 function( elem ) { 2721 return fn( elem, 0, args ); 2722 }; 2723 } 2724 2725 return fn; 2726 } 2727 }, 2728 2729 pseudos: { 2730 2731 // Potentially complex pseudos 2732 not: markFunction( function( selector ) { 2733 2734 // Trim the selector passed to compile 2735 // to avoid treating leading and trailing 2736 // spaces as combinators 2737 var input = [], 2738 results = [], 2739 matcher = compile( selector.replace( rtrimCSS, "$1" ) ); 2740 2741 return matcher[ expando ] ? 2742 markFunction( function( seed, matches, _context, xml ) { 2743 var elem, 2744 unmatched = matcher( seed, null, xml, [] ), 2745 i = seed.length; 2746 2747 // Match elements unmatched by `matcher` 2748 while ( i-- ) { 2749 if ( ( elem = unmatched[ i ] ) ) { 2750 seed[ i ] = !( matches[ i ] = elem ); 2751 } 2752 } 2753 } ) : 2754 function( elem, _context, xml ) { 2755 input[ 0 ] = elem; 2756 matcher( input, null, xml, results ); 2757 2758 // Don't keep the element 2759 // (see https://github.com/jquery/sizzle/issues/299) 2760 input[ 0 ] = null; 2761 return !results.pop(); 2762 }; 2763 } ), 2764 2765 has: markFunction( function( selector ) { 2766 return function( elem ) { 2767 return find( selector, elem ).length > 0; 2768 }; 2769 } ), 2770 2771 contains: markFunction( function( text ) { 2772 text = text.replace( runescape, funescape ); 2773 return function( elem ) { 2774 return ( elem.textContent || jQuery.text( elem ) ).indexOf( text ) > -1; 2775 }; 2776 } ), 2777 2778 // "Whether an element is represented by a :lang() selector 2779 // is based solely on the element's language value 2780 // being equal to the identifier C, 2781 // or beginning with the identifier C immediately followed by "-". 2782 // The matching of C against the element's language value is performed case-insensitively. 2783 // The identifier C does not have to be a valid language name." 2784 // https://www.w3.org/TR/selectors/#lang-pseudo 2785 lang: markFunction( function( lang ) { 2786 2787 // lang value must be a valid identifier 2788 if ( !ridentifier.test( lang || "" ) ) { 2789 find.error( "unsupported lang: " + lang ); 2790 } 2791 lang = lang.replace( runescape, funescape ).toLowerCase(); 2792 return function( elem ) { 2793 var elemLang; 2794 do { 2795 if ( ( elemLang = documentIsHTML ? 2796 elem.lang : 2797 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { 2798 2799 elemLang = elemLang.toLowerCase(); 2800 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 2801 } 2802 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); 2803 return false; 2804 }; 2805 } ), 2806 2807 // Miscellaneous 2808 target: function( elem ) { 2809 var hash = window.location && window.location.hash; 2810 return hash && hash.slice( 1 ) === elem.id; 2811 }, 2812 2813 root: function( elem ) { 2814 return elem === documentElement; 2815 }, 2816 2817 focus: function( elem ) { 2818 return elem === safeActiveElement() && 2819 document.hasFocus() && 2820 !!( elem.type || elem.href || ~elem.tabIndex ); 2821 }, 2822 2823 // Boolean properties 2824 enabled: createDisabledPseudo( false ), 2825 disabled: createDisabledPseudo( true ), 2826 2827 checked: function( elem ) { 2828 2829 // In CSS3, :checked should return both checked and selected elements 2830 // https://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 2831 return ( nodeName( elem, "input" ) && !!elem.checked ) || 2832 ( nodeName( elem, "option" ) && !!elem.selected ); 2833 }, 2834 2835 selected: function( elem ) { 2836 2837 // Support: IE <=11+ 2838 // Accessing the selectedIndex property 2839 // forces the browser to treat the default option as 2840 // selected when in an optgroup. 2841 if ( elem.parentNode ) { 2842 // eslint-disable-next-line no-unused-expressions 2843 elem.parentNode.selectedIndex; 2844 } 2845 2846 return elem.selected === true; 2847 }, 2848 2849 // Contents 2850 empty: function( elem ) { 2851 2852 // https://www.w3.org/TR/selectors/#empty-pseudo 2853 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 2854 // but not by others (comment: 8; processing instruction: 7; etc.) 2855 // nodeType < 6 works because attributes (2) do not appear as children 2856 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 2857 if ( elem.nodeType < 6 ) { 2858 return false; 2859 } 2860 } 2861 return true; 2862 }, 2863 2864 parent: function( elem ) { 2865 return !Expr.pseudos.empty( elem ); 2866 }, 2867 2868 // Element/input types 2869 header: function( elem ) { 2870 return rheader.test( elem.nodeName ); 2871 }, 2872 2873 input: function( elem ) { 2874 return rinputs.test( elem.nodeName ); 2875 }, 2876 2877 button: function( elem ) { 2878 return nodeName( elem, "input" ) && elem.type === "button" || 2879 nodeName( elem, "button" ); 2880 }, 2881 2882 text: function( elem ) { 2883 var attr; 2884 return nodeName( elem, "input" ) && elem.type === "text" && 2885 2886 // Support: IE <10 only 2887 // New HTML5 attribute values (e.g., "search") appear 2888 // with elem.type === "text" 2889 ( ( attr = elem.getAttribute( "type" ) ) == null || 2890 attr.toLowerCase() === "text" ); 2891 }, 2892 2893 // Position-in-collection 2894 first: createPositionalPseudo( function() { 2895 return [ 0 ]; 2896 } ), 2897 2898 last: createPositionalPseudo( function( _matchIndexes, length ) { 2899 return [ length - 1 ]; 2900 } ), 2901 2902 eq: createPositionalPseudo( function( _matchIndexes, length, argument ) { 2903 return [ argument < 0 ? argument + length : argument ]; 2904 } ), 2905 2906 even: createPositionalPseudo( function( matchIndexes, length ) { 2907 var i = 0; 2908 for ( ; i < length; i += 2 ) { 2909 matchIndexes.push( i ); 2910 } 2911 return matchIndexes; 2912 } ), 2913 2914 odd: createPositionalPseudo( function( matchIndexes, length ) { 2915 var i = 1; 2916 for ( ; i < length; i += 2 ) { 2917 matchIndexes.push( i ); 2918 } 2919 return matchIndexes; 2920 } ), 2921 2922 lt: createPositionalPseudo( function( matchIndexes, length, argument ) { 2923 var i; 2924 2925 if ( argument < 0 ) { 2926 i = argument + length; 2927 } else if ( argument > length ) { 2928 i = length; 2929 } else { 2930 i = argument; 2931 } 2932 2933 for ( ; --i >= 0; ) { 2934 matchIndexes.push( i ); 2935 } 2936 return matchIndexes; 2937 } ), 2938 2939 gt: createPositionalPseudo( function( matchIndexes, length, argument ) { 2940 var i = argument < 0 ? argument + length : argument; 2941 for ( ; ++i < length; ) { 2942 matchIndexes.push( i ); 2943 } 2944 return matchIndexes; 2945 } ) 2946 } 2947}; 2948 2949Expr.pseudos.nth = Expr.pseudos.eq; 2950 2951// Add button/input type pseudos 2952for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 2953 Expr.pseudos[ i ] = createInputPseudo( i ); 2954} 2955for ( i in { submit: true, reset: true } ) { 2956 Expr.pseudos[ i ] = createButtonPseudo( i ); 2957} 2958 2959// Easy API for creating new setFilters 2960function setFilters() {} 2961setFilters.prototype = Expr.filters = Expr.pseudos; 2962Expr.setFilters = new setFilters(); 2963 2964function tokenize( selector, parseOnly ) { 2965 var matched, match, tokens, type, 2966 soFar, groups, preFilters, 2967 cached = tokenCache[ selector + " " ]; 2968 2969 if ( cached ) { 2970 return parseOnly ? 0 : cached.slice( 0 ); 2971 } 2972 2973 soFar = selector; 2974 groups = []; 2975 preFilters = Expr.preFilter; 2976 2977 while ( soFar ) { 2978 2979 // Comma and first run 2980 if ( !matched || ( match = rcomma.exec( soFar ) ) ) { 2981 if ( match ) { 2982 2983 // Don't consume trailing commas as valid 2984 soFar = soFar.slice( match[ 0 ].length ) || soFar; 2985 } 2986 groups.push( ( tokens = [] ) ); 2987 } 2988 2989 matched = false; 2990 2991 // Combinators 2992 if ( ( match = rleadingCombinator.exec( soFar ) ) ) { 2993 matched = match.shift(); 2994 tokens.push( { 2995 value: matched, 2996 2997 // Cast descendant combinators to space 2998 type: match[ 0 ].replace( rtrimCSS, " " ) 2999 } ); 3000 soFar = soFar.slice( matched.length ); 3001 } 3002 3003 // Filters 3004 for ( type in Expr.filter ) { 3005 if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || 3006 ( match = preFilters[ type ]( match ) ) ) ) { 3007 matched = match.shift(); 3008 tokens.push( { 3009 value: matched, 3010 type: type, 3011 matches: match 3012 } ); 3013 soFar = soFar.slice( matched.length ); 3014 } 3015 } 3016 3017 if ( !matched ) { 3018 break; 3019 } 3020 } 3021 3022 // Return the length of the invalid excess 3023 // if we're just parsing 3024 // Otherwise, throw an error or return tokens 3025 if ( parseOnly ) { 3026 return soFar.length; 3027 } 3028 3029 return soFar ? 3030 find.error( selector ) : 3031 3032 // Cache the tokens 3033 tokenCache( selector, groups ).slice( 0 ); 3034} 3035 3036function toSelector( tokens ) { 3037 var i = 0, 3038 len = tokens.length, 3039 selector = ""; 3040 for ( ; i < len; i++ ) { 3041 selector += tokens[ i ].value; 3042 } 3043 return selector; 3044} 3045 3046function addCombinator( matcher, combinator, base ) { 3047 var dir = combinator.dir, 3048 skip = combinator.next, 3049 key = skip || dir, 3050 checkNonElements = base && key === "parentNode", 3051 doneName = done++; 3052 3053 return combinator.first ? 3054 3055 // Check against closest ancestor/preceding element 3056 function( elem, context, xml ) { 3057 while ( ( elem = elem[ dir ] ) ) { 3058 if ( elem.nodeType === 1 || checkNonElements ) { 3059 return matcher( elem, context, xml ); 3060 } 3061 } 3062 return false; 3063 } : 3064 3065 // Check against all ancestor/preceding elements 3066 function( elem, context, xml ) { 3067 var oldCache, outerCache, 3068 newCache = [ dirruns, doneName ]; 3069 3070 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 3071 if ( xml ) { 3072 while ( ( elem = elem[ dir ] ) ) { 3073 if ( elem.nodeType === 1 || checkNonElements ) { 3074 if ( matcher( elem, context, xml ) ) { 3075 return true; 3076 } 3077 } 3078 } 3079 } else { 3080 while ( ( elem = elem[ dir ] ) ) { 3081 if ( elem.nodeType === 1 || checkNonElements ) { 3082 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 3083 3084 if ( skip && nodeName( elem, skip ) ) { 3085 elem = elem[ dir ] || elem; 3086 } else if ( ( oldCache = outerCache[ key ] ) && 3087 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 3088 3089 // Assign to newCache so results back-propagate to previous elements 3090 return ( newCache[ 2 ] = oldCache[ 2 ] ); 3091 } else { 3092 3093 // Reuse newcache so results back-propagate to previous elements 3094 outerCache[ key ] = newCache; 3095 3096 // A match means we're done; a fail means we have to keep checking 3097 if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { 3098 return true; 3099 } 3100 } 3101 } 3102 } 3103 } 3104 return false; 3105 }; 3106} 3107 3108function elementMatcher( matchers ) { 3109 return matchers.length > 1 ? 3110 function( elem, context, xml ) { 3111 var i = matchers.length; 3112 while ( i-- ) { 3113 if ( !matchers[ i ]( elem, context, xml ) ) { 3114 return false; 3115 } 3116 } 3117 return true; 3118 } : 3119 matchers[ 0 ]; 3120} 3121 3122function multipleContexts( selector, contexts, results ) { 3123 var i = 0, 3124 len = contexts.length; 3125 for ( ; i < len; i++ ) { 3126 find( selector, contexts[ i ], results ); 3127 } 3128 return results; 3129} 3130 3131function condense( unmatched, map, filter, context, xml ) { 3132 var elem, 3133 newUnmatched = [], 3134 i = 0, 3135 len = unmatched.length, 3136 mapped = map != null; 3137 3138 for ( ; i < len; i++ ) { 3139 if ( ( elem = unmatched[ i ] ) ) { 3140 if ( !filter || filter( elem, context, xml ) ) { 3141 newUnmatched.push( elem ); 3142 if ( mapped ) { 3143 map.push( i ); 3144 } 3145 } 3146 } 3147 } 3148 3149 return newUnmatched; 3150} 3151 3152function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 3153 if ( postFilter && !postFilter[ expando ] ) { 3154 postFilter = setMatcher( postFilter ); 3155 } 3156 if ( postFinder && !postFinder[ expando ] ) { 3157 postFinder = setMatcher( postFinder, postSelector ); 3158 } 3159 return markFunction( function( seed, results, context, xml ) { 3160 var temp, i, elem, matcherOut, 3161 preMap = [], 3162 postMap = [], 3163 preexisting = results.length, 3164 3165 // Get initial elements from seed or context 3166 elems = seed || 3167 multipleContexts( selector || "*", 3168 context.nodeType ? [ context ] : context, [] ), 3169 3170 // Prefilter to get matcher input, preserving a map for seed-results synchronization 3171 matcherIn = preFilter && ( seed || !selector ) ? 3172 condense( elems, preMap, preFilter, context, xml ) : 3173 elems; 3174 3175 if ( matcher ) { 3176 3177 // If we have a postFinder, or filtered seed, or non-seed postFilter 3178 // or preexisting results, 3179 matcherOut = postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 3180 3181 // ...intermediate processing is necessary 3182 [] : 3183 3184 // ...otherwise use results directly 3185 results; 3186 3187 // Find primary matches 3188 matcher( matcherIn, matcherOut, context, xml ); 3189 } else { 3190 matcherOut = matcherIn; 3191 } 3192 3193 // Apply postFilter 3194 if ( postFilter ) { 3195 temp = condense( matcherOut, postMap ); 3196 postFilter( temp, [], context, xml ); 3197 3198 // Un-match failing elements by moving them back to matcherIn 3199 i = temp.length; 3200 while ( i-- ) { 3201 if ( ( elem = temp[ i ] ) ) { 3202 matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); 3203 } 3204 } 3205 } 3206 3207 if ( seed ) { 3208 if ( postFinder || preFilter ) { 3209 if ( postFinder ) { 3210 3211 // Get the final matcherOut by condensing this intermediate into postFinder contexts 3212 temp = []; 3213 i = matcherOut.length; 3214 while ( i-- ) { 3215 if ( ( elem = matcherOut[ i ] ) ) { 3216 3217 // Restore matcherIn since elem is not yet a final match 3218 temp.push( ( matcherIn[ i ] = elem ) ); 3219 } 3220 } 3221 postFinder( null, ( matcherOut = [] ), temp, xml ); 3222 } 3223 3224 // Move matched elements from seed to results to keep them synchronized 3225 i = matcherOut.length; 3226 while ( i-- ) { 3227 if ( ( elem = matcherOut[ i ] ) && 3228 ( temp = postFinder ? indexOf.call( seed, elem ) : preMap[ i ] ) > -1 ) { 3229 3230 seed[ temp ] = !( results[ temp ] = elem ); 3231 } 3232 } 3233 } 3234 3235 // Add elements to results, through postFinder if defined 3236 } else { 3237 matcherOut = condense( 3238 matcherOut === results ? 3239 matcherOut.splice( preexisting, matcherOut.length ) : 3240 matcherOut 3241 ); 3242 if ( postFinder ) { 3243 postFinder( null, results, matcherOut, xml ); 3244 } else { 3245 push.apply( results, matcherOut ); 3246 } 3247 } 3248 } ); 3249} 3250 3251function matcherFromTokens( tokens ) { 3252 var checkContext, matcher, j, 3253 len = tokens.length, 3254 leadingRelative = Expr.relative[ tokens[ 0 ].type ], 3255 implicitRelative = leadingRelative || Expr.relative[ " " ], 3256 i = leadingRelative ? 1 : 0, 3257 3258 // The foundational matcher ensures that elements are reachable from top-level context(s) 3259 matchContext = addCombinator( function( elem ) { 3260 return elem === checkContext; 3261 }, implicitRelative, true ), 3262 matchAnyContext = addCombinator( function( elem ) { 3263 return indexOf.call( checkContext, elem ) > -1; 3264 }, implicitRelative, true ), 3265 matchers = [ function( elem, context, xml ) { 3266 3267 // Support: IE 11+, Edge 17 - 18+ 3268 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3269 // two documents; shallow comparisons work. 3270 // eslint-disable-next-line eqeqeq 3271 var ret = ( !leadingRelative && ( xml || context != outermostContext ) ) || ( 3272 ( checkContext = context ).nodeType ? 3273 matchContext( elem, context, xml ) : 3274 matchAnyContext( elem, context, xml ) ); 3275 3276 // Avoid hanging onto element 3277 // (see https://github.com/jquery/sizzle/issues/299) 3278 checkContext = null; 3279 return ret; 3280 } ]; 3281 3282 for ( ; i < len; i++ ) { 3283 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { 3284 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; 3285 } else { 3286 matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); 3287 3288 // Return special upon seeing a positional matcher 3289 if ( matcher[ expando ] ) { 3290 3291 // Find the next relative operator (if any) for proper handling 3292 j = ++i; 3293 for ( ; j < len; j++ ) { 3294 if ( Expr.relative[ tokens[ j ].type ] ) { 3295 break; 3296 } 3297 } 3298 return setMatcher( 3299 i > 1 && elementMatcher( matchers ), 3300 i > 1 && toSelector( 3301 3302 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 3303 tokens.slice( 0, i - 1 ) 3304 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) 3305 ).replace( rtrimCSS, "$1" ), 3306 matcher, 3307 i < j && matcherFromTokens( tokens.slice( i, j ) ), 3308 j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), 3309 j < len && toSelector( tokens ) 3310 ); 3311 } 3312 matchers.push( matcher ); 3313 } 3314 } 3315 3316 return elementMatcher( matchers ); 3317} 3318 3319function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 3320 var bySet = setMatchers.length > 0, 3321 byElement = elementMatchers.length > 0, 3322 superMatcher = function( seed, context, xml, results, outermost ) { 3323 var elem, j, matcher, 3324 matchedCount = 0, 3325 i = "0", 3326 unmatched = seed && [], 3327 setMatched = [], 3328 contextBackup = outermostContext, 3329 3330 // We must always have either seed elements or outermost context 3331 elems = seed || byElement && Expr.find.TAG( "*", outermost ), 3332 3333 // Use integer dirruns iff this is the outermost matcher 3334 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), 3335 len = elems.length; 3336 3337 if ( outermost ) { 3338 3339 // Support: IE 11+, Edge 17 - 18+ 3340 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3341 // two documents; shallow comparisons work. 3342 // eslint-disable-next-line eqeqeq 3343 outermostContext = context == document || context || outermost; 3344 } 3345 3346 // Add elements passing elementMatchers directly to results 3347 // Support: iOS <=7 - 9 only 3348 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching 3349 // elements by id. (see trac-14142) 3350 for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { 3351 if ( byElement && elem ) { 3352 j = 0; 3353 3354 // Support: IE 11+, Edge 17 - 18+ 3355 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 3356 // two documents; shallow comparisons work. 3357 // eslint-disable-next-line eqeqeq 3358 if ( !context && elem.ownerDocument != document ) { 3359 setDocument( elem ); 3360 xml = !documentIsHTML; 3361 } 3362 while ( ( matcher = elementMatchers[ j++ ] ) ) { 3363 if ( matcher( elem, context || document, xml ) ) { 3364 push.call( results, elem ); 3365 break; 3366 } 3367 } 3368 if ( outermost ) { 3369 dirruns = dirrunsUnique; 3370 } 3371 } 3372 3373 // Track unmatched elements for set filters 3374 if ( bySet ) { 3375 3376 // They will have gone through all possible matchers 3377 if ( ( elem = !matcher && elem ) ) { 3378 matchedCount--; 3379 } 3380 3381 // Lengthen the array for every element, matched or not 3382 if ( seed ) { 3383 unmatched.push( elem ); 3384 } 3385 } 3386 } 3387 3388 // `i` is now the count of elements visited above, and adding it to `matchedCount` 3389 // makes the latter nonnegative. 3390 matchedCount += i; 3391 3392 // Apply set filters to unmatched elements 3393 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 3394 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 3395 // no element matchers and no seed. 3396 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 3397 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 3398 // numerically zero. 3399 if ( bySet && i !== matchedCount ) { 3400 j = 0; 3401 while ( ( matcher = setMatchers[ j++ ] ) ) { 3402 matcher( unmatched, setMatched, context, xml ); 3403 } 3404 3405 if ( seed ) { 3406 3407 // Reintegrate element matches to eliminate the need for sorting 3408 if ( matchedCount > 0 ) { 3409 while ( i-- ) { 3410 if ( !( unmatched[ i ] || setMatched[ i ] ) ) { 3411 setMatched[ i ] = pop.call( results ); 3412 } 3413 } 3414 } 3415 3416 // Discard index placeholder values to get only actual matches 3417 setMatched = condense( setMatched ); 3418 } 3419 3420 // Add matches to results 3421 push.apply( results, setMatched ); 3422 3423 // Seedless set matches succeeding multiple successful matchers stipulate sorting 3424 if ( outermost && !seed && setMatched.length > 0 && 3425 ( matchedCount + setMatchers.length ) > 1 ) { 3426 3427 jQuery.uniqueSort( results ); 3428 } 3429 } 3430 3431 // Override manipulation of globals by nested matchers 3432 if ( outermost ) { 3433 dirruns = dirrunsUnique; 3434 outermostContext = contextBackup; 3435 } 3436 3437 return unmatched; 3438 }; 3439 3440 return bySet ? 3441 markFunction( superMatcher ) : 3442 superMatcher; 3443} 3444 3445function compile( selector, match /* Internal Use Only */ ) { 3446 var i, 3447 setMatchers = [], 3448 elementMatchers = [], 3449 cached = compilerCache[ selector + " " ]; 3450 3451 if ( !cached ) { 3452 3453 // Generate a function of recursive functions that can be used to check each element 3454 if ( !match ) { 3455 match = tokenize( selector ); 3456 } 3457 i = match.length; 3458 while ( i-- ) { 3459 cached = matcherFromTokens( match[ i ] ); 3460 if ( cached[ expando ] ) { 3461 setMatchers.push( cached ); 3462 } else { 3463 elementMatchers.push( cached ); 3464 } 3465 } 3466 3467 // Cache the compiled function 3468 cached = compilerCache( selector, 3469 matcherFromGroupMatchers( elementMatchers, setMatchers ) ); 3470 3471 // Save selector and tokenization 3472 cached.selector = selector; 3473 } 3474 return cached; 3475} 3476 3477/** 3478 * A low-level selection function that works with jQuery's compiled 3479 * selector functions 3480 * @param {String|Function} selector A selector or a pre-compiled 3481 * selector function built with jQuery selector compile 3482 * @param {Element} context 3483 * @param {Array} [results] 3484 * @param {Array} [seed] A set of elements to match against 3485 */ 3486function select( selector, context, results, seed ) { 3487 var i, tokens, token, type, find, 3488 compiled = typeof selector === "function" && selector, 3489 match = !seed && tokenize( ( selector = compiled.selector || selector ) ); 3490 3491 results = results || []; 3492 3493 // Try to minimize operations if there is only one selector in the list and no seed 3494 // (the latter of which guarantees us context) 3495 if ( match.length === 1 ) { 3496 3497 // Reduce context if the leading compound selector is an ID 3498 tokens = match[ 0 ] = match[ 0 ].slice( 0 ); 3499 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && 3500 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { 3501 3502 context = ( Expr.find.ID( 3503 token.matches[ 0 ].replace( runescape, funescape ), 3504 context 3505 ) || [] )[ 0 ]; 3506 if ( !context ) { 3507 return results; 3508 3509 // Precompiled matchers will still verify ancestry, so step up a level 3510 } else if ( compiled ) { 3511 context = context.parentNode; 3512 } 3513 3514 selector = selector.slice( tokens.shift().value.length ); 3515 } 3516 3517 // Fetch a seed set for right-to-left matching 3518 i = matchExpr.needsContext.test( selector ) ? 0 : tokens.length; 3519 while ( i-- ) { 3520 token = tokens[ i ]; 3521 3522 // Abort if we hit a combinator 3523 if ( Expr.relative[ ( type = token.type ) ] ) { 3524 break; 3525 } 3526 if ( ( find = Expr.find[ type ] ) ) { 3527 3528 // Search, expanding context for leading sibling combinators 3529 if ( ( seed = find( 3530 token.matches[ 0 ].replace( runescape, funescape ), 3531 rsibling.test( tokens[ 0 ].type ) && 3532 testContext( context.parentNode ) || context 3533 ) ) ) { 3534 3535 // If seed is empty or no tokens remain, we can return early 3536 tokens.splice( i, 1 ); 3537 selector = seed.length && toSelector( tokens ); 3538 if ( !selector ) { 3539 push.apply( results, seed ); 3540 return results; 3541 } 3542 3543 break; 3544 } 3545 } 3546 } 3547 } 3548 3549 // Compile and execute a filtering function if one is not provided 3550 // Provide `match` to avoid retokenization if we modified the selector above 3551 ( compiled || compile( selector, match ) )( 3552 seed, 3553 context, 3554 !documentIsHTML, 3555 results, 3556 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 3557 ); 3558 return results; 3559} 3560 3561// One-time assignments 3562 3563// Support: Android <=4.0 - 4.1+ 3564// Sort stability 3565support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; 3566 3567// Initialize against the default document 3568setDocument(); 3569 3570// Support: Android <=4.0 - 4.1+ 3571// Detached nodes confoundingly follow *each other* 3572support.sortDetached = assert( function( el ) { 3573 3574 // Should return 1, but returns 4 (following) 3575 return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; 3576} ); 3577 3578jQuery.find = find; 3579 3580// Deprecated 3581jQuery.expr[ ":" ] = jQuery.expr.pseudos; 3582jQuery.unique = jQuery.uniqueSort; 3583 3584// These have always been private, but they used to be documented as part of 3585// Sizzle so let's maintain them for now for backwards compatibility purposes. 3586find.compile = compile; 3587find.select = select; 3588find.setDocument = setDocument; 3589find.tokenize = tokenize; 3590 3591find.escape = jQuery.escapeSelector; 3592find.getText = jQuery.text; 3593find.isXML = jQuery.isXMLDoc; 3594find.selectors = jQuery.expr; 3595find.support = jQuery.support; 3596find.uniqueSort = jQuery.uniqueSort; 3597 3598 /* eslint-enable */ 3599 3600} )(); 3601 3602 3603var dir = function( elem, dir, until ) { 3604 var matched = [], 3605 truncate = until !== undefined; 3606 3607 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 3608 if ( elem.nodeType === 1 ) { 3609 if ( truncate && jQuery( elem ).is( until ) ) { 3610 break; 3611 } 3612 matched.push( elem ); 3613 } 3614 } 3615 return matched; 3616}; 3617 3618 3619var siblings = function( n, elem ) { 3620 var matched = []; 3621 3622 for ( ; n; n = n.nextSibling ) { 3623 if ( n.nodeType === 1 && n !== elem ) { 3624 matched.push( n ); 3625 } 3626 } 3627 3628 return matched; 3629}; 3630 3631 3632var rneedsContext = jQuery.expr.match.needsContext; 3633 3634var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); 3635 3636 3637 3638// Implement the identical functionality for filter and not 3639function winnow( elements, qualifier, not ) { 3640 if ( isFunction( qualifier ) ) { 3641 return jQuery.grep( elements, function( elem, i ) { 3642 return !!qualifier.call( elem, i, elem ) !== not; 3643 } ); 3644 } 3645 3646 // Single element 3647 if ( qualifier.nodeType ) { 3648 return jQuery.grep( elements, function( elem ) { 3649 return ( elem === qualifier ) !== not; 3650 } ); 3651 } 3652 3653 // Arraylike of elements (jQuery, arguments, Array) 3654 if ( typeof qualifier !== "string" ) { 3655 return jQuery.grep( elements, function( elem ) { 3656 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 3657 } ); 3658 } 3659 3660 // Filtered directly for both simple and complex selectors 3661 return jQuery.filter( qualifier, elements, not ); 3662} 3663 3664jQuery.filter = function( expr, elems, not ) { 3665 var elem = elems[ 0 ]; 3666 3667 if ( not ) { 3668 expr = ":not(" + expr + ")"; 3669 } 3670 3671 if ( elems.length === 1 && elem.nodeType === 1 ) { 3672 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; 3673 } 3674 3675 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 3676 return elem.nodeType === 1; 3677 } ) ); 3678}; 3679 3680jQuery.fn.extend( { 3681 find: function( selector ) { 3682 var i, ret, 3683 len = this.length, 3684 self = this; 3685 3686 if ( typeof selector !== "string" ) { 3687 return this.pushStack( jQuery( selector ).filter( function() { 3688 for ( i = 0; i < len; i++ ) { 3689 if ( jQuery.contains( self[ i ], this ) ) { 3690 return true; 3691 } 3692 } 3693 } ) ); 3694 } 3695 3696 ret = this.pushStack( [] ); 3697 3698 for ( i = 0; i < len; i++ ) { 3699 jQuery.find( selector, self[ i ], ret ); 3700 } 3701 3702 return len > 1 ? jQuery.uniqueSort( ret ) : ret; 3703 }, 3704 filter: function( selector ) { 3705 return this.pushStack( winnow( this, selector || [], false ) ); 3706 }, 3707 not: function( selector ) { 3708 return this.pushStack( winnow( this, selector || [], true ) ); 3709 }, 3710 is: function( selector ) { 3711 return !!winnow( 3712 this, 3713 3714 // If this is a positional/relative selector, check membership in the returned set 3715 // so $("p:first").is("p:last") won't return true for a doc with two "p". 3716 typeof selector === "string" && rneedsContext.test( selector ) ? 3717 jQuery( selector ) : 3718 selector || [], 3719 false 3720 ).length; 3721 } 3722} ); 3723 3724 3725// Initialize a jQuery object 3726 3727 3728// A central reference to the root jQuery(document) 3729var rootjQuery, 3730 3731 // A simple way to check for HTML strings 3732 // Prioritize #id over <tag> to avoid XSS via location.hash (trac-9521) 3733 // Strict HTML recognition (trac-11290: must start with <) 3734 // Shortcut simple #id case for speed 3735 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 3736 3737 init = jQuery.fn.init = function( selector, context, root ) { 3738 var match, elem; 3739 3740 // HANDLE: $(""), $(null), $(undefined), $(false) 3741 if ( !selector ) { 3742 return this; 3743 } 3744 3745 // Method init() accepts an alternate rootjQuery 3746 // so migrate can support jQuery.sub (gh-2101) 3747 root = root || rootjQuery; 3748 3749 // Handle HTML strings 3750 if ( typeof selector === "string" ) { 3751 if ( selector[ 0 ] === "<" && 3752 selector[ selector.length - 1 ] === ">" && 3753 selector.length >= 3 ) { 3754 3755 // Assume that strings that start and end with <> are HTML and skip the regex check 3756 match = [ null, selector, null ]; 3757 3758 } else { 3759 match = rquickExpr.exec( selector ); 3760 } 3761 3762 // Match html or make sure no context is specified for #id 3763 if ( match && ( match[ 1 ] || !context ) ) { 3764 3765 // HANDLE: $(html) -> $(array) 3766 if ( match[ 1 ] ) { 3767 context = context instanceof jQuery ? context[ 0 ] : context; 3768 3769 // Option to run scripts is true for back-compat 3770 // Intentionally let the error be thrown if parseHTML is not present 3771 jQuery.merge( this, jQuery.parseHTML( 3772 match[ 1 ], 3773 context && context.nodeType ? context.ownerDocument || context : document, 3774 true 3775 ) ); 3776 3777 // HANDLE: $(html, props) 3778 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 3779 for ( match in context ) { 3780 3781 // Properties of context are called as methods if possible 3782 if ( isFunction( this[ match ] ) ) { 3783 this[ match ]( context[ match ] ); 3784 3785 // ...and otherwise set as attributes 3786 } else { 3787 this.attr( match, context[ match ] ); 3788 } 3789 } 3790 } 3791 3792 return this; 3793 3794 // HANDLE: $(#id) 3795 } else { 3796 elem = document.getElementById( match[ 2 ] ); 3797 3798 if ( elem ) { 3799 3800 // Inject the element directly into the jQuery object 3801 this[ 0 ] = elem; 3802 this.length = 1; 3803 } 3804 return this; 3805 } 3806 3807 // HANDLE: $(expr, $(...)) 3808 } else if ( !context || context.jquery ) { 3809 return ( context || root ).find( selector ); 3810 3811 // HANDLE: $(expr, context) 3812 // (which is just equivalent to: $(context).find(expr) 3813 } else { 3814 return this.constructor( context ).find( selector ); 3815 } 3816 3817 // HANDLE: $(DOMElement) 3818 } else if ( selector.nodeType ) { 3819 this[ 0 ] = selector; 3820 this.length = 1; 3821 return this; 3822 3823 // HANDLE: $(function) 3824 // Shortcut for document ready 3825 } else if ( isFunction( selector ) ) { 3826 return root.ready !== undefined ? 3827 root.ready( selector ) : 3828 3829 // Execute immediately if ready is not present 3830 selector( jQuery ); 3831 } 3832 3833 return jQuery.makeArray( selector, this ); 3834 }; 3835 3836// Give the init function the jQuery prototype for later instantiation 3837init.prototype = jQuery.fn; 3838 3839// Initialize central reference 3840rootjQuery = jQuery( document ); 3841 3842 3843var rparentsprev = /^(?:parents|prev(?:Until|All))/, 3844 3845 // Methods guaranteed to produce a unique set when starting from a unique set 3846 guaranteedUnique = { 3847 children: true, 3848 contents: true, 3849 next: true, 3850 prev: true 3851 }; 3852 3853jQuery.fn.extend( { 3854 has: function( target ) { 3855 var targets = jQuery( target, this ), 3856 l = targets.length; 3857 3858 return this.filter( function() { 3859 var i = 0; 3860 for ( ; i < l; i++ ) { 3861 if ( jQuery.contains( this, targets[ i ] ) ) { 3862 return true; 3863 } 3864 } 3865 } ); 3866 }, 3867 3868 closest: function( selectors, context ) { 3869 var cur, 3870 i = 0, 3871 l = this.length, 3872 matched = [], 3873 targets = typeof selectors !== "string" && jQuery( selectors ); 3874 3875 // Positional selectors never match, since there's no _selection_ context 3876 if ( !rneedsContext.test( selectors ) ) { 3877 for ( ; i < l; i++ ) { 3878 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 3879 3880 // Always skip document fragments 3881 if ( cur.nodeType < 11 && ( targets ? 3882 targets.index( cur ) > -1 : 3883 3884 // Don't pass non-elements to jQuery#find 3885 cur.nodeType === 1 && 3886 jQuery.find.matchesSelector( cur, selectors ) ) ) { 3887 3888 matched.push( cur ); 3889 break; 3890 } 3891 } 3892 } 3893 } 3894 3895 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 3896 }, 3897 3898 // Determine the position of an element within the set 3899 index: function( elem ) { 3900 3901 // No argument, return index in parent 3902 if ( !elem ) { 3903 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 3904 } 3905 3906 // Index in selector 3907 if ( typeof elem === "string" ) { 3908 return indexOf.call( jQuery( elem ), this[ 0 ] ); 3909 } 3910 3911 // Locate the position of the desired element 3912 return indexOf.call( this, 3913 3914 // If it receives a jQuery object, the first element is used 3915 elem.jquery ? elem[ 0 ] : elem 3916 ); 3917 }, 3918 3919 add: function( selector, context ) { 3920 return this.pushStack( 3921 jQuery.uniqueSort( 3922 jQuery.merge( this.get(), jQuery( selector, context ) ) 3923 ) 3924 ); 3925 }, 3926 3927 addBack: function( selector ) { 3928 return this.add( selector == null ? 3929 this.prevObject : this.prevObject.filter( selector ) 3930 ); 3931 } 3932} ); 3933 3934function sibling( cur, dir ) { 3935 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 3936 return cur; 3937} 3938 3939jQuery.each( { 3940 parent: function( elem ) { 3941 var parent = elem.parentNode; 3942 return parent && parent.nodeType !== 11 ? parent : null; 3943 }, 3944 parents: function( elem ) { 3945 return dir( elem, "parentNode" ); 3946 }, 3947 parentsUntil: function( elem, _i, until ) { 3948 return dir( elem, "parentNode", until ); 3949 }, 3950 next: function( elem ) { 3951 return sibling( elem, "nextSibling" ); 3952 }, 3953 prev: function( elem ) { 3954 return sibling( elem, "previousSibling" ); 3955 }, 3956 nextAll: function( elem ) { 3957 return dir( elem, "nextSibling" ); 3958 }, 3959 prevAll: function( elem ) { 3960 return dir( elem, "previousSibling" ); 3961 }, 3962 nextUntil: function( elem, _i, until ) { 3963 return dir( elem, "nextSibling", until ); 3964 }, 3965 prevUntil: function( elem, _i, until ) { 3966 return dir( elem, "previousSibling", until ); 3967 }, 3968 siblings: function( elem ) { 3969 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 3970 }, 3971 children: function( elem ) { 3972 return siblings( elem.firstChild ); 3973 }, 3974 contents: function( elem ) { 3975 if ( elem.contentDocument != null && 3976 3977 // Support: IE 11+ 3978 // <object> elements with no `data` attribute has an object 3979 // `contentDocument` with a `null` prototype. 3980 getProto( elem.contentDocument ) ) { 3981 3982 return elem.contentDocument; 3983 } 3984 3985 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 3986 // Treat the template element as a regular one in browsers that 3987 // don't support it. 3988 if ( nodeName( elem, "template" ) ) { 3989 elem = elem.content || elem; 3990 } 3991 3992 return jQuery.merge( [], elem.childNodes ); 3993 } 3994}, function( name, fn ) { 3995 jQuery.fn[ name ] = function( until, selector ) { 3996 var matched = jQuery.map( this, fn, until ); 3997 3998 if ( name.slice( -5 ) !== "Until" ) { 3999 selector = until; 4000 } 4001 4002 if ( selector && typeof selector === "string" ) { 4003 matched = jQuery.filter( selector, matched ); 4004 } 4005 4006 if ( this.length > 1 ) { 4007 4008 // Remove duplicates 4009 if ( !guaranteedUnique[ name ] ) { 4010 jQuery.uniqueSort( matched ); 4011 } 4012 4013 // Reverse order for parents* and prev-derivatives 4014 if ( rparentsprev.test( name ) ) { 4015 matched.reverse(); 4016 } 4017 } 4018 4019 return this.pushStack( matched ); 4020 }; 4021} ); 4022var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); 4023 4024 4025 4026// Convert String-formatted options into Object-formatted ones 4027function createOptions( options ) { 4028 var object = {}; 4029 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { 4030 object[ flag ] = true; 4031 } ); 4032 return object; 4033} 4034 4035/* 4036 * Create a callback list using the following parameters: 4037 * 4038 * options: an optional list of space-separated options that will change how 4039 * the callback list behaves or a more traditional option object 4040 * 4041 * By default a callback list will act like an event callback list and can be 4042 * "fired" multiple times. 4043 * 4044 * Possible options: 4045 * 4046 * once: will ensure the callback list can only be fired once (like a Deferred) 4047 * 4048 * memory: will keep track of previous values and will call any callback added 4049 * after the list has been fired right away with the latest "memorized" 4050 * values (like a Deferred) 4051 * 4052 * unique: will ensure a callback can only be added once (no duplicate in the list) 4053 * 4054 * stopOnFalse: interrupt callings when a callback returns false 4055 * 4056 */ 4057jQuery.Callbacks = function( options ) { 4058 4059 // Convert options from String-formatted to Object-formatted if needed 4060 // (we check in cache first) 4061 options = typeof options === "string" ? 4062 createOptions( options ) : 4063 jQuery.extend( {}, options ); 4064 4065 var // Flag to know if list is currently firing 4066 firing, 4067 4068 // Last fire value for non-forgettable lists 4069 memory, 4070 4071 // Flag to know if list was already fired 4072 fired, 4073 4074 // Flag to prevent firing 4075 locked, 4076 4077 // Actual callback list 4078 list = [], 4079 4080 // Queue of execution data for repeatable lists 4081 queue = [], 4082 4083 // Index of currently firing callback (modified by add/remove as needed) 4084 firingIndex = -1, 4085 4086 // Fire callbacks 4087 fire = function() { 4088 4089 // Enforce single-firing 4090 locked = locked || options.once; 4091 4092 // Execute callbacks for all pending executions, 4093 // respecting firingIndex overrides and runtime changes 4094 fired = firing = true; 4095 for ( ; queue.length; firingIndex = -1 ) { 4096 memory = queue.shift(); 4097 while ( ++firingIndex < list.length ) { 4098 4099 // Run callback and check for early termination 4100 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 4101 options.stopOnFalse ) { 4102 4103 // Jump to end and forget the data so .add doesn't re-fire 4104 firingIndex = list.length; 4105 memory = false; 4106 } 4107 } 4108 } 4109 4110 // Forget the data if we're done with it 4111 if ( !options.memory ) { 4112 memory = false; 4113 } 4114 4115 firing = false; 4116 4117 // Clean up if we're done firing for good 4118 if ( locked ) { 4119 4120 // Keep an empty list if we have data for future add calls 4121 if ( memory ) { 4122 list = []; 4123 4124 // Otherwise, this object is spent 4125 } else { 4126 list = ""; 4127 } 4128 } 4129 }, 4130 4131 // Actual Callbacks object 4132 self = { 4133 4134 // Add a callback or a collection of callbacks to the list 4135 add: function() { 4136 if ( list ) { 4137 4138 // If we have memory from a past run, we should fire after adding 4139 if ( memory && !firing ) { 4140 firingIndex = list.length - 1; 4141 queue.push( memory ); 4142 } 4143 4144 ( function add( args ) { 4145 jQuery.each( args, function( _, arg ) { 4146 if ( isFunction( arg ) ) { 4147 if ( !options.unique || !self.has( arg ) ) { 4148 list.push( arg ); 4149 } 4150 } else if ( arg && arg.length && toType( arg ) !== "string" ) { 4151 4152 // Inspect recursively 4153 add( arg ); 4154 } 4155 } ); 4156 } )( arguments ); 4157 4158 if ( memory && !firing ) { 4159 fire(); 4160 } 4161 } 4162 return this; 4163 }, 4164 4165 // Remove a callback from the list 4166 remove: function() { 4167 jQuery.each( arguments, function( _, arg ) { 4168 var index; 4169 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 4170 list.splice( index, 1 ); 4171 4172 // Handle firing indexes 4173 if ( index <= firingIndex ) { 4174 firingIndex--; 4175 } 4176 } 4177 } ); 4178 return this; 4179 }, 4180 4181 // Check if a given callback is in the list. 4182 // If no argument is given, return whether or not list has callbacks attached. 4183 has: function( fn ) { 4184 return fn ? 4185 jQuery.inArray( fn, list ) > -1 : 4186 list.length > 0; 4187 }, 4188 4189 // Remove all callbacks from the list 4190 empty: function() { 4191 if ( list ) { 4192 list = []; 4193 } 4194 return this; 4195 }, 4196 4197 // Disable .fire and .add 4198 // Abort any current/pending executions 4199 // Clear all callbacks and values 4200 disable: function() { 4201 locked = queue = []; 4202 list = memory = ""; 4203 return this; 4204 }, 4205 disabled: function() { 4206 return !list; 4207 }, 4208 4209 // Disable .fire 4210 // Also disable .add unless we have memory (since it would have no effect) 4211 // Abort any pending executions 4212 lock: function() { 4213 locked = queue = []; 4214 if ( !memory && !firing ) { 4215 list = memory = ""; 4216 } 4217 return this; 4218 }, 4219 locked: function() { 4220 return !!locked; 4221 }, 4222 4223 // Call all callbacks with the given context and arguments 4224 fireWith: function( context, args ) { 4225 if ( !locked ) { 4226 args = args || []; 4227 args = [ context, args.slice ? args.slice() : args ]; 4228 queue.push( args ); 4229 if ( !firing ) { 4230 fire(); 4231 } 4232 } 4233 return this; 4234 }, 4235 4236 // Call all the callbacks with the given arguments 4237 fire: function() { 4238 self.fireWith( this, arguments ); 4239 return this; 4240 }, 4241 4242 // To know if the callbacks have already been called at least once 4243 fired: function() { 4244 return !!fired; 4245 } 4246 }; 4247 4248 return self; 4249}; 4250 4251 4252function Identity( v ) { 4253 return v; 4254} 4255function Thrower( ex ) { 4256 throw ex; 4257} 4258 4259function adoptValue( value, resolve, reject, noValue ) { 4260 var method; 4261 4262 try { 4263 4264 // Check for promise aspect first to privilege synchronous behavior 4265 if ( value && isFunction( ( method = value.promise ) ) ) { 4266 method.call( value ).done( resolve ).fail( reject ); 4267 4268 // Other thenables 4269 } else if ( value && isFunction( ( method = value.then ) ) ) { 4270 method.call( value, resolve, reject ); 4271 4272 // Other non-thenables 4273 } else { 4274 4275 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 4276 // * false: [ value ].slice( 0 ) => resolve( value ) 4277 // * true: [ value ].slice( 1 ) => resolve() 4278 resolve.apply( undefined, [ value ].slice( noValue ) ); 4279 } 4280 4281 // For Promises/A+, convert exceptions into rejections 4282 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 4283 // Deferred#then to conditionally suppress rejection. 4284 } catch ( value ) { 4285 4286 // Support: Android 4.0 only 4287 // Strict mode functions invoked without .call/.apply get global-object context 4288 reject.apply( undefined, [ value ] ); 4289 } 4290} 4291 4292jQuery.extend( { 4293 4294 Deferred: function( func ) { 4295 var tuples = [ 4296 4297 // action, add listener, callbacks, 4298 // ... .then handlers, argument index, [final state] 4299 [ "notify", "progress", jQuery.Callbacks( "memory" ), 4300 jQuery.Callbacks( "memory" ), 2 ], 4301 [ "resolve", "done", jQuery.Callbacks( "once memory" ), 4302 jQuery.Callbacks( "once memory" ), 0, "resolved" ], 4303 [ "reject", "fail", jQuery.Callbacks( "once memory" ), 4304 jQuery.Callbacks( "once memory" ), 1, "rejected" ] 4305 ], 4306 state = "pending", 4307 promise = { 4308 state: function() { 4309 return state; 4310 }, 4311 always: function() { 4312 deferred.done( arguments ).fail( arguments ); 4313 return this; 4314 }, 4315 "catch": function( fn ) { 4316 return promise.then( null, fn ); 4317 }, 4318 4319 // Keep pipe for back-compat 4320 pipe: function( /* fnDone, fnFail, fnProgress */ ) { 4321 var fns = arguments; 4322 4323 return jQuery.Deferred( function( newDefer ) { 4324 jQuery.each( tuples, function( _i, tuple ) { 4325 4326 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 4327 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; 4328 4329 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 4330 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 4331 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 4332 deferred[ tuple[ 1 ] ]( function() { 4333 var returned = fn && fn.apply( this, arguments ); 4334 if ( returned && isFunction( returned.promise ) ) { 4335 returned.promise() 4336 .progress( newDefer.notify ) 4337 .done( newDefer.resolve ) 4338 .fail( newDefer.reject ); 4339 } else { 4340 newDefer[ tuple[ 0 ] + "With" ]( 4341 this, 4342 fn ? [ returned ] : arguments 4343 ); 4344 } 4345 } ); 4346 } ); 4347 fns = null; 4348 } ).promise(); 4349 }, 4350 then: function( onFulfilled, onRejected, onProgress ) { 4351 var maxDepth = 0; 4352 function resolve( depth, deferred, handler, special ) { 4353 return function() { 4354 var that = this, 4355 args = arguments, 4356 mightThrow = function() { 4357 var returned, then; 4358 4359 // Support: Promises/A+ section 2.3.3.3.3 4360 // https://promisesaplus.com/#point-59 4361 // Ignore double-resolution attempts 4362 if ( depth < maxDepth ) { 4363 return; 4364 } 4365 4366 returned = handler.apply( that, args ); 4367 4368 // Support: Promises/A+ section 2.3.1 4369 // https://promisesaplus.com/#point-48 4370 if ( returned === deferred.promise() ) { 4371 throw new TypeError( "Thenable self-resolution" ); 4372 } 4373 4374 // Support: Promises/A+ sections 2.3.3.1, 3.5 4375 // https://promisesaplus.com/#point-54 4376 // https://promisesaplus.com/#point-75 4377 // Retrieve `then` only once 4378 then = returned && 4379 4380 // Support: Promises/A+ section 2.3.4 4381 // https://promisesaplus.com/#point-64 4382 // Only check objects and functions for thenability 4383 ( typeof returned === "object" || 4384 typeof returned === "function" ) && 4385 returned.then; 4386 4387 // Handle a returned thenable 4388 if ( isFunction( then ) ) { 4389 4390 // Special processors (notify) just wait for resolution 4391 if ( special ) { 4392 then.call( 4393 returned, 4394 resolve( maxDepth, deferred, Identity, special ), 4395 resolve( maxDepth, deferred, Thrower, special ) 4396 ); 4397 4398 // Normal processors (resolve) also hook into progress 4399 } else { 4400 4401 // ...and disregard older resolution values 4402 maxDepth++; 4403 4404 then.call( 4405 returned, 4406 resolve( maxDepth, deferred, Identity, special ), 4407 resolve( maxDepth, deferred, Thrower, special ), 4408 resolve( maxDepth, deferred, Identity, 4409 deferred.notifyWith ) 4410 ); 4411 } 4412 4413 // Handle all other returned values 4414 } else { 4415 4416 // Only substitute handlers pass on context 4417 // and multiple values (non-spec behavior) 4418 if ( handler !== Identity ) { 4419 that = undefined; 4420 args = [ returned ]; 4421 } 4422 4423 // Process the value(s) 4424 // Default process is resolve 4425 ( special || deferred.resolveWith )( that, args ); 4426 } 4427 }, 4428 4429 // Only normal processors (resolve) catch and reject exceptions 4430 process = special ? 4431 mightThrow : 4432 function() { 4433 try { 4434 mightThrow(); 4435 } catch ( e ) { 4436 4437 if ( jQuery.Deferred.exceptionHook ) { 4438 jQuery.Deferred.exceptionHook( e, 4439 process.error ); 4440 } 4441 4442 // Support: Promises/A+ section 2.3.3.3.4.1 4443 // https://promisesaplus.com/#point-61 4444 // Ignore post-resolution exceptions 4445 if ( depth + 1 >= maxDepth ) { 4446 4447 // Only substitute handlers pass on context 4448 // and multiple values (non-spec behavior) 4449 if ( handler !== Thrower ) { 4450 that = undefined; 4451 args = [ e ]; 4452 } 4453 4454 deferred.rejectWith( that, args ); 4455 } 4456 } 4457 }; 4458 4459 // Support: Promises/A+ section 2.3.3.3.1 4460 // https://promisesaplus.com/#point-57 4461 // Re-resolve promises immediately to dodge false rejection from 4462 // subsequent errors 4463 if ( depth ) { 4464 process(); 4465 } else { 4466 4467 // Call an optional hook to record the error, in case of exception 4468 // since it's otherwise lost when execution goes async 4469 if ( jQuery.Deferred.getErrorHook ) { 4470 process.error = jQuery.Deferred.getErrorHook(); 4471 4472 // The deprecated alias of the above. While the name suggests 4473 // returning the stack, not an error instance, jQuery just passes 4474 // it directly to `console.warn` so both will work; an instance 4475 // just better cooperates with source maps. 4476 } else if ( jQuery.Deferred.getStackHook ) { 4477 process.error = jQuery.Deferred.getStackHook(); 4478 } 4479 window.setTimeout( process ); 4480 } 4481 }; 4482 } 4483 4484 return jQuery.Deferred( function( newDefer ) { 4485 4486 // progress_handlers.add( ... ) 4487 tuples[ 0 ][ 3 ].add( 4488 resolve( 4489 0, 4490 newDefer, 4491 isFunction( onProgress ) ? 4492 onProgress : 4493 Identity, 4494 newDefer.notifyWith 4495 ) 4496 ); 4497 4498 // fulfilled_handlers.add( ... ) 4499 tuples[ 1 ][ 3 ].add( 4500 resolve( 4501 0, 4502 newDefer, 4503 isFunction( onFulfilled ) ? 4504 onFulfilled : 4505 Identity 4506 ) 4507 ); 4508 4509 // rejected_handlers.add( ... ) 4510 tuples[ 2 ][ 3 ].add( 4511 resolve( 4512 0, 4513 newDefer, 4514 isFunction( onRejected ) ? 4515 onRejected : 4516 Thrower 4517 ) 4518 ); 4519 } ).promise(); 4520 }, 4521 4522 // Get a promise for this deferred 4523 // If obj is provided, the promise aspect is added to the object 4524 promise: function( obj ) { 4525 return obj != null ? jQuery.extend( obj, promise ) : promise; 4526 } 4527 }, 4528 deferred = {}; 4529 4530 // Add list-specific methods 4531 jQuery.each( tuples, function( i, tuple ) { 4532 var list = tuple[ 2 ], 4533 stateString = tuple[ 5 ]; 4534 4535 // promise.progress = list.add 4536 // promise.done = list.add 4537 // promise.fail = list.add 4538 promise[ tuple[ 1 ] ] = list.add; 4539 4540 // Handle state 4541 if ( stateString ) { 4542 list.add( 4543 function() { 4544 4545 // state = "resolved" (i.e., fulfilled) 4546 // state = "rejected" 4547 state = stateString; 4548 }, 4549 4550 // rejected_callbacks.disable 4551 // fulfilled_callbacks.disable 4552 tuples[ 3 - i ][ 2 ].disable, 4553 4554 // rejected_handlers.disable 4555 // fulfilled_handlers.disable 4556 tuples[ 3 - i ][ 3 ].disable, 4557 4558 // progress_callbacks.lock 4559 tuples[ 0 ][ 2 ].lock, 4560 4561 // progress_handlers.lock 4562 tuples[ 0 ][ 3 ].lock 4563 ); 4564 } 4565 4566 // progress_handlers.fire 4567 // fulfilled_handlers.fire 4568 // rejected_handlers.fire 4569 list.add( tuple[ 3 ].fire ); 4570 4571 // deferred.notify = function() { deferred.notifyWith(...) } 4572 // deferred.resolve = function() { deferred.resolveWith(...) } 4573 // deferred.reject = function() { deferred.rejectWith(...) } 4574 deferred[ tuple[ 0 ] ] = function() { 4575 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); 4576 return this; 4577 }; 4578 4579 // deferred.notifyWith = list.fireWith 4580 // deferred.resolveWith = list.fireWith 4581 // deferred.rejectWith = list.fireWith 4582 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 4583 } ); 4584 4585 // Make the deferred a promise 4586 promise.promise( deferred ); 4587 4588 // Call given func if any 4589 if ( func ) { 4590 func.call( deferred, deferred ); 4591 } 4592 4593 // All done! 4594 return deferred; 4595 }, 4596 4597 // Deferred helper 4598 when: function( singleValue ) { 4599 var 4600 4601 // count of uncompleted subordinates 4602 remaining = arguments.length, 4603 4604 // count of unprocessed arguments 4605 i = remaining, 4606 4607 // subordinate fulfillment data 4608 resolveContexts = Array( i ), 4609 resolveValues = slice.call( arguments ), 4610 4611 // the primary Deferred 4612 primary = jQuery.Deferred(), 4613 4614 // subordinate callback factory 4615 updateFunc = function( i ) { 4616 return function( value ) { 4617 resolveContexts[ i ] = this; 4618 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 4619 if ( !( --remaining ) ) { 4620 primary.resolveWith( resolveContexts, resolveValues ); 4621 } 4622 }; 4623 }; 4624 4625 // Single- and empty arguments are adopted like Promise.resolve 4626 if ( remaining <= 1 ) { 4627 adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, 4628 !remaining ); 4629 4630 // Use .then() to unwrap secondary thenables (cf. gh-3000) 4631 if ( primary.state() === "pending" || 4632 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { 4633 4634 return primary.then(); 4635 } 4636 } 4637 4638 // Multiple arguments are aggregated like Promise.all array elements 4639 while ( i-- ) { 4640 adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); 4641 } 4642 4643 return primary.promise(); 4644 } 4645} ); 4646 4647 4648// These usually indicate a programmer mistake during development, 4649// warn about them ASAP rather than swallowing them by default. 4650var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 4651 4652// If `jQuery.Deferred.getErrorHook` is defined, `asyncError` is an error 4653// captured before the async barrier to get the original error cause 4654// which may otherwise be hidden. 4655jQuery.Deferred.exceptionHook = function( error, asyncError ) { 4656 4657 // Support: IE 8 - 9 only 4658 // Console exists when dev tools are open, which can happen at any time 4659 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { 4660 window.console.warn( "jQuery.Deferred exception: " + error.message, 4661 error.stack, asyncError ); 4662 } 4663}; 4664 4665 4666 4667 4668jQuery.readyException = function( error ) { 4669 window.setTimeout( function() { 4670 throw error; 4671 } ); 4672}; 4673 4674 4675 4676 4677// The deferred used on DOM ready 4678var readyList = jQuery.Deferred(); 4679 4680jQuery.fn.ready = function( fn ) { 4681 4682 readyList 4683 .then( fn ) 4684 4685 // Wrap jQuery.readyException in a function so that the lookup 4686 // happens at the time of error handling instead of callback 4687 // registration. 4688 .catch( function( error ) { 4689 jQuery.readyException( error ); 4690 } ); 4691 4692 return this; 4693}; 4694 4695jQuery.extend( { 4696 4697 // Is the DOM ready to be used? Set to true once it occurs. 4698 isReady: false, 4699 4700 // A counter to track how many items to wait for before 4701 // the ready event fires. See trac-6781 4702 readyWait: 1, 4703 4704 // Handle when the DOM is ready 4705 ready: function( wait ) { 4706 4707 // Abort if there are pending holds or we're already ready 4708 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 4709 return; 4710 } 4711 4712 // Remember that the DOM is ready 4713 jQuery.isReady = true; 4714 4715 // If a normal DOM Ready event fired, decrement, and wait if need be 4716 if ( wait !== true && --jQuery.readyWait > 0 ) { 4717 return; 4718 } 4719 4720 // If there are functions bound, to execute 4721 readyList.resolveWith( document, [ jQuery ] ); 4722 } 4723} ); 4724 4725jQuery.ready.then = readyList.then; 4726 4727// The ready event handler and self cleanup method 4728function completed() { 4729 document.removeEventListener( "DOMContentLoaded", completed ); 4730 window.removeEventListener( "load", completed ); 4731 jQuery.ready(); 4732} 4733 4734// Catch cases where $(document).ready() is called 4735// after the browser event has already occurred. 4736// Support: IE <=9 - 10 only 4737// Older IE sometimes signals "interactive" too soon 4738if ( document.readyState === "complete" || 4739 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 4740 4741 // Handle it asynchronously to allow scripts the opportunity to delay ready 4742 window.setTimeout( jQuery.ready ); 4743 4744} else { 4745 4746 // Use the handy event callback 4747 document.addEventListener( "DOMContentLoaded", completed ); 4748 4749 // A fallback to window.onload, that will always work 4750 window.addEventListener( "load", completed ); 4751} 4752 4753 4754 4755 4756// Multifunctional method to get and set values of a collection 4757// The value/s can optionally be executed if it's a function 4758var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 4759 var i = 0, 4760 len = elems.length, 4761 bulk = key == null; 4762 4763 // Sets many values 4764 if ( toType( key ) === "object" ) { 4765 chainable = true; 4766 for ( i in key ) { 4767 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 4768 } 4769 4770 // Sets one value 4771 } else if ( value !== undefined ) { 4772 chainable = true; 4773 4774 if ( !isFunction( value ) ) { 4775 raw = true; 4776 } 4777 4778 if ( bulk ) { 4779 4780 // Bulk operations run against the entire set 4781 if ( raw ) { 4782 fn.call( elems, value ); 4783 fn = null; 4784 4785 // ...except when executing function values 4786 } else { 4787 bulk = fn; 4788 fn = function( elem, _key, value ) { 4789 return bulk.call( jQuery( elem ), value ); 4790 }; 4791 } 4792 } 4793 4794 if ( fn ) { 4795 for ( ; i < len; i++ ) { 4796 fn( 4797 elems[ i ], key, raw ? 4798 value : 4799 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 4800 ); 4801 } 4802 } 4803 } 4804 4805 if ( chainable ) { 4806 return elems; 4807 } 4808 4809 // Gets 4810 if ( bulk ) { 4811 return fn.call( elems ); 4812 } 4813 4814 return len ? fn( elems[ 0 ], key ) : emptyGet; 4815}; 4816 4817 4818// Matches dashed string for camelizing 4819var rmsPrefix = /^-ms-/, 4820 rdashAlpha = /-([a-z])/g; 4821 4822// Used by camelCase as callback to replace() 4823function fcamelCase( _all, letter ) { 4824 return letter.toUpperCase(); 4825} 4826 4827// Convert dashed to camelCase; used by the css and data modules 4828// Support: IE <=9 - 11, Edge 12 - 15 4829// Microsoft forgot to hump their vendor prefix (trac-9572) 4830function camelCase( string ) { 4831 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 4832} 4833var acceptData = function( owner ) { 4834 4835 // Accepts only: 4836 // - Node 4837 // - Node.ELEMENT_NODE 4838 // - Node.DOCUMENT_NODE 4839 // - Object 4840 // - Any 4841 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 4842}; 4843 4844 4845 4846 4847function Data() { 4848 this.expando = jQuery.expando + Data.uid++; 4849} 4850 4851Data.uid = 1; 4852 4853Data.prototype = { 4854 4855 cache: function( owner ) { 4856 4857 // Check if the owner object already has a cache 4858 var value = owner[ this.expando ]; 4859 4860 // If not, create one 4861 if ( !value ) { 4862 value = {}; 4863 4864 // We can accept data for non-element nodes in modern browsers, 4865 // but we should not, see trac-8335. 4866 // Always return an empty object. 4867 if ( acceptData( owner ) ) { 4868 4869 // If it is a node unlikely to be stringify-ed or looped over 4870 // use plain assignment 4871 if ( owner.nodeType ) { 4872 owner[ this.expando ] = value; 4873 4874 // Otherwise secure it in a non-enumerable property 4875 // configurable must be true to allow the property to be 4876 // deleted when data is removed 4877 } else { 4878 Object.defineProperty( owner, this.expando, { 4879 value: value, 4880 configurable: true 4881 } ); 4882 } 4883 } 4884 } 4885 4886 return value; 4887 }, 4888 set: function( owner, data, value ) { 4889 var prop, 4890 cache = this.cache( owner ); 4891 4892 // Handle: [ owner, key, value ] args 4893 // Always use camelCase key (gh-2257) 4894 if ( typeof data === "string" ) { 4895 cache[ camelCase( data ) ] = value; 4896 4897 // Handle: [ owner, { properties } ] args 4898 } else { 4899 4900 // Copy the properties one-by-one to the cache object 4901 for ( prop in data ) { 4902 cache[ camelCase( prop ) ] = data[ prop ]; 4903 } 4904 } 4905 return cache; 4906 }, 4907 get: function( owner, key ) { 4908 return key === undefined ? 4909 this.cache( owner ) : 4910 4911 // Always use camelCase key (gh-2257) 4912 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; 4913 }, 4914 access: function( owner, key, value ) { 4915 4916 // In cases where either: 4917 // 4918 // 1. No key was specified 4919 // 2. A string key was specified, but no value provided 4920 // 4921 // Take the "read" path and allow the get method to determine 4922 // which value to return, respectively either: 4923 // 4924 // 1. The entire cache object 4925 // 2. The data stored at the key 4926 // 4927 if ( key === undefined || 4928 ( ( key && typeof key === "string" ) && value === undefined ) ) { 4929 4930 return this.get( owner, key ); 4931 } 4932 4933 // When the key is not a string, or both a key and value 4934 // are specified, set or extend (existing objects) with either: 4935 // 4936 // 1. An object of properties 4937 // 2. A key and value 4938 // 4939 this.set( owner, key, value ); 4940 4941 // Since the "set" path can have two possible entry points 4942 // return the expected data based on which path was taken[*] 4943 return value !== undefined ? value : key; 4944 }, 4945 remove: function( owner, key ) { 4946 var i, 4947 cache = owner[ this.expando ]; 4948 4949 if ( cache === undefined ) { 4950 return; 4951 } 4952 4953 if ( key !== undefined ) { 4954 4955 // Support array or space separated string of keys 4956 if ( Array.isArray( key ) ) { 4957 4958 // If key is an array of keys... 4959 // We always set camelCase keys, so remove that. 4960 key = key.map( camelCase ); 4961 } else { 4962 key = camelCase( key ); 4963 4964 // If a key with the spaces exists, use it. 4965 // Otherwise, create an array by matching non-whitespace 4966 key = key in cache ? 4967 [ key ] : 4968 ( key.match( rnothtmlwhite ) || [] ); 4969 } 4970 4971 i = key.length; 4972 4973 while ( i-- ) { 4974 delete cache[ key[ i ] ]; 4975 } 4976 } 4977 4978 // Remove the expando if there's no more data 4979 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 4980 4981 // Support: Chrome <=35 - 45 4982 // Webkit & Blink performance suffers when deleting properties 4983 // from DOM nodes, so set to undefined instead 4984 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 4985 if ( owner.nodeType ) { 4986 owner[ this.expando ] = undefined; 4987 } else { 4988 delete owner[ this.expando ]; 4989 } 4990 } 4991 }, 4992 hasData: function( owner ) { 4993 var cache = owner[ this.expando ]; 4994 return cache !== undefined && !jQuery.isEmptyObject( cache ); 4995 } 4996}; 4997var dataPriv = new Data(); 4998 4999var dataUser = new Data(); 5000 5001 5002 5003// Implementation Summary 5004// 5005// 1. Enforce API surface and semantic compatibility with 1.9.x branch 5006// 2. Improve the module's maintainability by reducing the storage 5007// paths to a single mechanism. 5008// 3. Use the same single mechanism to support "private" and "user" data. 5009// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 5010// 5. Avoid exposing implementation details on user objects (eg. expando properties) 5011// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 5012 5013var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 5014 rmultiDash = /[A-Z]/g; 5015 5016function getData( data ) { 5017 if ( data === "true" ) { 5018 return true; 5019 } 5020 5021 if ( data === "false" ) { 5022 return false; 5023 } 5024 5025 if ( data === "null" ) { 5026 return null; 5027 } 5028 5029 // Only convert to a number if it doesn't change the string 5030 if ( data === +data + "" ) { 5031 return +data; 5032 } 5033 5034 if ( rbrace.test( data ) ) { 5035 return JSON.parse( data ); 5036 } 5037 5038 return data; 5039} 5040 5041function dataAttr( elem, key, data ) { 5042 var name; 5043 5044 // If nothing was found internally, try to fetch any 5045 // data from the HTML5 data-* attribute 5046 if ( data === undefined && elem.nodeType === 1 ) { 5047 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 5048 data = elem.getAttribute( name ); 5049 5050 if ( typeof data === "string" ) { 5051 try { 5052 data = getData( data ); 5053 } catch ( e ) {} 5054 5055 // Make sure we set the data so it isn't changed later 5056 dataUser.set( elem, key, data ); 5057 } else { 5058 data = undefined; 5059 } 5060 } 5061 return data; 5062} 5063 5064jQuery.extend( { 5065 hasData: function( elem ) { 5066 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 5067 }, 5068 5069 data: function( elem, name, data ) { 5070 return dataUser.access( elem, name, data ); 5071 }, 5072 5073 removeData: function( elem, name ) { 5074 dataUser.remove( elem, name ); 5075 }, 5076 5077 // TODO: Now that all calls to _data and _removeData have been replaced 5078 // with direct calls to dataPriv methods, these can be deprecated. 5079 _data: function( elem, name, data ) { 5080 return dataPriv.access( elem, name, data ); 5081 }, 5082 5083 _removeData: function( elem, name ) { 5084 dataPriv.remove( elem, name ); 5085 } 5086} ); 5087 5088jQuery.fn.extend( { 5089 data: function( key, value ) { 5090 var i, name, data, 5091 elem = this[ 0 ], 5092 attrs = elem && elem.attributes; 5093 5094 // Gets all values 5095 if ( key === undefined ) { 5096 if ( this.length ) { 5097 data = dataUser.get( elem ); 5098 5099 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 5100 i = attrs.length; 5101 while ( i-- ) { 5102 5103 // Support: IE 11 only 5104 // The attrs elements can be null (trac-14894) 5105 if ( attrs[ i ] ) { 5106 name = attrs[ i ].name; 5107 if ( name.indexOf( "data-" ) === 0 ) { 5108 name = camelCase( name.slice( 5 ) ); 5109 dataAttr( elem, name, data[ name ] ); 5110 } 5111 } 5112 } 5113 dataPriv.set( elem, "hasDataAttrs", true ); 5114 } 5115 } 5116 5117 return data; 5118 } 5119 5120 // Sets multiple values 5121 if ( typeof key === "object" ) { 5122 return this.each( function() { 5123 dataUser.set( this, key ); 5124 } ); 5125 } 5126 5127 return access( this, function( value ) { 5128 var data; 5129 5130 // The calling jQuery object (element matches) is not empty 5131 // (and therefore has an element appears at this[ 0 ]) and the 5132 // `value` parameter was not undefined. An empty jQuery object 5133 // will result in `undefined` for elem = this[ 0 ] which will 5134 // throw an exception if an attempt to read a data cache is made. 5135 if ( elem && value === undefined ) { 5136 5137 // Attempt to get data from the cache 5138 // The key will always be camelCased in Data 5139 data = dataUser.get( elem, key ); 5140 if ( data !== undefined ) { 5141 return data; 5142 } 5143 5144 // Attempt to "discover" the data in 5145 // HTML5 custom data-* attrs 5146 data = dataAttr( elem, key ); 5147 if ( data !== undefined ) { 5148 return data; 5149 } 5150 5151 // We tried really hard, but the data doesn't exist. 5152 return; 5153 } 5154 5155 // Set the data... 5156 this.each( function() { 5157 5158 // We always store the camelCased key 5159 dataUser.set( this, key, value ); 5160 } ); 5161 }, null, value, arguments.length > 1, null, true ); 5162 }, 5163 5164 removeData: function( key ) { 5165 return this.each( function() { 5166 dataUser.remove( this, key ); 5167 } ); 5168 } 5169} ); 5170 5171 5172jQuery.extend( { 5173 queue: function( elem, type, data ) { 5174 var queue; 5175 5176 if ( elem ) { 5177 type = ( type || "fx" ) + "queue"; 5178 queue = dataPriv.get( elem, type ); 5179 5180 // Speed up dequeue by getting out quickly if this is just a lookup 5181 if ( data ) { 5182 if ( !queue || Array.isArray( data ) ) { 5183 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 5184 } else { 5185 queue.push( data ); 5186 } 5187 } 5188 return queue || []; 5189 } 5190 }, 5191 5192 dequeue: function( elem, type ) { 5193 type = type || "fx"; 5194 5195 var queue = jQuery.queue( elem, type ), 5196 startLength = queue.length, 5197 fn = queue.shift(), 5198 hooks = jQuery._queueHooks( elem, type ), 5199 next = function() { 5200 jQuery.dequeue( elem, type ); 5201 }; 5202 5203 // If the fx queue is dequeued, always remove the progress sentinel 5204 if ( fn === "inprogress" ) { 5205 fn = queue.shift(); 5206 startLength--; 5207 } 5208 5209 if ( fn ) { 5210 5211 // Add a progress sentinel to prevent the fx queue from being 5212 // automatically dequeued 5213 if ( type === "fx" ) { 5214 queue.unshift( "inprogress" ); 5215 } 5216 5217 // Clear up the last queue stop function 5218 delete hooks.stop; 5219 fn.call( elem, next, hooks ); 5220 } 5221 5222 if ( !startLength && hooks ) { 5223 hooks.empty.fire(); 5224 } 5225 }, 5226 5227 // Not public - generate a queueHooks object, or return the current one 5228 _queueHooks: function( elem, type ) { 5229 var key = type + "queueHooks"; 5230 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 5231 empty: jQuery.Callbacks( "once memory" ).add( function() { 5232 dataPriv.remove( elem, [ type + "queue", key ] ); 5233 } ) 5234 } ); 5235 } 5236} ); 5237 5238jQuery.fn.extend( { 5239 queue: function( type, data ) { 5240 var setter = 2; 5241 5242 if ( typeof type !== "string" ) { 5243 data = type; 5244 type = "fx"; 5245 setter--; 5246 } 5247 5248 if ( arguments.length < setter ) { 5249 return jQuery.queue( this[ 0 ], type ); 5250 } 5251 5252 return data === undefined ? 5253 this : 5254 this.each( function() { 5255 var queue = jQuery.queue( this, type, data ); 5256 5257 // Ensure a hooks for this queue 5258 jQuery._queueHooks( this, type ); 5259 5260 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 5261 jQuery.dequeue( this, type ); 5262 } 5263 } ); 5264 }, 5265 dequeue: function( type ) { 5266 return this.each( function() { 5267 jQuery.dequeue( this, type ); 5268 } ); 5269 }, 5270 clearQueue: function( type ) { 5271 return this.queue( type || "fx", [] ); 5272 }, 5273 5274 // Get a promise resolved when queues of a certain type 5275 // are emptied (fx is the type by default) 5276 promise: function( type, obj ) { 5277 var tmp, 5278 count = 1, 5279 defer = jQuery.Deferred(), 5280 elements = this, 5281 i = this.length, 5282 resolve = function() { 5283 if ( !( --count ) ) { 5284 defer.resolveWith( elements, [ elements ] ); 5285 } 5286 }; 5287 5288 if ( typeof type !== "string" ) { 5289 obj = type; 5290 type = undefined; 5291 } 5292 type = type || "fx"; 5293 5294 while ( i-- ) { 5295 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 5296 if ( tmp && tmp.empty ) { 5297 count++; 5298 tmp.empty.add( resolve ); 5299 } 5300 } 5301 resolve(); 5302 return defer.promise( obj ); 5303 } 5304} ); 5305var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 5306 5307var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 5308 5309 5310var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 5311 5312var documentElement = document.documentElement; 5313 5314 5315 5316 var isAttached = function( elem ) { 5317 return jQuery.contains( elem.ownerDocument, elem ); 5318 }, 5319 composed = { composed: true }; 5320 5321 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only 5322 // Check attachment across shadow DOM boundaries when possible (gh-3504) 5323 // Support: iOS 10.0-10.2 only 5324 // Early iOS 10 versions support `attachShadow` but not `getRootNode`, 5325 // leading to errors. We need to check for `getRootNode`. 5326 if ( documentElement.getRootNode ) { 5327 isAttached = function( elem ) { 5328 return jQuery.contains( elem.ownerDocument, elem ) || 5329 elem.getRootNode( composed ) === elem.ownerDocument; 5330 }; 5331 } 5332var isHiddenWithinTree = function( elem, el ) { 5333 5334 // isHiddenWithinTree might be called from jQuery#filter function; 5335 // in that case, element will be second argument 5336 elem = el || elem; 5337 5338 // Inline style trumps all 5339 return elem.style.display === "none" || 5340 elem.style.display === "" && 5341 5342 // Otherwise, check computed style 5343 // Support: Firefox <=43 - 45 5344 // Disconnected elements can have computed display: none, so first confirm that elem is 5345 // in the document. 5346 isAttached( elem ) && 5347 5348 jQuery.css( elem, "display" ) === "none"; 5349 }; 5350 5351 5352 5353function adjustCSS( elem, prop, valueParts, tween ) { 5354 var adjusted, scale, 5355 maxIterations = 20, 5356 currentValue = tween ? 5357 function() { 5358 return tween.cur(); 5359 } : 5360 function() { 5361 return jQuery.css( elem, prop, "" ); 5362 }, 5363 initial = currentValue(), 5364 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 5365 5366 // Starting value computation is required for potential unit mismatches 5367 initialInUnit = elem.nodeType && 5368 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 5369 rcssNum.exec( jQuery.css( elem, prop ) ); 5370 5371 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 5372 5373 // Support: Firefox <=54 5374 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 5375 initial = initial / 2; 5376 5377 // Trust units reported by jQuery.css 5378 unit = unit || initialInUnit[ 3 ]; 5379 5380 // Iteratively approximate from a nonzero starting point 5381 initialInUnit = +initial || 1; 5382 5383 while ( maxIterations-- ) { 5384 5385 // Evaluate and update our best guess (doubling guesses that zero out). 5386 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 5387 jQuery.style( elem, prop, initialInUnit + unit ); 5388 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { 5389 maxIterations = 0; 5390 } 5391 initialInUnit = initialInUnit / scale; 5392 5393 } 5394 5395 initialInUnit = initialInUnit * 2; 5396 jQuery.style( elem, prop, initialInUnit + unit ); 5397 5398 // Make sure we update the tween properties later on 5399 valueParts = valueParts || []; 5400 } 5401 5402 if ( valueParts ) { 5403 initialInUnit = +initialInUnit || +initial || 0; 5404 5405 // Apply relative offset (+=/-=) if specified 5406 adjusted = valueParts[ 1 ] ? 5407 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 5408 +valueParts[ 2 ]; 5409 if ( tween ) { 5410 tween.unit = unit; 5411 tween.start = initialInUnit; 5412 tween.end = adjusted; 5413 } 5414 } 5415 return adjusted; 5416} 5417 5418 5419var defaultDisplayMap = {}; 5420 5421function getDefaultDisplay( elem ) { 5422 var temp, 5423 doc = elem.ownerDocument, 5424 nodeName = elem.nodeName, 5425 display = defaultDisplayMap[ nodeName ]; 5426 5427 if ( display ) { 5428 return display; 5429 } 5430 5431 temp = doc.body.appendChild( doc.createElement( nodeName ) ); 5432 display = jQuery.css( temp, "display" ); 5433 5434 temp.parentNode.removeChild( temp ); 5435 5436 if ( display === "none" ) { 5437 display = "block"; 5438 } 5439 defaultDisplayMap[ nodeName ] = display; 5440 5441 return display; 5442} 5443 5444function showHide( elements, show ) { 5445 var display, elem, 5446 values = [], 5447 index = 0, 5448 length = elements.length; 5449 5450 // Determine new display value for elements that need to change 5451 for ( ; index < length; index++ ) { 5452 elem = elements[ index ]; 5453 if ( !elem.style ) { 5454 continue; 5455 } 5456 5457 display = elem.style.display; 5458 if ( show ) { 5459 5460 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 5461 // check is required in this first loop unless we have a nonempty display value (either 5462 // inline or about-to-be-restored) 5463 if ( display === "none" ) { 5464 values[ index ] = dataPriv.get( elem, "display" ) || null; 5465 if ( !values[ index ] ) { 5466 elem.style.display = ""; 5467 } 5468 } 5469 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { 5470 values[ index ] = getDefaultDisplay( elem ); 5471 } 5472 } else { 5473 if ( display !== "none" ) { 5474 values[ index ] = "none"; 5475 5476 // Remember what we're overwriting 5477 dataPriv.set( elem, "display", display ); 5478 } 5479 } 5480 } 5481 5482 // Set the display of the elements in a second loop to avoid constant reflow 5483 for ( index = 0; index < length; index++ ) { 5484 if ( values[ index ] != null ) { 5485 elements[ index ].style.display = values[ index ]; 5486 } 5487 } 5488 5489 return elements; 5490} 5491 5492jQuery.fn.extend( { 5493 show: function() { 5494 return showHide( this, true ); 5495 }, 5496 hide: function() { 5497 return showHide( this ); 5498 }, 5499 toggle: function( state ) { 5500 if ( typeof state === "boolean" ) { 5501 return state ? this.show() : this.hide(); 5502 } 5503 5504 return this.each( function() { 5505 if ( isHiddenWithinTree( this ) ) { 5506 jQuery( this ).show(); 5507 } else { 5508 jQuery( this ).hide(); 5509 } 5510 } ); 5511 } 5512} ); 5513var rcheckableType = ( /^(?:checkbox|radio)$/i ); 5514 5515var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); 5516 5517var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); 5518 5519 5520 5521( function() { 5522 var fragment = document.createDocumentFragment(), 5523 div = fragment.appendChild( document.createElement( "div" ) ), 5524 input = document.createElement( "input" ); 5525 5526 // Support: Android 4.0 - 4.3 only 5527 // Check state lost if the name is set (trac-11217) 5528 // Support: Windows Web Apps (WWA) 5529 // `name` and `type` must use .setAttribute for WWA (trac-14901) 5530 input.setAttribute( "type", "radio" ); 5531 input.setAttribute( "checked", "checked" ); 5532 input.setAttribute( "name", "t" ); 5533 5534 div.appendChild( input ); 5535 5536 // Support: Android <=4.1 only 5537 // Older WebKit doesn't clone checked state correctly in fragments 5538 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 5539 5540 // Support: IE <=11 only 5541 // Make sure textarea (and checkbox) defaultValue is properly cloned 5542 div.innerHTML = "<textarea>x</textarea>"; 5543 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 5544 5545 // Support: IE <=9 only 5546 // IE <=9 replaces <option> tags with their contents when inserted outside of 5547 // the select element. 5548 div.innerHTML = "<option></option>"; 5549 support.option = !!div.lastChild; 5550} )(); 5551 5552 5553// We have to close these tags to support XHTML (trac-13200) 5554var wrapMap = { 5555 5556 // XHTML parsers do not magically insert elements in the 5557 // same way that tag soup parsers do. So we cannot shorten 5558 // this by omitting <tbody> or other required elements. 5559 thead: [ 1, "<table>", "</table>" ], 5560 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 5561 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 5562 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 5563 5564 _default: [ 0, "", "" ] 5565}; 5566 5567wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 5568wrapMap.th = wrapMap.td; 5569 5570// Support: IE <=9 only 5571if ( !support.option ) { 5572 wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ]; 5573} 5574 5575 5576function getAll( context, tag ) { 5577 5578 // Support: IE <=9 - 11 only 5579 // Use typeof to avoid zero-argument method invocation on host objects (trac-15151) 5580 var ret; 5581 5582 if ( typeof context.getElementsByTagName !== "undefined" ) { 5583 ret = context.getElementsByTagName( tag || "*" ); 5584 5585 } else if ( typeof context.querySelectorAll !== "undefined" ) { 5586 ret = context.querySelectorAll( tag || "*" ); 5587 5588 } else { 5589 ret = []; 5590 } 5591 5592 if ( tag === undefined || tag && nodeName( context, tag ) ) { 5593 return jQuery.merge( [ context ], ret ); 5594 } 5595 5596 return ret; 5597} 5598 5599 5600// Mark scripts as having already been evaluated 5601function setGlobalEval( elems, refElements ) { 5602 var i = 0, 5603 l = elems.length; 5604 5605 for ( ; i < l; i++ ) { 5606 dataPriv.set( 5607 elems[ i ], 5608 "globalEval", 5609 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 5610 ); 5611 } 5612} 5613 5614 5615var rhtml = /<|&#?\w+;/; 5616 5617function buildFragment( elems, context, scripts, selection, ignored ) { 5618 var elem, tmp, tag, wrap, attached, j, 5619 fragment = context.createDocumentFragment(), 5620 nodes = [], 5621 i = 0, 5622 l = elems.length; 5623 5624 for ( ; i < l; i++ ) { 5625 elem = elems[ i ]; 5626 5627 if ( elem || elem === 0 ) { 5628 5629 // Add nodes directly 5630 if ( toType( elem ) === "object" ) { 5631 5632 // Support: Android <=4.0 only, PhantomJS 1 only 5633 // push.apply(_, arraylike) throws on ancient WebKit 5634 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 5635 5636 // Convert non-html into a text node 5637 } else if ( !rhtml.test( elem ) ) { 5638 nodes.push( context.createTextNode( elem ) ); 5639 5640 // Convert html into DOM nodes 5641 } else { 5642 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 5643 5644 // Deserialize a standard representation 5645 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 5646 wrap = wrapMap[ tag ] || wrapMap._default; 5647 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 5648 5649 // Descend through wrappers to the right content 5650 j = wrap[ 0 ]; 5651 while ( j-- ) { 5652 tmp = tmp.lastChild; 5653 } 5654 5655 // Support: Android <=4.0 only, PhantomJS 1 only 5656 // push.apply(_, arraylike) throws on ancient WebKit 5657 jQuery.merge( nodes, tmp.childNodes ); 5658 5659 // Remember the top-level container 5660 tmp = fragment.firstChild; 5661 5662 // Ensure the created nodes are orphaned (trac-12392) 5663 tmp.textContent = ""; 5664 } 5665 } 5666 } 5667 5668 // Remove wrapper from fragment 5669 fragment.textContent = ""; 5670 5671 i = 0; 5672 while ( ( elem = nodes[ i++ ] ) ) { 5673 5674 // Skip elements already in the context collection (trac-4087) 5675 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 5676 if ( ignored ) { 5677 ignored.push( elem ); 5678 } 5679 continue; 5680 } 5681 5682 attached = isAttached( elem ); 5683 5684 // Append to fragment 5685 tmp = getAll( fragment.appendChild( elem ), "script" ); 5686 5687 // Preserve script evaluation history 5688 if ( attached ) { 5689 setGlobalEval( tmp ); 5690 } 5691 5692 // Capture executables 5693 if ( scripts ) { 5694 j = 0; 5695 while ( ( elem = tmp[ j++ ] ) ) { 5696 if ( rscriptType.test( elem.type || "" ) ) { 5697 scripts.push( elem ); 5698 } 5699 } 5700 } 5701 } 5702 5703 return fragment; 5704} 5705 5706 5707var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 5708 5709function returnTrue() { 5710 return true; 5711} 5712 5713function returnFalse() { 5714 return false; 5715} 5716 5717function on( elem, types, selector, data, fn, one ) { 5718 var origFn, type; 5719 5720 // Types can be a map of types/handlers 5721 if ( typeof types === "object" ) { 5722 5723 // ( types-Object, selector, data ) 5724 if ( typeof selector !== "string" ) { 5725 5726 // ( types-Object, data ) 5727 data = data || selector; 5728 selector = undefined; 5729 } 5730 for ( type in types ) { 5731 on( elem, type, selector, data, types[ type ], one ); 5732 } 5733 return elem; 5734 } 5735 5736 if ( data == null && fn == null ) { 5737 5738 // ( types, fn ) 5739 fn = selector; 5740 data = selector = undefined; 5741 } else if ( fn == null ) { 5742 if ( typeof selector === "string" ) { 5743 5744 // ( types, selector, fn ) 5745 fn = data; 5746 data = undefined; 5747 } else { 5748 5749 // ( types, data, fn ) 5750 fn = data; 5751 data = selector; 5752 selector = undefined; 5753 } 5754 } 5755 if ( fn === false ) { 5756 fn = returnFalse; 5757 } else if ( !fn ) { 5758 return elem; 5759 } 5760 5761 if ( one === 1 ) { 5762 origFn = fn; 5763 fn = function( event ) { 5764 5765 // Can use an empty set, since event contains the info 5766 jQuery().off( event ); 5767 return origFn.apply( this, arguments ); 5768 }; 5769 5770 // Use same guid so caller can remove using origFn 5771 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 5772 } 5773 return elem.each( function() { 5774 jQuery.event.add( this, types, fn, data, selector ); 5775 } ); 5776} 5777 5778/* 5779 * Helper functions for managing events -- not part of the public interface. 5780 * Props to Dean Edwards' addEvent library for many of the ideas. 5781 */ 5782jQuery.event = { 5783 5784 global: {}, 5785 5786 add: function( elem, types, handler, data, selector ) { 5787 5788 var handleObjIn, eventHandle, tmp, 5789 events, t, handleObj, 5790 special, handlers, type, namespaces, origType, 5791 elemData = dataPriv.get( elem ); 5792 5793 // Only attach events to objects that accept data 5794 if ( !acceptData( elem ) ) { 5795 return; 5796 } 5797 5798 // Caller can pass in an object of custom data in lieu of the handler 5799 if ( handler.handler ) { 5800 handleObjIn = handler; 5801 handler = handleObjIn.handler; 5802 selector = handleObjIn.selector; 5803 } 5804 5805 // Ensure that invalid selectors throw exceptions at attach time 5806 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 5807 if ( selector ) { 5808 jQuery.find.matchesSelector( documentElement, selector ); 5809 } 5810 5811 // Make sure that the handler has a unique ID, used to find/remove it later 5812 if ( !handler.guid ) { 5813 handler.guid = jQuery.guid++; 5814 } 5815 5816 // Init the element's event structure and main handler, if this is the first 5817 if ( !( events = elemData.events ) ) { 5818 events = elemData.events = Object.create( null ); 5819 } 5820 if ( !( eventHandle = elemData.handle ) ) { 5821 eventHandle = elemData.handle = function( e ) { 5822 5823 // Discard the second event of a jQuery.event.trigger() and 5824 // when an event is called after a page has unloaded 5825 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 5826 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 5827 }; 5828 } 5829 5830 // Handle multiple events separated by a space 5831 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 5832 t = types.length; 5833 while ( t-- ) { 5834 tmp = rtypenamespace.exec( types[ t ] ) || []; 5835 type = origType = tmp[ 1 ]; 5836 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 5837 5838 // There *must* be a type, no attaching namespace-only handlers 5839 if ( !type ) { 5840 continue; 5841 } 5842 5843 // If event changes its type, use the special event handlers for the changed type 5844 special = jQuery.event.special[ type ] || {}; 5845 5846 // If selector defined, determine special event api type, otherwise given type 5847 type = ( selector ? special.delegateType : special.bindType ) || type; 5848 5849 // Update special based on newly reset type 5850 special = jQuery.event.special[ type ] || {}; 5851 5852 // handleObj is passed to all event handlers 5853 handleObj = jQuery.extend( { 5854 type: type, 5855 origType: origType, 5856 data: data, 5857 handler: handler, 5858 guid: handler.guid, 5859 selector: selector, 5860 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 5861 namespace: namespaces.join( "." ) 5862 }, handleObjIn ); 5863 5864 // Init the event handler queue if we're the first 5865 if ( !( handlers = events[ type ] ) ) { 5866 handlers = events[ type ] = []; 5867 handlers.delegateCount = 0; 5868 5869 // Only use addEventListener if the special events handler returns false 5870 if ( !special.setup || 5871 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 5872 5873 if ( elem.addEventListener ) { 5874 elem.addEventListener( type, eventHandle ); 5875 } 5876 } 5877 } 5878 5879 if ( special.add ) { 5880 special.add.call( elem, handleObj ); 5881 5882 if ( !handleObj.handler.guid ) { 5883 handleObj.handler.guid = handler.guid; 5884 } 5885 } 5886 5887 // Add to the element's handler list, delegates in front 5888 if ( selector ) { 5889 handlers.splice( handlers.delegateCount++, 0, handleObj ); 5890 } else { 5891 handlers.push( handleObj ); 5892 } 5893 5894 // Keep track of which events have ever been used, for event optimization 5895 jQuery.event.global[ type ] = true; 5896 } 5897 5898 }, 5899 5900 // Detach an event or set of events from an element 5901 remove: function( elem, types, handler, selector, mappedTypes ) { 5902 5903 var j, origCount, tmp, 5904 events, t, handleObj, 5905 special, handlers, type, namespaces, origType, 5906 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 5907 5908 if ( !elemData || !( events = elemData.events ) ) { 5909 return; 5910 } 5911 5912 // Once for each type.namespace in types; type may be omitted 5913 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 5914 t = types.length; 5915 while ( t-- ) { 5916 tmp = rtypenamespace.exec( types[ t ] ) || []; 5917 type = origType = tmp[ 1 ]; 5918 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 5919 5920 // Unbind all events (on this namespace, if provided) for the element 5921 if ( !type ) { 5922 for ( type in events ) { 5923 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 5924 } 5925 continue; 5926 } 5927 5928 special = jQuery.event.special[ type ] || {}; 5929 type = ( selector ? special.delegateType : special.bindType ) || type; 5930 handlers = events[ type ] || []; 5931 tmp = tmp[ 2 ] && 5932 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 5933 5934 // Remove matching events 5935 origCount = j = handlers.length; 5936 while ( j-- ) { 5937 handleObj = handlers[ j ]; 5938 5939 if ( ( mappedTypes || origType === handleObj.origType ) && 5940 ( !handler || handler.guid === handleObj.guid ) && 5941 ( !tmp || tmp.test( handleObj.namespace ) ) && 5942 ( !selector || selector === handleObj.selector || 5943 selector === "**" && handleObj.selector ) ) { 5944 handlers.splice( j, 1 ); 5945 5946 if ( handleObj.selector ) { 5947 handlers.delegateCount--; 5948 } 5949 if ( special.remove ) { 5950 special.remove.call( elem, handleObj ); 5951 } 5952 } 5953 } 5954 5955 // Remove generic event handler if we removed something and no more handlers exist 5956 // (avoids potential for endless recursion during removal of special event handlers) 5957 if ( origCount && !handlers.length ) { 5958 if ( !special.teardown || 5959 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 5960 5961 jQuery.removeEvent( elem, type, elemData.handle ); 5962 } 5963 5964 delete events[ type ]; 5965 } 5966 } 5967 5968 // Remove data and the expando if it's no longer used 5969 if ( jQuery.isEmptyObject( events ) ) { 5970 dataPriv.remove( elem, "handle events" ); 5971 } 5972 }, 5973 5974 dispatch: function( nativeEvent ) { 5975 5976 var i, j, ret, matched, handleObj, handlerQueue, 5977 args = new Array( arguments.length ), 5978 5979 // Make a writable jQuery.Event from the native event object 5980 event = jQuery.event.fix( nativeEvent ), 5981 5982 handlers = ( 5983 dataPriv.get( this, "events" ) || Object.create( null ) 5984 )[ event.type ] || [], 5985 special = jQuery.event.special[ event.type ] || {}; 5986 5987 // Use the fix-ed jQuery.Event rather than the (read-only) native event 5988 args[ 0 ] = event; 5989 5990 for ( i = 1; i < arguments.length; i++ ) { 5991 args[ i ] = arguments[ i ]; 5992 } 5993 5994 event.delegateTarget = this; 5995 5996 // Call the preDispatch hook for the mapped type, and let it bail if desired 5997 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 5998 return; 5999 } 6000 6001 // Determine handlers 6002 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 6003 6004 // Run delegates first; they may want to stop propagation beneath us 6005 i = 0; 6006 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 6007 event.currentTarget = matched.elem; 6008 6009 j = 0; 6010 while ( ( handleObj = matched.handlers[ j++ ] ) && 6011 !event.isImmediatePropagationStopped() ) { 6012 6013 // If the event is namespaced, then each handler is only invoked if it is 6014 // specially universal or its namespaces are a superset of the event's. 6015 if ( !event.rnamespace || handleObj.namespace === false || 6016 event.rnamespace.test( handleObj.namespace ) ) { 6017 6018 event.handleObj = handleObj; 6019 event.data = handleObj.data; 6020 6021 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 6022 handleObj.handler ).apply( matched.elem, args ); 6023 6024 if ( ret !== undefined ) { 6025 if ( ( event.result = ret ) === false ) { 6026 event.preventDefault(); 6027 event.stopPropagation(); 6028 } 6029 } 6030 } 6031 } 6032 } 6033 6034 // Call the postDispatch hook for the mapped type 6035 if ( special.postDispatch ) { 6036 special.postDispatch.call( this, event ); 6037 } 6038 6039 return event.result; 6040 }, 6041 6042 handlers: function( event, handlers ) { 6043 var i, handleObj, sel, matchedHandlers, matchedSelectors, 6044 handlerQueue = [], 6045 delegateCount = handlers.delegateCount, 6046 cur = event.target; 6047 6048 // Find delegate handlers 6049 if ( delegateCount && 6050 6051 // Support: IE <=9 6052 // Black-hole SVG <use> instance trees (trac-13180) 6053 cur.nodeType && 6054 6055 // Support: Firefox <=42 6056 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 6057 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 6058 // Support: IE 11 only 6059 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 6060 !( event.type === "click" && event.button >= 1 ) ) { 6061 6062 for ( ; cur !== this; cur = cur.parentNode || this ) { 6063 6064 // Don't check non-elements (trac-13208) 6065 // Don't process clicks on disabled elements (trac-6911, trac-8165, trac-11382, trac-11764) 6066 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { 6067 matchedHandlers = []; 6068 matchedSelectors = {}; 6069 for ( i = 0; i < delegateCount; i++ ) { 6070 handleObj = handlers[ i ]; 6071 6072 // Don't conflict with Object.prototype properties (trac-13203) 6073 sel = handleObj.selector + " "; 6074 6075 if ( matchedSelectors[ sel ] === undefined ) { 6076 matchedSelectors[ sel ] = handleObj.needsContext ? 6077 jQuery( sel, this ).index( cur ) > -1 : 6078 jQuery.find( sel, this, null, [ cur ] ).length; 6079 } 6080 if ( matchedSelectors[ sel ] ) { 6081 matchedHandlers.push( handleObj ); 6082 } 6083 } 6084 if ( matchedHandlers.length ) { 6085 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); 6086 } 6087 } 6088 } 6089 } 6090 6091 // Add the remaining (directly-bound) handlers 6092 cur = this; 6093 if ( delegateCount < handlers.length ) { 6094 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); 6095 } 6096 6097 return handlerQueue; 6098 }, 6099 6100 addProp: function( name, hook ) { 6101 Object.defineProperty( jQuery.Event.prototype, name, { 6102 enumerable: true, 6103 configurable: true, 6104 6105 get: isFunction( hook ) ? 6106 function() { 6107 if ( this.originalEvent ) { 6108 return hook( this.originalEvent ); 6109 } 6110 } : 6111 function() { 6112 if ( this.originalEvent ) { 6113 return this.originalEvent[ name ]; 6114 } 6115 }, 6116 6117 set: function( value ) { 6118 Object.defineProperty( this, name, { 6119 enumerable: true, 6120 configurable: true, 6121 writable: true, 6122 value: value 6123 } ); 6124 } 6125 } ); 6126 }, 6127 6128 fix: function( originalEvent ) { 6129 return originalEvent[ jQuery.expando ] ? 6130 originalEvent : 6131 new jQuery.Event( originalEvent ); 6132 }, 6133 6134 special: { 6135 load: { 6136 6137 // Prevent triggered image.load events from bubbling to window.load 6138 noBubble: true 6139 }, 6140 click: { 6141 6142 // Utilize native event to ensure correct state for checkable inputs 6143 setup: function( data ) { 6144 6145 // For mutual compressibility with _default, replace `this` access with a local var. 6146 // `|| data` is dead code meant only to preserve the variable through minification. 6147 var el = this || data; 6148 6149 // Claim the first handler 6150 if ( rcheckableType.test( el.type ) && 6151 el.click && nodeName( el, "input" ) ) { 6152 6153 // dataPriv.set( el, "click", ... ) 6154 leverageNative( el, "click", true ); 6155 } 6156 6157 // Return false to allow normal processing in the caller 6158 return false; 6159 }, 6160 trigger: function( data ) { 6161 6162 // For mutual compressibility with _default, replace `this` access with a local var. 6163 // `|| data` is dead code meant only to preserve the variable through minification. 6164 var el = this || data; 6165 6166 // Force setup before triggering a click 6167 if ( rcheckableType.test( el.type ) && 6168 el.click && nodeName( el, "input" ) ) { 6169 6170 leverageNative( el, "click" ); 6171 } 6172 6173 // Return non-false to allow normal event-path propagation 6174 return true; 6175 }, 6176 6177 // For cross-browser consistency, suppress native .click() on links 6178 // Also prevent it if we're currently inside a leveraged native-event stack 6179 _default: function( event ) { 6180 var target = event.target; 6181 return rcheckableType.test( target.type ) && 6182 target.click && nodeName( target, "input" ) && 6183 dataPriv.get( target, "click" ) || 6184 nodeName( target, "a" ); 6185 } 6186 }, 6187 6188 beforeunload: { 6189 postDispatch: function( event ) { 6190 6191 // Support: Firefox 20+ 6192 // Firefox doesn't alert if the returnValue field is not set. 6193 if ( event.result !== undefined && event.originalEvent ) { 6194 event.originalEvent.returnValue = event.result; 6195 } 6196 } 6197 } 6198 } 6199}; 6200 6201// Ensure the presence of an event listener that handles manually-triggered 6202// synthetic events by interrupting progress until reinvoked in response to 6203// *native* events that it fires directly, ensuring that state changes have 6204// already occurred before other listeners are invoked. 6205function leverageNative( el, type, isSetup ) { 6206 6207 // Missing `isSetup` indicates a trigger call, which must force setup through jQuery.event.add 6208 if ( !isSetup ) { 6209 if ( dataPriv.get( el, type ) === undefined ) { 6210 jQuery.event.add( el, type, returnTrue ); 6211 } 6212 return; 6213 } 6214 6215 // Register the controller as a special universal handler for all event namespaces 6216 dataPriv.set( el, type, false ); 6217 jQuery.event.add( el, type, { 6218 namespace: false, 6219 handler: function( event ) { 6220 var result, 6221 saved = dataPriv.get( this, type ); 6222 6223 if ( ( event.isTrigger & 1 ) && this[ type ] ) { 6224 6225 // Interrupt processing of the outer synthetic .trigger()ed event 6226 if ( !saved ) { 6227 6228 // Store arguments for use when handling the inner native event 6229 // There will always be at least one argument (an event object), so this array 6230 // will not be confused with a leftover capture object. 6231 saved = slice.call( arguments ); 6232 dataPriv.set( this, type, saved ); 6233 6234 // Trigger the native event and capture its result 6235 this[ type ](); 6236 result = dataPriv.get( this, type ); 6237 dataPriv.set( this, type, false ); 6238 6239 if ( saved !== result ) { 6240 6241 // Cancel the outer synthetic event 6242 event.stopImmediatePropagation(); 6243 event.preventDefault(); 6244 6245 return result; 6246 } 6247 6248 // If this is an inner synthetic event for an event with a bubbling surrogate 6249 // (focus or blur), assume that the surrogate already propagated from triggering 6250 // the native event and prevent that from happening again here. 6251 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the 6252 // bubbling surrogate propagates *after* the non-bubbling base), but that seems 6253 // less bad than duplication. 6254 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { 6255 event.stopPropagation(); 6256 } 6257 6258 // If this is a native event triggered above, everything is now in order 6259 // Fire an inner synthetic event with the original arguments 6260 } else if ( saved ) { 6261 6262 // ...and capture the result 6263 dataPriv.set( this, type, jQuery.event.trigger( 6264 saved[ 0 ], 6265 saved.slice( 1 ), 6266 this 6267 ) ); 6268 6269 // Abort handling of the native event by all jQuery handlers while allowing 6270 // native handlers on the same element to run. On target, this is achieved 6271 // by stopping immediate propagation just on the jQuery event. However, 6272 // the native event is re-wrapped by a jQuery one on each level of the 6273 // propagation so the only way to stop it for jQuery is to stop it for 6274 // everyone via native `stopPropagation()`. This is not a problem for 6275 // focus/blur which don't bubble, but it does also stop click on checkboxes 6276 // and radios. We accept this limitation. 6277 event.stopPropagation(); 6278 event.isImmediatePropagationStopped = returnTrue; 6279 } 6280 } 6281 } ); 6282} 6283 6284jQuery.removeEvent = function( elem, type, handle ) { 6285 6286 // This "if" is needed for plain objects 6287 if ( elem.removeEventListener ) { 6288 elem.removeEventListener( type, handle ); 6289 } 6290}; 6291 6292jQuery.Event = function( src, props ) { 6293 6294 // Allow instantiation without the 'new' keyword 6295 if ( !( this instanceof jQuery.Event ) ) { 6296 return new jQuery.Event( src, props ); 6297 } 6298 6299 // Event object 6300 if ( src && src.type ) { 6301 this.originalEvent = src; 6302 this.type = src.type; 6303 6304 // Events bubbling up the document may have been marked as prevented 6305 // by a handler lower down the tree; reflect the correct value. 6306 this.isDefaultPrevented = src.defaultPrevented || 6307 src.defaultPrevented === undefined && 6308 6309 // Support: Android <=2.3 only 6310 src.returnValue === false ? 6311 returnTrue : 6312 returnFalse; 6313 6314 // Create target properties 6315 // Support: Safari <=6 - 7 only 6316 // Target should not be a text node (trac-504, trac-13143) 6317 this.target = ( src.target && src.target.nodeType === 3 ) ? 6318 src.target.parentNode : 6319 src.target; 6320 6321 this.currentTarget = src.currentTarget; 6322 this.relatedTarget = src.relatedTarget; 6323 6324 // Event type 6325 } else { 6326 this.type = src; 6327 } 6328 6329 // Put explicitly provided properties onto the event object 6330 if ( props ) { 6331 jQuery.extend( this, props ); 6332 } 6333 6334 // Create a timestamp if incoming event doesn't have one 6335 this.timeStamp = src && src.timeStamp || Date.now(); 6336 6337 // Mark it as fixed 6338 this[ jQuery.expando ] = true; 6339}; 6340 6341// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 6342// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 6343jQuery.Event.prototype = { 6344 constructor: jQuery.Event, 6345 isDefaultPrevented: returnFalse, 6346 isPropagationStopped: returnFalse, 6347 isImmediatePropagationStopped: returnFalse, 6348 isSimulated: false, 6349 6350 preventDefault: function() { 6351 var e = this.originalEvent; 6352 6353 this.isDefaultPrevented = returnTrue; 6354 6355 if ( e && !this.isSimulated ) { 6356 e.preventDefault(); 6357 } 6358 }, 6359 stopPropagation: function() { 6360 var e = this.originalEvent; 6361 6362 this.isPropagationStopped = returnTrue; 6363 6364 if ( e && !this.isSimulated ) { 6365 e.stopPropagation(); 6366 } 6367 }, 6368 stopImmediatePropagation: function() { 6369 var e = this.originalEvent; 6370 6371 this.isImmediatePropagationStopped = returnTrue; 6372 6373 if ( e && !this.isSimulated ) { 6374 e.stopImmediatePropagation(); 6375 } 6376 6377 this.stopPropagation(); 6378 } 6379}; 6380 6381// Includes all common event props including KeyEvent and MouseEvent specific props 6382jQuery.each( { 6383 altKey: true, 6384 bubbles: true, 6385 cancelable: true, 6386 changedTouches: true, 6387 ctrlKey: true, 6388 detail: true, 6389 eventPhase: true, 6390 metaKey: true, 6391 pageX: true, 6392 pageY: true, 6393 shiftKey: true, 6394 view: true, 6395 "char": true, 6396 code: true, 6397 charCode: true, 6398 key: true, 6399 keyCode: true, 6400 button: true, 6401 buttons: true, 6402 clientX: true, 6403 clientY: true, 6404 offsetX: true, 6405 offsetY: true, 6406 pointerId: true, 6407 pointerType: true, 6408 screenX: true, 6409 screenY: true, 6410 targetTouches: true, 6411 toElement: true, 6412 touches: true, 6413 which: true 6414}, jQuery.event.addProp ); 6415 6416jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { 6417 6418 function focusMappedHandler( nativeEvent ) { 6419 if ( document.documentMode ) { 6420 6421 // Support: IE 11+ 6422 // Attach a single focusin/focusout handler on the document while someone wants 6423 // focus/blur. This is because the former are synchronous in IE while the latter 6424 // are async. In other browsers, all those handlers are invoked synchronously. 6425 6426 // `handle` from private data would already wrap the event, but we need 6427 // to change the `type` here. 6428 var handle = dataPriv.get( this, "handle" ), 6429 event = jQuery.event.fix( nativeEvent ); 6430 event.type = nativeEvent.type === "focusin" ? "focus" : "blur"; 6431 event.isSimulated = true; 6432 6433 // First, handle focusin/focusout 6434 handle( nativeEvent ); 6435 6436 // ...then, handle focus/blur 6437 // 6438 // focus/blur don't bubble while focusin/focusout do; simulate the former by only 6439 // invoking the handler at the lower level. 6440 if ( event.target === event.currentTarget ) { 6441 6442 // The setup part calls `leverageNative`, which, in turn, calls 6443 // `jQuery.event.add`, so event handle will already have been set 6444 // by this point. 6445 handle( event ); 6446 } 6447 } else { 6448 6449 // For non-IE browsers, attach a single capturing handler on the document 6450 // while someone wants focusin/focusout. 6451 jQuery.event.simulate( delegateType, nativeEvent.target, 6452 jQuery.event.fix( nativeEvent ) ); 6453 } 6454 } 6455 6456 jQuery.event.special[ type ] = { 6457 6458 // Utilize native event if possible so blur/focus sequence is correct 6459 setup: function() { 6460 6461 var attaches; 6462 6463 // Claim the first handler 6464 // dataPriv.set( this, "focus", ... ) 6465 // dataPriv.set( this, "blur", ... ) 6466 leverageNative( this, type, true ); 6467 6468 if ( document.documentMode ) { 6469 6470 // Support: IE 9 - 11+ 6471 // We use the same native handler for focusin & focus (and focusout & blur) 6472 // so we need to coordinate setup & teardown parts between those events. 6473 // Use `delegateType` as the key as `type` is already used by `leverageNative`. 6474 attaches = dataPriv.get( this, delegateType ); 6475 if ( !attaches ) { 6476 this.addEventListener( delegateType, focusMappedHandler ); 6477 } 6478 dataPriv.set( this, delegateType, ( attaches || 0 ) + 1 ); 6479 } else { 6480 6481 // Return false to allow normal processing in the caller 6482 return false; 6483 } 6484 }, 6485 trigger: function() { 6486 6487 // Force setup before trigger 6488 leverageNative( this, type ); 6489 6490 // Return non-false to allow normal event-path propagation 6491 return true; 6492 }, 6493 6494 teardown: function() { 6495 var attaches; 6496 6497 if ( document.documentMode ) { 6498 attaches = dataPriv.get( this, delegateType ) - 1; 6499 if ( !attaches ) { 6500 this.removeEventListener( delegateType, focusMappedHandler ); 6501 dataPriv.remove( this, delegateType ); 6502 } else { 6503 dataPriv.set( this, delegateType, attaches ); 6504 } 6505 } else { 6506 6507 // Return false to indicate standard teardown should be applied 6508 return false; 6509 } 6510 }, 6511 6512 // Suppress native focus or blur if we're currently inside 6513 // a leveraged native-event stack 6514 _default: function( event ) { 6515 return dataPriv.get( event.target, type ); 6516 }, 6517 6518 delegateType: delegateType 6519 }; 6520 6521 // Support: Firefox <=44 6522 // Firefox doesn't have focus(in | out) events 6523 // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 6524 // 6525 // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 6526 // focus(in | out) events fire after focus & blur events, 6527 // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 6528 // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 6529 // 6530 // Support: IE 9 - 11+ 6531 // To preserve relative focusin/focus & focusout/blur event order guaranteed on the 3.x branch, 6532 // attach a single handler for both events in IE. 6533 jQuery.event.special[ delegateType ] = { 6534 setup: function() { 6535 6536 // Handle: regular nodes (via `this.ownerDocument`), window 6537 // (via `this.document`) & document (via `this`). 6538 var doc = this.ownerDocument || this.document || this, 6539 dataHolder = document.documentMode ? this : doc, 6540 attaches = dataPriv.get( dataHolder, delegateType ); 6541 6542 // Support: IE 9 - 11+ 6543 // We use the same native handler for focusin & focus (and focusout & blur) 6544 // so we need to coordinate setup & teardown parts between those events. 6545 // Use `delegateType` as the key as `type` is already used by `leverageNative`. 6546 if ( !attaches ) { 6547 if ( document.documentMode ) { 6548 this.addEventListener( delegateType, focusMappedHandler ); 6549 } else { 6550 doc.addEventListener( type, focusMappedHandler, true ); 6551 } 6552 } 6553 dataPriv.set( dataHolder, delegateType, ( attaches || 0 ) + 1 ); 6554 }, 6555 teardown: function() { 6556 var doc = this.ownerDocument || this.document || this, 6557 dataHolder = document.documentMode ? this : doc, 6558 attaches = dataPriv.get( dataHolder, delegateType ) - 1; 6559 6560 if ( !attaches ) { 6561 if ( document.documentMode ) { 6562 this.removeEventListener( delegateType, focusMappedHandler ); 6563 } else { 6564 doc.removeEventListener( type, focusMappedHandler, true ); 6565 } 6566 dataPriv.remove( dataHolder, delegateType ); 6567 } else { 6568 dataPriv.set( dataHolder, delegateType, attaches ); 6569 } 6570 } 6571 }; 6572} ); 6573 6574// Create mouseenter/leave events using mouseover/out and event-time checks 6575// so that event delegation works in jQuery. 6576// Do the same for pointerenter/pointerleave and pointerover/pointerout 6577// 6578// Support: Safari 7 only 6579// Safari sends mouseenter too often; see: 6580// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 6581// for the description of the bug (it existed in older Chrome versions as well). 6582jQuery.each( { 6583 mouseenter: "mouseover", 6584 mouseleave: "mouseout", 6585 pointerenter: "pointerover", 6586 pointerleave: "pointerout" 6587}, function( orig, fix ) { 6588 jQuery.event.special[ orig ] = { 6589 delegateType: fix, 6590 bindType: fix, 6591 6592 handle: function( event ) { 6593 var ret, 6594 target = this, 6595 related = event.relatedTarget, 6596 handleObj = event.handleObj; 6597 6598 // For mouseenter/leave call the handler if related is outside the target. 6599 // NB: No relatedTarget if the mouse left/entered the browser window 6600 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 6601 event.type = handleObj.origType; 6602 ret = handleObj.handler.apply( this, arguments ); 6603 event.type = fix; 6604 } 6605 return ret; 6606 } 6607 }; 6608} ); 6609 6610jQuery.fn.extend( { 6611 6612 on: function( types, selector, data, fn ) { 6613 return on( this, types, selector, data, fn ); 6614 }, 6615 one: function( types, selector, data, fn ) { 6616 return on( this, types, selector, data, fn, 1 ); 6617 }, 6618 off: function( types, selector, fn ) { 6619 var handleObj, type; 6620 if ( types && types.preventDefault && types.handleObj ) { 6621 6622 // ( event ) dispatched jQuery.Event 6623 handleObj = types.handleObj; 6624 jQuery( types.delegateTarget ).off( 6625 handleObj.namespace ? 6626 handleObj.origType + "." + handleObj.namespace : 6627 handleObj.origType, 6628 handleObj.selector, 6629 handleObj.handler 6630 ); 6631 return this; 6632 } 6633 if ( typeof types === "object" ) { 6634 6635 // ( types-object [, selector] ) 6636 for ( type in types ) { 6637 this.off( type, selector, types[ type ] ); 6638 } 6639 return this; 6640 } 6641 if ( selector === false || typeof selector === "function" ) { 6642 6643 // ( types [, fn] ) 6644 fn = selector; 6645 selector = undefined; 6646 } 6647 if ( fn === false ) { 6648 fn = returnFalse; 6649 } 6650 return this.each( function() { 6651 jQuery.event.remove( this, types, fn, selector ); 6652 } ); 6653 } 6654} ); 6655 6656 6657var 6658 6659 // Support: IE <=10 - 11, Edge 12 - 13 only 6660 // In IE/Edge using regex groups here causes severe slowdowns. 6661 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 6662 rnoInnerhtml = /<script|<style|<link/i, 6663 6664 // checked="checked" or checked 6665 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 6666 6667 rcleanScript = /^\s*<!\[CDATA\[|\]\]>\s*$/g; 6668 6669// Prefer a tbody over its parent table for containing new rows 6670function manipulationTarget( elem, content ) { 6671 if ( nodeName( elem, "table" ) && 6672 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { 6673 6674 return jQuery( elem ).children( "tbody" )[ 0 ] || elem; 6675 } 6676 6677 return elem; 6678} 6679 6680// Replace/restore the type attribute of script elements for safe DOM manipulation 6681function disableScript( elem ) { 6682 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 6683 return elem; 6684} 6685function restoreScript( elem ) { 6686 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { 6687 elem.type = elem.type.slice( 5 ); 6688 } else { 6689 elem.removeAttribute( "type" ); 6690 } 6691 6692 return elem; 6693} 6694 6695function cloneCopyEvent( src, dest ) { 6696 var i, l, type, pdataOld, udataOld, udataCur, events; 6697 6698 if ( dest.nodeType !== 1 ) { 6699 return; 6700 } 6701 6702 // 1. Copy private data: events, handlers, etc. 6703 if ( dataPriv.hasData( src ) ) { 6704 pdataOld = dataPriv.get( src ); 6705 events = pdataOld.events; 6706 6707 if ( events ) { 6708 dataPriv.remove( dest, "handle events" ); 6709 6710 for ( type in events ) { 6711 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 6712 jQuery.event.add( dest, type, events[ type ][ i ] ); 6713 } 6714 } 6715 } 6716 } 6717 6718 // 2. Copy user data 6719 if ( dataUser.hasData( src ) ) { 6720 udataOld = dataUser.access( src ); 6721 udataCur = jQuery.extend( {}, udataOld ); 6722 6723 dataUser.set( dest, udataCur ); 6724 } 6725} 6726 6727// Fix IE bugs, see support tests 6728function fixInput( src, dest ) { 6729 var nodeName = dest.nodeName.toLowerCase(); 6730 6731 // Fails to persist the checked state of a cloned checkbox or radio button. 6732 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 6733 dest.checked = src.checked; 6734 6735 // Fails to return the selected option to the default selected state when cloning options 6736 } else if ( nodeName === "input" || nodeName === "textarea" ) { 6737 dest.defaultValue = src.defaultValue; 6738 } 6739} 6740 6741function domManip( collection, args, callback, ignored ) { 6742 6743 // Flatten any nested arrays 6744 args = flat( args ); 6745 6746 var fragment, first, scripts, hasScripts, node, doc, 6747 i = 0, 6748 l = collection.length, 6749 iNoClone = l - 1, 6750 value = args[ 0 ], 6751 valueIsFunction = isFunction( value ); 6752 6753 // We can't cloneNode fragments that contain checked, in WebKit 6754 if ( valueIsFunction || 6755 ( l > 1 && typeof value === "string" && 6756 !support.checkClone && rchecked.test( value ) ) ) { 6757 return collection.each( function( index ) { 6758 var self = collection.eq( index ); 6759 if ( valueIsFunction ) { 6760 args[ 0 ] = value.call( this, index, self.html() ); 6761 } 6762 domManip( self, args, callback, ignored ); 6763 } ); 6764 } 6765 6766 if ( l ) { 6767 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 6768 first = fragment.firstChild; 6769 6770 if ( fragment.childNodes.length === 1 ) { 6771 fragment = first; 6772 } 6773 6774 // Require either new content or an interest in ignored elements to invoke the callback 6775 if ( first || ignored ) { 6776 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 6777 hasScripts = scripts.length; 6778 6779 // Use the original fragment for the last item 6780 // instead of the first because it can end up 6781 // being emptied incorrectly in certain situations (trac-8070). 6782 for ( ; i < l; i++ ) { 6783 node = fragment; 6784 6785 if ( i !== iNoClone ) { 6786 node = jQuery.clone( node, true, true ); 6787 6788 // Keep references to cloned scripts for later restoration 6789 if ( hasScripts ) { 6790 6791 // Support: Android <=4.0 only, PhantomJS 1 only 6792 // push.apply(_, arraylike) throws on ancient WebKit 6793 jQuery.merge( scripts, getAll( node, "script" ) ); 6794 } 6795 } 6796 6797 callback.call( collection[ i ], node, i ); 6798 } 6799 6800 if ( hasScripts ) { 6801 doc = scripts[ scripts.length - 1 ].ownerDocument; 6802 6803 // Re-enable scripts 6804 jQuery.map( scripts, restoreScript ); 6805 6806 // Evaluate executable scripts on first document insertion 6807 for ( i = 0; i < hasScripts; i++ ) { 6808 node = scripts[ i ]; 6809 if ( rscriptType.test( node.type || "" ) && 6810 !dataPriv.access( node, "globalEval" ) && 6811 jQuery.contains( doc, node ) ) { 6812 6813 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { 6814 6815 // Optional AJAX dependency, but won't run scripts if not present 6816 if ( jQuery._evalUrl && !node.noModule ) { 6817 jQuery._evalUrl( node.src, { 6818 nonce: node.nonce || node.getAttribute( "nonce" ) 6819 }, doc ); 6820 } 6821 } else { 6822 6823 // Unwrap a CDATA section containing script contents. This shouldn't be 6824 // needed as in XML documents they're already not visible when 6825 // inspecting element contents and in HTML documents they have no 6826 // meaning but we're preserving that logic for backwards compatibility. 6827 // This will be removed completely in 4.0. See gh-4904. 6828 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); 6829 } 6830 } 6831 } 6832 } 6833 } 6834 } 6835 6836 return collection; 6837} 6838 6839function remove( elem, selector, keepData ) { 6840 var node, 6841 nodes = selector ? jQuery.filter( selector, elem ) : elem, 6842 i = 0; 6843 6844 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 6845 if ( !keepData && node.nodeType === 1 ) { 6846 jQuery.cleanData( getAll( node ) ); 6847 } 6848 6849 if ( node.parentNode ) { 6850 if ( keepData && isAttached( node ) ) { 6851 setGlobalEval( getAll( node, "script" ) ); 6852 } 6853 node.parentNode.removeChild( node ); 6854 } 6855 } 6856 6857 return elem; 6858} 6859 6860jQuery.extend( { 6861 htmlPrefilter: function( html ) { 6862 return html; 6863 }, 6864 6865 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 6866 var i, l, srcElements, destElements, 6867 clone = elem.cloneNode( true ), 6868 inPage = isAttached( elem ); 6869 6870 // Fix IE cloning issues 6871 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 6872 !jQuery.isXMLDoc( elem ) ) { 6873 6874 // We eschew jQuery#find here for performance reasons: 6875 // https://jsperf.com/getall-vs-sizzle/2 6876 destElements = getAll( clone ); 6877 srcElements = getAll( elem ); 6878 6879 for ( i = 0, l = srcElements.length; i < l; i++ ) { 6880 fixInput( srcElements[ i ], destElements[ i ] ); 6881 } 6882 } 6883 6884 // Copy the events from the original to the clone 6885 if ( dataAndEvents ) { 6886 if ( deepDataAndEvents ) { 6887 srcElements = srcElements || getAll( elem ); 6888 destElements = destElements || getAll( clone ); 6889 6890 for ( i = 0, l = srcElements.length; i < l; i++ ) { 6891 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 6892 } 6893 } else { 6894 cloneCopyEvent( elem, clone ); 6895 } 6896 } 6897 6898 // Preserve script evaluation history 6899 destElements = getAll( clone, "script" ); 6900 if ( destElements.length > 0 ) { 6901 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 6902 } 6903 6904 // Return the cloned set 6905 return clone; 6906 }, 6907 6908 cleanData: function( elems ) { 6909 var data, elem, type, 6910 special = jQuery.event.special, 6911 i = 0; 6912 6913 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 6914 if ( acceptData( elem ) ) { 6915 if ( ( data = elem[ dataPriv.expando ] ) ) { 6916 if ( data.events ) { 6917 for ( type in data.events ) { 6918 if ( special[ type ] ) { 6919 jQuery.event.remove( elem, type ); 6920 6921 // This is a shortcut to avoid jQuery.event.remove's overhead 6922 } else { 6923 jQuery.removeEvent( elem, type, data.handle ); 6924 } 6925 } 6926 } 6927 6928 // Support: Chrome <=35 - 45+ 6929 // Assign undefined instead of using delete, see Data#remove 6930 elem[ dataPriv.expando ] = undefined; 6931 } 6932 if ( elem[ dataUser.expando ] ) { 6933 6934 // Support: Chrome <=35 - 45+ 6935 // Assign undefined instead of using delete, see Data#remove 6936 elem[ dataUser.expando ] = undefined; 6937 } 6938 } 6939 } 6940 } 6941} ); 6942 6943jQuery.fn.extend( { 6944 detach: function( selector ) { 6945 return remove( this, selector, true ); 6946 }, 6947 6948 remove: function( selector ) { 6949 return remove( this, selector ); 6950 }, 6951 6952 text: function( value ) { 6953 return access( this, function( value ) { 6954 return value === undefined ? 6955 jQuery.text( this ) : 6956 this.empty().each( function() { 6957 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6958 this.textContent = value; 6959 } 6960 } ); 6961 }, null, value, arguments.length ); 6962 }, 6963 6964 append: function() { 6965 return domManip( this, arguments, function( elem ) { 6966 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6967 var target = manipulationTarget( this, elem ); 6968 target.appendChild( elem ); 6969 } 6970 } ); 6971 }, 6972 6973 prepend: function() { 6974 return domManip( this, arguments, function( elem ) { 6975 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 6976 var target = manipulationTarget( this, elem ); 6977 target.insertBefore( elem, target.firstChild ); 6978 } 6979 } ); 6980 }, 6981 6982 before: function() { 6983 return domManip( this, arguments, function( elem ) { 6984 if ( this.parentNode ) { 6985 this.parentNode.insertBefore( elem, this ); 6986 } 6987 } ); 6988 }, 6989 6990 after: function() { 6991 return domManip( this, arguments, function( elem ) { 6992 if ( this.parentNode ) { 6993 this.parentNode.insertBefore( elem, this.nextSibling ); 6994 } 6995 } ); 6996 }, 6997 6998 empty: function() { 6999 var elem, 7000 i = 0; 7001 7002 for ( ; ( elem = this[ i ] ) != null; i++ ) { 7003 if ( elem.nodeType === 1 ) { 7004 7005 // Prevent memory leaks 7006 jQuery.cleanData( getAll( elem, false ) ); 7007 7008 // Remove any remaining nodes 7009 elem.textContent = ""; 7010 } 7011 } 7012 7013 return this; 7014 }, 7015 7016 clone: function( dataAndEvents, deepDataAndEvents ) { 7017 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 7018 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 7019 7020 return this.map( function() { 7021 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 7022 } ); 7023 }, 7024 7025 html: function( value ) { 7026 return access( this, function( value ) { 7027 var elem = this[ 0 ] || {}, 7028 i = 0, 7029 l = this.length; 7030 7031 if ( value === undefined && elem.nodeType === 1 ) { 7032 return elem.innerHTML; 7033 } 7034 7035 // See if we can take a shortcut and just use innerHTML 7036 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 7037 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 7038 7039 value = jQuery.htmlPrefilter( value ); 7040 7041 try { 7042 for ( ; i < l; i++ ) { 7043 elem = this[ i ] || {}; 7044 7045 // Remove element nodes and prevent memory leaks 7046 if ( elem.nodeType === 1 ) { 7047 jQuery.cleanData( getAll( elem, false ) ); 7048 elem.innerHTML = value; 7049 } 7050 } 7051 7052 elem = 0; 7053 7054 // If using innerHTML throws an exception, use the fallback method 7055 } catch ( e ) {} 7056 } 7057 7058 if ( elem ) { 7059 this.empty().append( value ); 7060 } 7061 }, null, value, arguments.length ); 7062 }, 7063 7064 replaceWith: function() { 7065 var ignored = []; 7066 7067 // Make the changes, replacing each non-ignored context element with the new content 7068 return domManip( this, arguments, function( elem ) { 7069 var parent = this.parentNode; 7070 7071 if ( jQuery.inArray( this, ignored ) < 0 ) { 7072 jQuery.cleanData( getAll( this ) ); 7073 if ( parent ) { 7074 parent.replaceChild( elem, this ); 7075 } 7076 } 7077 7078 // Force callback invocation 7079 }, ignored ); 7080 } 7081} ); 7082 7083jQuery.each( { 7084 appendTo: "append", 7085 prependTo: "prepend", 7086 insertBefore: "before", 7087 insertAfter: "after", 7088 replaceAll: "replaceWith" 7089}, function( name, original ) { 7090 jQuery.fn[ name ] = function( selector ) { 7091 var elems, 7092 ret = [], 7093 insert = jQuery( selector ), 7094 last = insert.length - 1, 7095 i = 0; 7096 7097 for ( ; i <= last; i++ ) { 7098 elems = i === last ? this : this.clone( true ); 7099 jQuery( insert[ i ] )[ original ]( elems ); 7100 7101 // Support: Android <=4.0 only, PhantomJS 1 only 7102 // .get() because push.apply(_, arraylike) throws on ancient WebKit 7103 push.apply( ret, elems.get() ); 7104 } 7105 7106 return this.pushStack( ret ); 7107 }; 7108} ); 7109var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 7110 7111var rcustomProp = /^--/; 7112 7113 7114var getStyles = function( elem ) { 7115 7116 // Support: IE <=11 only, Firefox <=30 (trac-15098, trac-14150) 7117 // IE throws on elements created in popups 7118 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 7119 var view = elem.ownerDocument.defaultView; 7120 7121 if ( !view || !view.opener ) { 7122 view = window; 7123 } 7124 7125 return view.getComputedStyle( elem ); 7126 }; 7127 7128var swap = function( elem, options, callback ) { 7129 var ret, name, 7130 old = {}; 7131 7132 // Remember the old values, and insert the new ones 7133 for ( name in options ) { 7134 old[ name ] = elem.style[ name ]; 7135 elem.style[ name ] = options[ name ]; 7136 } 7137 7138 ret = callback.call( elem ); 7139 7140 // Revert the old values 7141 for ( name in options ) { 7142 elem.style[ name ] = old[ name ]; 7143 } 7144 7145 return ret; 7146}; 7147 7148 7149var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); 7150 7151 7152 7153( function() { 7154 7155 // Executing both pixelPosition & boxSizingReliable tests require only one layout 7156 // so they're executed at the same time to save the second computation. 7157 function computeStyleTests() { 7158 7159 // This is a singleton, we need to execute it only once 7160 if ( !div ) { 7161 return; 7162 } 7163 7164 container.style.cssText = "position:absolute;left:-11111px;width:60px;" + 7165 "margin-top:1px;padding:0;border:0"; 7166 div.style.cssText = 7167 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 7168 "margin:auto;border:1px;padding:1px;" + 7169 "width:60%;top:1%"; 7170 documentElement.appendChild( container ).appendChild( div ); 7171 7172 var divStyle = window.getComputedStyle( div ); 7173 pixelPositionVal = divStyle.top !== "1%"; 7174 7175 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 7176 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; 7177 7178 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 7179 // Some styles come back with percentage values, even though they shouldn't 7180 div.style.right = "60%"; 7181 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; 7182 7183 // Support: IE 9 - 11 only 7184 // Detect misreporting of content dimensions for box-sizing:border-box elements 7185 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; 7186 7187 // Support: IE 9 only 7188 // Detect overflow:scroll screwiness (gh-3699) 7189 // Support: Chrome <=64 7190 // Don't get tricked when zoom affects offsetWidth (gh-4029) 7191 div.style.position = "absolute"; 7192 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; 7193 7194 documentElement.removeChild( container ); 7195 7196 // Nullify the div so it wouldn't be stored in the memory and 7197 // it will also be a sign that checks already performed 7198 div = null; 7199 } 7200 7201 function roundPixelMeasures( measure ) { 7202 return Math.round( parseFloat( measure ) ); 7203 } 7204 7205 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, 7206 reliableTrDimensionsVal, reliableMarginLeftVal, 7207 container = document.createElement( "div" ), 7208 div = document.createElement( "div" ); 7209 7210 // Finish early in limited (non-browser) environments 7211 if ( !div.style ) { 7212 return; 7213 } 7214 7215 // Support: IE <=9 - 11 only 7216 // Style of cloned element affects source element cloned (trac-8908) 7217 div.style.backgroundClip = "content-box"; 7218 div.cloneNode( true ).style.backgroundClip = ""; 7219 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 7220 7221 jQuery.extend( support, { 7222 boxSizingReliable: function() { 7223 computeStyleTests(); 7224 return boxSizingReliableVal; 7225 }, 7226 pixelBoxStyles: function() { 7227 computeStyleTests(); 7228 return pixelBoxStylesVal; 7229 }, 7230 pixelPosition: function() { 7231 computeStyleTests(); 7232 return pixelPositionVal; 7233 }, 7234 reliableMarginLeft: function() { 7235 computeStyleTests(); 7236 return reliableMarginLeftVal; 7237 }, 7238 scrollboxSize: function() { 7239 computeStyleTests(); 7240 return scrollboxSizeVal; 7241 }, 7242 7243 // Support: IE 9 - 11+, Edge 15 - 18+ 7244 // IE/Edge misreport `getComputedStyle` of table rows with width/height 7245 // set in CSS while `offset*` properties report correct values. 7246 // Behavior in IE 9 is more subtle than in newer versions & it passes 7247 // some versions of this test; make sure not to make it pass there! 7248 // 7249 // Support: Firefox 70+ 7250 // Only Firefox includes border widths 7251 // in computed dimensions. (gh-4529) 7252 reliableTrDimensions: function() { 7253 var table, tr, trChild, trStyle; 7254 if ( reliableTrDimensionsVal == null ) { 7255 table = document.createElement( "table" ); 7256 tr = document.createElement( "tr" ); 7257 trChild = document.createElement( "div" ); 7258 7259 table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; 7260 tr.style.cssText = "box-sizing:content-box;border:1px solid"; 7261 7262 // Support: Chrome 86+ 7263 // Height set through cssText does not get applied. 7264 // Computed height then comes back as 0. 7265 tr.style.height = "1px"; 7266 trChild.style.height = "9px"; 7267 7268 // Support: Android 8 Chrome 86+ 7269 // In our bodyBackground.html iframe, 7270 // display for all div elements is set to "inline", 7271 // which causes a problem only in Android 8 Chrome 86. 7272 // Ensuring the div is `display: block` 7273 // gets around this issue. 7274 trChild.style.display = "block"; 7275 7276 documentElement 7277 .appendChild( table ) 7278 .appendChild( tr ) 7279 .appendChild( trChild ); 7280 7281 trStyle = window.getComputedStyle( tr ); 7282 reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + 7283 parseInt( trStyle.borderTopWidth, 10 ) + 7284 parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; 7285 7286 documentElement.removeChild( table ); 7287 } 7288 return reliableTrDimensionsVal; 7289 } 7290 } ); 7291} )(); 7292 7293 7294function curCSS( elem, name, computed ) { 7295 var width, minWidth, maxWidth, ret, 7296 isCustomProp = rcustomProp.test( name ), 7297 7298 // Support: Firefox 51+ 7299 // Retrieving style before computed somehow 7300 // fixes an issue with getting wrong values 7301 // on detached elements 7302 style = elem.style; 7303 7304 computed = computed || getStyles( elem ); 7305 7306 // getPropertyValue is needed for: 7307 // .css('filter') (IE 9 only, trac-12537) 7308 // .css('--customProperty) (gh-3144) 7309 if ( computed ) { 7310 7311 // Support: IE <=9 - 11+ 7312 // IE only supports `"float"` in `getPropertyValue`; in computed styles 7313 // it's only available as `"cssFloat"`. We no longer modify properties 7314 // sent to `.css()` apart from camelCasing, so we need to check both. 7315 // Normally, this would create difference in behavior: if 7316 // `getPropertyValue` returns an empty string, the value returned 7317 // by `.css()` would be `undefined`. This is usually the case for 7318 // disconnected elements. However, in IE even disconnected elements 7319 // with no styles return `"none"` for `getPropertyValue( "float" )` 7320 ret = computed.getPropertyValue( name ) || computed[ name ]; 7321 7322 if ( isCustomProp && ret ) { 7323 7324 // Support: Firefox 105+, Chrome <=105+ 7325 // Spec requires trimming whitespace for custom properties (gh-4926). 7326 // Firefox only trims leading whitespace. Chrome just collapses 7327 // both leading & trailing whitespace to a single space. 7328 // 7329 // Fall back to `undefined` if empty string returned. 7330 // This collapses a missing definition with property defined 7331 // and set to an empty string but there's no standard API 7332 // allowing us to differentiate them without a performance penalty 7333 // and returning `undefined` aligns with older jQuery. 7334 // 7335 // rtrimCSS treats U+000D CARRIAGE RETURN and U+000C FORM FEED 7336 // as whitespace while CSS does not, but this is not a problem 7337 // because CSS preprocessing replaces them with U+000A LINE FEED 7338 // (which *is* CSS whitespace) 7339 // https://www.w3.org/TR/css-syntax-3/#input-preprocessing 7340 ret = ret.replace( rtrimCSS, "$1" ) || undefined; 7341 } 7342 7343 if ( ret === "" && !isAttached( elem ) ) { 7344 ret = jQuery.style( elem, name ); 7345 } 7346 7347 // A tribute to the "awesome hack by Dean Edwards" 7348 // Android Browser returns percentage for some values, 7349 // but width seems to be reliably pixels. 7350 // This is against the CSSOM draft spec: 7351 // https://drafts.csswg.org/cssom/#resolved-values 7352 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { 7353 7354 // Remember the original values 7355 width = style.width; 7356 minWidth = style.minWidth; 7357 maxWidth = style.maxWidth; 7358 7359 // Put in the new values to get a computed value out 7360 style.minWidth = style.maxWidth = style.width = ret; 7361 ret = computed.width; 7362 7363 // Revert the changed values 7364 style.width = width; 7365 style.minWidth = minWidth; 7366 style.maxWidth = maxWidth; 7367 } 7368 } 7369 7370 return ret !== undefined ? 7371 7372 // Support: IE <=9 - 11 only 7373 // IE returns zIndex value as an integer. 7374 ret + "" : 7375 ret; 7376} 7377 7378 7379function addGetHookIf( conditionFn, hookFn ) { 7380 7381 // Define the hook, we'll check on the first run if it's really needed. 7382 return { 7383 get: function() { 7384 if ( conditionFn() ) { 7385 7386 // Hook not needed (or it's not possible to use it due 7387 // to missing dependency), remove it. 7388 delete this.get; 7389 return; 7390 } 7391 7392 // Hook needed; redefine it so that the support test is not executed again. 7393 return ( this.get = hookFn ).apply( this, arguments ); 7394 } 7395 }; 7396} 7397 7398 7399var cssPrefixes = [ "Webkit", "Moz", "ms" ], 7400 emptyStyle = document.createElement( "div" ).style, 7401 vendorProps = {}; 7402 7403// Return a vendor-prefixed property or undefined 7404function vendorPropName( name ) { 7405 7406 // Check for vendor prefixed names 7407 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 7408 i = cssPrefixes.length; 7409 7410 while ( i-- ) { 7411 name = cssPrefixes[ i ] + capName; 7412 if ( name in emptyStyle ) { 7413 return name; 7414 } 7415 } 7416} 7417 7418// Return a potentially-mapped jQuery.cssProps or vendor prefixed property 7419function finalPropName( name ) { 7420 var final = jQuery.cssProps[ name ] || vendorProps[ name ]; 7421 7422 if ( final ) { 7423 return final; 7424 } 7425 if ( name in emptyStyle ) { 7426 return name; 7427 } 7428 return vendorProps[ name ] = vendorPropName( name ) || name; 7429} 7430 7431 7432var 7433 7434 // Swappable if display is none or starts with table 7435 // except "table", "table-cell", or "table-caption" 7436 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 7437 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 7438 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 7439 cssNormalTransform = { 7440 letterSpacing: "0", 7441 fontWeight: "400" 7442 }; 7443 7444function setPositiveNumber( _elem, value, subtract ) { 7445 7446 // Any relative (+/-) values have already been 7447 // normalized at this point 7448 var matches = rcssNum.exec( value ); 7449 return matches ? 7450 7451 // Guard against undefined "subtract", e.g., when used as in cssHooks 7452 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 7453 value; 7454} 7455 7456function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { 7457 var i = dimension === "width" ? 1 : 0, 7458 extra = 0, 7459 delta = 0, 7460 marginDelta = 0; 7461 7462 // Adjustment may not be necessary 7463 if ( box === ( isBorderBox ? "border" : "content" ) ) { 7464 return 0; 7465 } 7466 7467 for ( ; i < 4; i += 2 ) { 7468 7469 // Both box models exclude margin 7470 // Count margin delta separately to only add it after scroll gutter adjustment. 7471 // This is needed to make negative margins work with `outerHeight( true )` (gh-3982). 7472 if ( box === "margin" ) { 7473 marginDelta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); 7474 } 7475 7476 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 7477 if ( !isBorderBox ) { 7478 7479 // Add padding 7480 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 7481 7482 // For "border" or "margin", add border 7483 if ( box !== "padding" ) { 7484 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 7485 7486 // But still keep track of it otherwise 7487 } else { 7488 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 7489 } 7490 7491 // If we get here with a border-box (content + padding + border), we're seeking "content" or 7492 // "padding" or "margin" 7493 } else { 7494 7495 // For "content", subtract padding 7496 if ( box === "content" ) { 7497 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 7498 } 7499 7500 // For "content" or "padding", subtract border 7501 if ( box !== "margin" ) { 7502 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 7503 } 7504 } 7505 } 7506 7507 // Account for positive content-box scroll gutter when requested by providing computedVal 7508 if ( !isBorderBox && computedVal >= 0 ) { 7509 7510 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 7511 // Assuming integer scroll gutter, subtract the rest and round down 7512 delta += Math.max( 0, Math.ceil( 7513 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 7514 computedVal - 7515 delta - 7516 extra - 7517 0.5 7518 7519 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter 7520 // Use an explicit zero to avoid NaN (gh-3964) 7521 ) ) || 0; 7522 } 7523 7524 return delta + marginDelta; 7525} 7526 7527function getWidthOrHeight( elem, dimension, extra ) { 7528 7529 // Start with computed style 7530 var styles = getStyles( elem ), 7531 7532 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). 7533 // Fake content-box until we know it's needed to know the true value. 7534 boxSizingNeeded = !support.boxSizingReliable() || extra, 7535 isBorderBox = boxSizingNeeded && 7536 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 7537 valueIsBorderBox = isBorderBox, 7538 7539 val = curCSS( elem, dimension, styles ), 7540 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); 7541 7542 // Support: Firefox <=54 7543 // Return a confounding non-pixel value or feign ignorance, as appropriate. 7544 if ( rnumnonpx.test( val ) ) { 7545 if ( !extra ) { 7546 return val; 7547 } 7548 val = "auto"; 7549 } 7550 7551 7552 // Support: IE 9 - 11 only 7553 // Use offsetWidth/offsetHeight for when box sizing is unreliable. 7554 // In those cases, the computed value can be trusted to be border-box. 7555 if ( ( !support.boxSizingReliable() && isBorderBox || 7556 7557 // Support: IE 10 - 11+, Edge 15 - 18+ 7558 // IE/Edge misreport `getComputedStyle` of table rows with width/height 7559 // set in CSS while `offset*` properties report correct values. 7560 // Interestingly, in some cases IE 9 doesn't suffer from this issue. 7561 !support.reliableTrDimensions() && nodeName( elem, "tr" ) || 7562 7563 // Fall back to offsetWidth/offsetHeight when value is "auto" 7564 // This happens for inline elements with no explicit setting (gh-3571) 7565 val === "auto" || 7566 7567 // Support: Android <=4.1 - 4.3 only 7568 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 7569 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && 7570 7571 // Make sure the element is visible & connected 7572 elem.getClientRects().length ) { 7573 7574 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 7575 7576 // Where available, offsetWidth/offsetHeight approximate border box dimensions. 7577 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the 7578 // retrieved value as a content box dimension. 7579 valueIsBorderBox = offsetProp in elem; 7580 if ( valueIsBorderBox ) { 7581 val = elem[ offsetProp ]; 7582 } 7583 } 7584 7585 // Normalize "" and auto 7586 val = parseFloat( val ) || 0; 7587 7588 // Adjust for the element's box model 7589 return ( val + 7590 boxModelAdjustment( 7591 elem, 7592 dimension, 7593 extra || ( isBorderBox ? "border" : "content" ), 7594 valueIsBorderBox, 7595 styles, 7596 7597 // Provide the current computed size to request scroll gutter calculation (gh-3589) 7598 val 7599 ) 7600 ) + "px"; 7601} 7602 7603jQuery.extend( { 7604 7605 // Add in style property hooks for overriding the default 7606 // behavior of getting and setting a style property 7607 cssHooks: { 7608 opacity: { 7609 get: function( elem, computed ) { 7610 if ( computed ) { 7611 7612 // We should always get a number back from opacity 7613 var ret = curCSS( elem, "opacity" ); 7614 return ret === "" ? "1" : ret; 7615 } 7616 } 7617 } 7618 }, 7619 7620 // Don't automatically add "px" to these possibly-unitless properties 7621 cssNumber: { 7622 animationIterationCount: true, 7623 aspectRatio: true, 7624 borderImageSlice: true, 7625 columnCount: true, 7626 flexGrow: true, 7627 flexShrink: true, 7628 fontWeight: true, 7629 gridArea: true, 7630 gridColumn: true, 7631 gridColumnEnd: true, 7632 gridColumnStart: true, 7633 gridRow: true, 7634 gridRowEnd: true, 7635 gridRowStart: true, 7636 lineHeight: true, 7637 opacity: true, 7638 order: true, 7639 orphans: true, 7640 scale: true, 7641 widows: true, 7642 zIndex: true, 7643 zoom: true, 7644 7645 // SVG-related 7646 fillOpacity: true, 7647 floodOpacity: true, 7648 stopOpacity: true, 7649 strokeMiterlimit: true, 7650 strokeOpacity: true 7651 }, 7652 7653 // Add in properties whose names you wish to fix before 7654 // setting or getting the value 7655 cssProps: {}, 7656 7657 // Get and set the style property on a DOM Node 7658 style: function( elem, name, value, extra ) { 7659 7660 // Don't set styles on text and comment nodes 7661 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 7662 return; 7663 } 7664 7665 // Make sure that we're working with the right name 7666 var ret, type, hooks, 7667 origName = camelCase( name ), 7668 isCustomProp = rcustomProp.test( name ), 7669 style = elem.style; 7670 7671 // Make sure that we're working with the right name. We don't 7672 // want to query the value if it is a CSS custom property 7673 // since they are user-defined. 7674 if ( !isCustomProp ) { 7675 name = finalPropName( origName ); 7676 } 7677 7678 // Gets hook for the prefixed version, then unprefixed version 7679 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 7680 7681 // Check if we're setting a value 7682 if ( value !== undefined ) { 7683 type = typeof value; 7684 7685 // Convert "+=" or "-=" to relative numbers (trac-7345) 7686 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 7687 value = adjustCSS( elem, name, ret ); 7688 7689 // Fixes bug trac-9237 7690 type = "number"; 7691 } 7692 7693 // Make sure that null and NaN values aren't set (trac-7116) 7694 if ( value == null || value !== value ) { 7695 return; 7696 } 7697 7698 // If a number was passed in, add the unit (except for certain CSS properties) 7699 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append 7700 // "px" to a few hardcoded values. 7701 if ( type === "number" && !isCustomProp ) { 7702 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 7703 } 7704 7705 // background-* props affect original clone's values 7706 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 7707 style[ name ] = "inherit"; 7708 } 7709 7710 // If a hook was provided, use that value, otherwise just set the specified value 7711 if ( !hooks || !( "set" in hooks ) || 7712 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 7713 7714 if ( isCustomProp ) { 7715 style.setProperty( name, value ); 7716 } else { 7717 style[ name ] = value; 7718 } 7719 } 7720 7721 } else { 7722 7723 // If a hook was provided get the non-computed value from there 7724 if ( hooks && "get" in hooks && 7725 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 7726 7727 return ret; 7728 } 7729 7730 // Otherwise just get the value from the style object 7731 return style[ name ]; 7732 } 7733 }, 7734 7735 css: function( elem, name, extra, styles ) { 7736 var val, num, hooks, 7737 origName = camelCase( name ), 7738 isCustomProp = rcustomProp.test( name ); 7739 7740 // Make sure that we're working with the right name. We don't 7741 // want to modify the value if it is a CSS custom property 7742 // since they are user-defined. 7743 if ( !isCustomProp ) { 7744 name = finalPropName( origName ); 7745 } 7746 7747 // Try prefixed name followed by the unprefixed name 7748 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 7749 7750 // If a hook was provided get the computed value from there 7751 if ( hooks && "get" in hooks ) { 7752 val = hooks.get( elem, true, extra ); 7753 } 7754 7755 // Otherwise, if a way to get the computed value exists, use that 7756 if ( val === undefined ) { 7757 val = curCSS( elem, name, styles ); 7758 } 7759 7760 // Convert "normal" to computed value 7761 if ( val === "normal" && name in cssNormalTransform ) { 7762 val = cssNormalTransform[ name ]; 7763 } 7764 7765 // Make numeric if forced or a qualifier was provided and val looks numeric 7766 if ( extra === "" || extra ) { 7767 num = parseFloat( val ); 7768 return extra === true || isFinite( num ) ? num || 0 : val; 7769 } 7770 7771 return val; 7772 } 7773} ); 7774 7775jQuery.each( [ "height", "width" ], function( _i, dimension ) { 7776 jQuery.cssHooks[ dimension ] = { 7777 get: function( elem, computed, extra ) { 7778 if ( computed ) { 7779 7780 // Certain elements can have dimension info if we invisibly show them 7781 // but it must have a current display style that would benefit 7782 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 7783 7784 // Support: Safari 8+ 7785 // Table columns in Safari have non-zero offsetWidth & zero 7786 // getBoundingClientRect().width unless display is changed. 7787 // Support: IE <=11 only 7788 // Running getBoundingClientRect on a disconnected node 7789 // in IE throws an error. 7790 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? 7791 swap( elem, cssShow, function() { 7792 return getWidthOrHeight( elem, dimension, extra ); 7793 } ) : 7794 getWidthOrHeight( elem, dimension, extra ); 7795 } 7796 }, 7797 7798 set: function( elem, value, extra ) { 7799 var matches, 7800 styles = getStyles( elem ), 7801 7802 // Only read styles.position if the test has a chance to fail 7803 // to avoid forcing a reflow. 7804 scrollboxSizeBuggy = !support.scrollboxSize() && 7805 styles.position === "absolute", 7806 7807 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) 7808 boxSizingNeeded = scrollboxSizeBuggy || extra, 7809 isBorderBox = boxSizingNeeded && 7810 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 7811 subtract = extra ? 7812 boxModelAdjustment( 7813 elem, 7814 dimension, 7815 extra, 7816 isBorderBox, 7817 styles 7818 ) : 7819 0; 7820 7821 // Account for unreliable border-box dimensions by comparing offset* to computed and 7822 // faking a content-box to get border and padding (gh-3699) 7823 if ( isBorderBox && scrollboxSizeBuggy ) { 7824 subtract -= Math.ceil( 7825 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 7826 parseFloat( styles[ dimension ] ) - 7827 boxModelAdjustment( elem, dimension, "border", false, styles ) - 7828 0.5 7829 ); 7830 } 7831 7832 // Convert to pixels if value adjustment is needed 7833 if ( subtract && ( matches = rcssNum.exec( value ) ) && 7834 ( matches[ 3 ] || "px" ) !== "px" ) { 7835 7836 elem.style[ dimension ] = value; 7837 value = jQuery.css( elem, dimension ); 7838 } 7839 7840 return setPositiveNumber( elem, value, subtract ); 7841 } 7842 }; 7843} ); 7844 7845jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 7846 function( elem, computed ) { 7847 if ( computed ) { 7848 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 7849 elem.getBoundingClientRect().left - 7850 swap( elem, { marginLeft: 0 }, function() { 7851 return elem.getBoundingClientRect().left; 7852 } ) 7853 ) + "px"; 7854 } 7855 } 7856); 7857 7858// These hooks are used by animate to expand properties 7859jQuery.each( { 7860 margin: "", 7861 padding: "", 7862 border: "Width" 7863}, function( prefix, suffix ) { 7864 jQuery.cssHooks[ prefix + suffix ] = { 7865 expand: function( value ) { 7866 var i = 0, 7867 expanded = {}, 7868 7869 // Assumes a single number if not a string 7870 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 7871 7872 for ( ; i < 4; i++ ) { 7873 expanded[ prefix + cssExpand[ i ] + suffix ] = 7874 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 7875 } 7876 7877 return expanded; 7878 } 7879 }; 7880 7881 if ( prefix !== "margin" ) { 7882 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 7883 } 7884} ); 7885 7886jQuery.fn.extend( { 7887 css: function( name, value ) { 7888 return access( this, function( elem, name, value ) { 7889 var styles, len, 7890 map = {}, 7891 i = 0; 7892 7893 if ( Array.isArray( name ) ) { 7894 styles = getStyles( elem ); 7895 len = name.length; 7896 7897 for ( ; i < len; i++ ) { 7898 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 7899 } 7900 7901 return map; 7902 } 7903 7904 return value !== undefined ? 7905 jQuery.style( elem, name, value ) : 7906 jQuery.css( elem, name ); 7907 }, name, value, arguments.length > 1 ); 7908 } 7909} ); 7910 7911 7912function Tween( elem, options, prop, end, easing ) { 7913 return new Tween.prototype.init( elem, options, prop, end, easing ); 7914} 7915jQuery.Tween = Tween; 7916 7917Tween.prototype = { 7918 constructor: Tween, 7919 init: function( elem, options, prop, end, easing, unit ) { 7920 this.elem = elem; 7921 this.prop = prop; 7922 this.easing = easing || jQuery.easing._default; 7923 this.options = options; 7924 this.start = this.now = this.cur(); 7925 this.end = end; 7926 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 7927 }, 7928 cur: function() { 7929 var hooks = Tween.propHooks[ this.prop ]; 7930 7931 return hooks && hooks.get ? 7932 hooks.get( this ) : 7933 Tween.propHooks._default.get( this ); 7934 }, 7935 run: function( percent ) { 7936 var eased, 7937 hooks = Tween.propHooks[ this.prop ]; 7938 7939 if ( this.options.duration ) { 7940 this.pos = eased = jQuery.easing[ this.easing ]( 7941 percent, this.options.duration * percent, 0, 1, this.options.duration 7942 ); 7943 } else { 7944 this.pos = eased = percent; 7945 } 7946 this.now = ( this.end - this.start ) * eased + this.start; 7947 7948 if ( this.options.step ) { 7949 this.options.step.call( this.elem, this.now, this ); 7950 } 7951 7952 if ( hooks && hooks.set ) { 7953 hooks.set( this ); 7954 } else { 7955 Tween.propHooks._default.set( this ); 7956 } 7957 return this; 7958 } 7959}; 7960 7961Tween.prototype.init.prototype = Tween.prototype; 7962 7963Tween.propHooks = { 7964 _default: { 7965 get: function( tween ) { 7966 var result; 7967 7968 // Use a property on the element directly when it is not a DOM element, 7969 // or when there is no matching style property that exists. 7970 if ( tween.elem.nodeType !== 1 || 7971 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 7972 return tween.elem[ tween.prop ]; 7973 } 7974 7975 // Passing an empty string as a 3rd parameter to .css will automatically 7976 // attempt a parseFloat and fallback to a string if the parse fails. 7977 // Simple values such as "10px" are parsed to Float; 7978 // complex values such as "rotate(1rad)" are returned as-is. 7979 result = jQuery.css( tween.elem, tween.prop, "" ); 7980 7981 // Empty strings, null, undefined and "auto" are converted to 0. 7982 return !result || result === "auto" ? 0 : result; 7983 }, 7984 set: function( tween ) { 7985 7986 // Use step hook for back compat. 7987 // Use cssHook if its there. 7988 // Use .style if available and use plain properties where available. 7989 if ( jQuery.fx.step[ tween.prop ] ) { 7990 jQuery.fx.step[ tween.prop ]( tween ); 7991 } else if ( tween.elem.nodeType === 1 && ( 7992 jQuery.cssHooks[ tween.prop ] || 7993 tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { 7994 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 7995 } else { 7996 tween.elem[ tween.prop ] = tween.now; 7997 } 7998 } 7999 } 8000}; 8001 8002// Support: IE <=9 only 8003// Panic based approach to setting things on disconnected nodes 8004Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 8005 set: function( tween ) { 8006 if ( tween.elem.nodeType && tween.elem.parentNode ) { 8007 tween.elem[ tween.prop ] = tween.now; 8008 } 8009 } 8010}; 8011 8012jQuery.easing = { 8013 linear: function( p ) { 8014 return p; 8015 }, 8016 swing: function( p ) { 8017 return 0.5 - Math.cos( p * Math.PI ) / 2; 8018 }, 8019 _default: "swing" 8020}; 8021 8022jQuery.fx = Tween.prototype.init; 8023 8024// Back compat <1.8 extension point 8025jQuery.fx.step = {}; 8026 8027 8028 8029 8030var 8031 fxNow, inProgress, 8032 rfxtypes = /^(?:toggle|show|hide)$/, 8033 rrun = /queueHooks$/; 8034 8035function schedule() { 8036 if ( inProgress ) { 8037 if ( document.hidden === false && window.requestAnimationFrame ) { 8038 window.requestAnimationFrame( schedule ); 8039 } else { 8040 window.setTimeout( schedule, jQuery.fx.interval ); 8041 } 8042 8043 jQuery.fx.tick(); 8044 } 8045} 8046 8047// Animations created synchronously will run synchronously 8048function createFxNow() { 8049 window.setTimeout( function() { 8050 fxNow = undefined; 8051 } ); 8052 return ( fxNow = Date.now() ); 8053} 8054 8055// Generate parameters to create a standard animation 8056function genFx( type, includeWidth ) { 8057 var which, 8058 i = 0, 8059 attrs = { height: type }; 8060 8061 // If we include width, step value is 1 to do all cssExpand values, 8062 // otherwise step value is 2 to skip over Left and Right 8063 includeWidth = includeWidth ? 1 : 0; 8064 for ( ; i < 4; i += 2 - includeWidth ) { 8065 which = cssExpand[ i ]; 8066 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 8067 } 8068 8069 if ( includeWidth ) { 8070 attrs.opacity = attrs.width = type; 8071 } 8072 8073 return attrs; 8074} 8075 8076function createTween( value, prop, animation ) { 8077 var tween, 8078 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 8079 index = 0, 8080 length = collection.length; 8081 for ( ; index < length; index++ ) { 8082 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 8083 8084 // We're done with this property 8085 return tween; 8086 } 8087 } 8088} 8089 8090function defaultPrefilter( elem, props, opts ) { 8091 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, 8092 isBox = "width" in props || "height" in props, 8093 anim = this, 8094 orig = {}, 8095 style = elem.style, 8096 hidden = elem.nodeType && isHiddenWithinTree( elem ), 8097 dataShow = dataPriv.get( elem, "fxshow" ); 8098 8099 // Queue-skipping animations hijack the fx hooks 8100 if ( !opts.queue ) { 8101 hooks = jQuery._queueHooks( elem, "fx" ); 8102 if ( hooks.unqueued == null ) { 8103 hooks.unqueued = 0; 8104 oldfire = hooks.empty.fire; 8105 hooks.empty.fire = function() { 8106 if ( !hooks.unqueued ) { 8107 oldfire(); 8108 } 8109 }; 8110 } 8111 hooks.unqueued++; 8112 8113 anim.always( function() { 8114 8115 // Ensure the complete handler is called before this completes 8116 anim.always( function() { 8117 hooks.unqueued--; 8118 if ( !jQuery.queue( elem, "fx" ).length ) { 8119 hooks.empty.fire(); 8120 } 8121 } ); 8122 } ); 8123 } 8124 8125 // Detect show/hide animations 8126 for ( prop in props ) { 8127 value = props[ prop ]; 8128 if ( rfxtypes.test( value ) ) { 8129 delete props[ prop ]; 8130 toggle = toggle || value === "toggle"; 8131 if ( value === ( hidden ? "hide" : "show" ) ) { 8132 8133 // Pretend to be hidden if this is a "show" and 8134 // there is still data from a stopped show/hide 8135 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 8136 hidden = true; 8137 8138 // Ignore all other no-op show/hide data 8139 } else { 8140 continue; 8141 } 8142 } 8143 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 8144 } 8145 } 8146 8147 // Bail out if this is a no-op like .hide().hide() 8148 propTween = !jQuery.isEmptyObject( props ); 8149 if ( !propTween && jQuery.isEmptyObject( orig ) ) { 8150 return; 8151 } 8152 8153 // Restrict "overflow" and "display" styles during box animations 8154 if ( isBox && elem.nodeType === 1 ) { 8155 8156 // Support: IE <=9 - 11, Edge 12 - 15 8157 // Record all 3 overflow attributes because IE does not infer the shorthand 8158 // from identically-valued overflowX and overflowY and Edge just mirrors 8159 // the overflowX value there. 8160 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 8161 8162 // Identify a display type, preferring old show/hide data over the CSS cascade 8163 restoreDisplay = dataShow && dataShow.display; 8164 if ( restoreDisplay == null ) { 8165 restoreDisplay = dataPriv.get( elem, "display" ); 8166 } 8167 display = jQuery.css( elem, "display" ); 8168 if ( display === "none" ) { 8169 if ( restoreDisplay ) { 8170 display = restoreDisplay; 8171 } else { 8172 8173 // Get nonempty value(s) by temporarily forcing visibility 8174 showHide( [ elem ], true ); 8175 restoreDisplay = elem.style.display || restoreDisplay; 8176 display = jQuery.css( elem, "display" ); 8177 showHide( [ elem ] ); 8178 } 8179 } 8180 8181 // Animate inline elements as inline-block 8182 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { 8183 if ( jQuery.css( elem, "float" ) === "none" ) { 8184 8185 // Restore the original display value at the end of pure show/hide animations 8186 if ( !propTween ) { 8187 anim.done( function() { 8188 style.display = restoreDisplay; 8189 } ); 8190 if ( restoreDisplay == null ) { 8191 display = style.display; 8192 restoreDisplay = display === "none" ? "" : display; 8193 } 8194 } 8195 style.display = "inline-block"; 8196 } 8197 } 8198 } 8199 8200 if ( opts.overflow ) { 8201 style.overflow = "hidden"; 8202 anim.always( function() { 8203 style.overflow = opts.overflow[ 0 ]; 8204 style.overflowX = opts.overflow[ 1 ]; 8205 style.overflowY = opts.overflow[ 2 ]; 8206 } ); 8207 } 8208 8209 // Implement show/hide animations 8210 propTween = false; 8211 for ( prop in orig ) { 8212 8213 // General show/hide setup for this element animation 8214 if ( !propTween ) { 8215 if ( dataShow ) { 8216 if ( "hidden" in dataShow ) { 8217 hidden = dataShow.hidden; 8218 } 8219 } else { 8220 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); 8221 } 8222 8223 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 8224 if ( toggle ) { 8225 dataShow.hidden = !hidden; 8226 } 8227 8228 // Show elements before animating them 8229 if ( hidden ) { 8230 showHide( [ elem ], true ); 8231 } 8232 8233 /* eslint-disable no-loop-func */ 8234 8235 anim.done( function() { 8236 8237 /* eslint-enable no-loop-func */ 8238 8239 // The final step of a "hide" animation is actually hiding the element 8240 if ( !hidden ) { 8241 showHide( [ elem ] ); 8242 } 8243 dataPriv.remove( elem, "fxshow" ); 8244 for ( prop in orig ) { 8245 jQuery.style( elem, prop, orig[ prop ] ); 8246 } 8247 } ); 8248 } 8249 8250 // Per-property setup 8251 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 8252 if ( !( prop in dataShow ) ) { 8253 dataShow[ prop ] = propTween.start; 8254 if ( hidden ) { 8255 propTween.end = propTween.start; 8256 propTween.start = 0; 8257 } 8258 } 8259 } 8260} 8261 8262function propFilter( props, specialEasing ) { 8263 var index, name, easing, value, hooks; 8264 8265 // camelCase, specialEasing and expand cssHook pass 8266 for ( index in props ) { 8267 name = camelCase( index ); 8268 easing = specialEasing[ name ]; 8269 value = props[ index ]; 8270 if ( Array.isArray( value ) ) { 8271 easing = value[ 1 ]; 8272 value = props[ index ] = value[ 0 ]; 8273 } 8274 8275 if ( index !== name ) { 8276 props[ name ] = value; 8277 delete props[ index ]; 8278 } 8279 8280 hooks = jQuery.cssHooks[ name ]; 8281 if ( hooks && "expand" in hooks ) { 8282 value = hooks.expand( value ); 8283 delete props[ name ]; 8284 8285 // Not quite $.extend, this won't overwrite existing keys. 8286 // Reusing 'index' because we have the correct "name" 8287 for ( index in value ) { 8288 if ( !( index in props ) ) { 8289 props[ index ] = value[ index ]; 8290 specialEasing[ index ] = easing; 8291 } 8292 } 8293 } else { 8294 specialEasing[ name ] = easing; 8295 } 8296 } 8297} 8298 8299function Animation( elem, properties, options ) { 8300 var result, 8301 stopped, 8302 index = 0, 8303 length = Animation.prefilters.length, 8304 deferred = jQuery.Deferred().always( function() { 8305 8306 // Don't match elem in the :animated selector 8307 delete tick.elem; 8308 } ), 8309 tick = function() { 8310 if ( stopped ) { 8311 return false; 8312 } 8313 var currentTime = fxNow || createFxNow(), 8314 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 8315 8316 // Support: Android 2.3 only 8317 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (trac-12497) 8318 temp = remaining / animation.duration || 0, 8319 percent = 1 - temp, 8320 index = 0, 8321 length = animation.tweens.length; 8322 8323 for ( ; index < length; index++ ) { 8324 animation.tweens[ index ].run( percent ); 8325 } 8326 8327 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 8328 8329 // If there's more to do, yield 8330 if ( percent < 1 && length ) { 8331 return remaining; 8332 } 8333 8334 // If this was an empty animation, synthesize a final progress notification 8335 if ( !length ) { 8336 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 8337 } 8338 8339 // Resolve the animation and report its conclusion 8340 deferred.resolveWith( elem, [ animation ] ); 8341 return false; 8342 }, 8343 animation = deferred.promise( { 8344 elem: elem, 8345 props: jQuery.extend( {}, properties ), 8346 opts: jQuery.extend( true, { 8347 specialEasing: {}, 8348 easing: jQuery.easing._default 8349 }, options ), 8350 originalProperties: properties, 8351 originalOptions: options, 8352 startTime: fxNow || createFxNow(), 8353 duration: options.duration, 8354 tweens: [], 8355 createTween: function( prop, end ) { 8356 var tween = jQuery.Tween( elem, animation.opts, prop, end, 8357 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 8358 animation.tweens.push( tween ); 8359 return tween; 8360 }, 8361 stop: function( gotoEnd ) { 8362 var index = 0, 8363 8364 // If we are going to the end, we want to run all the tweens 8365 // otherwise we skip this part 8366 length = gotoEnd ? animation.tweens.length : 0; 8367 if ( stopped ) { 8368 return this; 8369 } 8370 stopped = true; 8371 for ( ; index < length; index++ ) { 8372 animation.tweens[ index ].run( 1 ); 8373 } 8374 8375 // Resolve when we played the last frame; otherwise, reject 8376 if ( gotoEnd ) { 8377 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 8378 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 8379 } else { 8380 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 8381 } 8382 return this; 8383 } 8384 } ), 8385 props = animation.props; 8386 8387 propFilter( props, animation.opts.specialEasing ); 8388 8389 for ( ; index < length; index++ ) { 8390 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 8391 if ( result ) { 8392 if ( isFunction( result.stop ) ) { 8393 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 8394 result.stop.bind( result ); 8395 } 8396 return result; 8397 } 8398 } 8399 8400 jQuery.map( props, createTween, animation ); 8401 8402 if ( isFunction( animation.opts.start ) ) { 8403 animation.opts.start.call( elem, animation ); 8404 } 8405 8406 // Attach callbacks from options 8407 animation 8408 .progress( animation.opts.progress ) 8409 .done( animation.opts.done, animation.opts.complete ) 8410 .fail( animation.opts.fail ) 8411 .always( animation.opts.always ); 8412 8413 jQuery.fx.timer( 8414 jQuery.extend( tick, { 8415 elem: elem, 8416 anim: animation, 8417 queue: animation.opts.queue 8418 } ) 8419 ); 8420 8421 return animation; 8422} 8423 8424jQuery.Animation = jQuery.extend( Animation, { 8425 8426 tweeners: { 8427 "*": [ function( prop, value ) { 8428 var tween = this.createTween( prop, value ); 8429 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 8430 return tween; 8431 } ] 8432 }, 8433 8434 tweener: function( props, callback ) { 8435 if ( isFunction( props ) ) { 8436 callback = props; 8437 props = [ "*" ]; 8438 } else { 8439 props = props.match( rnothtmlwhite ); 8440 } 8441 8442 var prop, 8443 index = 0, 8444 length = props.length; 8445 8446 for ( ; index < length; index++ ) { 8447 prop = props[ index ]; 8448 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 8449 Animation.tweeners[ prop ].unshift( callback ); 8450 } 8451 }, 8452 8453 prefilters: [ defaultPrefilter ], 8454 8455 prefilter: function( callback, prepend ) { 8456 if ( prepend ) { 8457 Animation.prefilters.unshift( callback ); 8458 } else { 8459 Animation.prefilters.push( callback ); 8460 } 8461 } 8462} ); 8463 8464jQuery.speed = function( speed, easing, fn ) { 8465 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 8466 complete: fn || !fn && easing || 8467 isFunction( speed ) && speed, 8468 duration: speed, 8469 easing: fn && easing || easing && !isFunction( easing ) && easing 8470 }; 8471 8472 // Go to the end state if fx are off 8473 if ( jQuery.fx.off ) { 8474 opt.duration = 0; 8475 8476 } else { 8477 if ( typeof opt.duration !== "number" ) { 8478 if ( opt.duration in jQuery.fx.speeds ) { 8479 opt.duration = jQuery.fx.speeds[ opt.duration ]; 8480 8481 } else { 8482 opt.duration = jQuery.fx.speeds._default; 8483 } 8484 } 8485 } 8486 8487 // Normalize opt.queue - true/undefined/null -> "fx" 8488 if ( opt.queue == null || opt.queue === true ) { 8489 opt.queue = "fx"; 8490 } 8491 8492 // Queueing 8493 opt.old = opt.complete; 8494 8495 opt.complete = function() { 8496 if ( isFunction( opt.old ) ) { 8497 opt.old.call( this ); 8498 } 8499 8500 if ( opt.queue ) { 8501 jQuery.dequeue( this, opt.queue ); 8502 } 8503 }; 8504 8505 return opt; 8506}; 8507 8508jQuery.fn.extend( { 8509 fadeTo: function( speed, to, easing, callback ) { 8510 8511 // Show any hidden elements after setting opacity to 0 8512 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() 8513 8514 // Animate to the value specified 8515 .end().animate( { opacity: to }, speed, easing, callback ); 8516 }, 8517 animate: function( prop, speed, easing, callback ) { 8518 var empty = jQuery.isEmptyObject( prop ), 8519 optall = jQuery.speed( speed, easing, callback ), 8520 doAnimation = function() { 8521 8522 // Operate on a copy of prop so per-property easing won't be lost 8523 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 8524 8525 // Empty animations, or finishing resolves immediately 8526 if ( empty || dataPriv.get( this, "finish" ) ) { 8527 anim.stop( true ); 8528 } 8529 }; 8530 8531 doAnimation.finish = doAnimation; 8532 8533 return empty || optall.queue === false ? 8534 this.each( doAnimation ) : 8535 this.queue( optall.queue, doAnimation ); 8536 }, 8537 stop: function( type, clearQueue, gotoEnd ) { 8538 var stopQueue = function( hooks ) { 8539 var stop = hooks.stop; 8540 delete hooks.stop; 8541 stop( gotoEnd ); 8542 }; 8543 8544 if ( typeof type !== "string" ) { 8545 gotoEnd = clearQueue; 8546 clearQueue = type; 8547 type = undefined; 8548 } 8549 if ( clearQueue ) { 8550 this.queue( type || "fx", [] ); 8551 } 8552 8553 return this.each( function() { 8554 var dequeue = true, 8555 index = type != null && type + "queueHooks", 8556 timers = jQuery.timers, 8557 data = dataPriv.get( this ); 8558 8559 if ( index ) { 8560 if ( data[ index ] && data[ index ].stop ) { 8561 stopQueue( data[ index ] ); 8562 } 8563 } else { 8564 for ( index in data ) { 8565 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 8566 stopQueue( data[ index ] ); 8567 } 8568 } 8569 } 8570 8571 for ( index = timers.length; index--; ) { 8572 if ( timers[ index ].elem === this && 8573 ( type == null || timers[ index ].queue === type ) ) { 8574 8575 timers[ index ].anim.stop( gotoEnd ); 8576 dequeue = false; 8577 timers.splice( index, 1 ); 8578 } 8579 } 8580 8581 // Start the next in the queue if the last step wasn't forced. 8582 // Timers currently will call their complete callbacks, which 8583 // will dequeue but only if they were gotoEnd. 8584 if ( dequeue || !gotoEnd ) { 8585 jQuery.dequeue( this, type ); 8586 } 8587 } ); 8588 }, 8589 finish: function( type ) { 8590 if ( type !== false ) { 8591 type = type || "fx"; 8592 } 8593 return this.each( function() { 8594 var index, 8595 data = dataPriv.get( this ), 8596 queue = data[ type + "queue" ], 8597 hooks = data[ type + "queueHooks" ], 8598 timers = jQuery.timers, 8599 length = queue ? queue.length : 0; 8600 8601 // Enable finishing flag on private data 8602 data.finish = true; 8603 8604 // Empty the queue first 8605 jQuery.queue( this, type, [] ); 8606 8607 if ( hooks && hooks.stop ) { 8608 hooks.stop.call( this, true ); 8609 } 8610 8611 // Look for any active animations, and finish them 8612 for ( index = timers.length; index--; ) { 8613 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 8614 timers[ index ].anim.stop( true ); 8615 timers.splice( index, 1 ); 8616 } 8617 } 8618 8619 // Look for any animations in the old queue and finish them 8620 for ( index = 0; index < length; index++ ) { 8621 if ( queue[ index ] && queue[ index ].finish ) { 8622 queue[ index ].finish.call( this ); 8623 } 8624 } 8625 8626 // Turn off finishing flag 8627 delete data.finish; 8628 } ); 8629 } 8630} ); 8631 8632jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { 8633 var cssFn = jQuery.fn[ name ]; 8634 jQuery.fn[ name ] = function( speed, easing, callback ) { 8635 return speed == null || typeof speed === "boolean" ? 8636 cssFn.apply( this, arguments ) : 8637 this.animate( genFx( name, true ), speed, easing, callback ); 8638 }; 8639} ); 8640 8641// Generate shortcuts for custom animations 8642jQuery.each( { 8643 slideDown: genFx( "show" ), 8644 slideUp: genFx( "hide" ), 8645 slideToggle: genFx( "toggle" ), 8646 fadeIn: { opacity: "show" }, 8647 fadeOut: { opacity: "hide" }, 8648 fadeToggle: { opacity: "toggle" } 8649}, function( name, props ) { 8650 jQuery.fn[ name ] = function( speed, easing, callback ) { 8651 return this.animate( props, speed, easing, callback ); 8652 }; 8653} ); 8654 8655jQuery.timers = []; 8656jQuery.fx.tick = function() { 8657 var timer, 8658 i = 0, 8659 timers = jQuery.timers; 8660 8661 fxNow = Date.now(); 8662 8663 for ( ; i < timers.length; i++ ) { 8664 timer = timers[ i ]; 8665 8666 // Run the timer and safely remove it when done (allowing for external removal) 8667 if ( !timer() && timers[ i ] === timer ) { 8668 timers.splice( i--, 1 ); 8669 } 8670 } 8671 8672 if ( !timers.length ) { 8673 jQuery.fx.stop(); 8674 } 8675 fxNow = undefined; 8676}; 8677 8678jQuery.fx.timer = function( timer ) { 8679 jQuery.timers.push( timer ); 8680 jQuery.fx.start(); 8681}; 8682 8683jQuery.fx.interval = 13; 8684jQuery.fx.start = function() { 8685 if ( inProgress ) { 8686 return; 8687 } 8688 8689 inProgress = true; 8690 schedule(); 8691}; 8692 8693jQuery.fx.stop = function() { 8694 inProgress = null; 8695}; 8696 8697jQuery.fx.speeds = { 8698 slow: 600, 8699 fast: 200, 8700 8701 // Default speed 8702 _default: 400 8703}; 8704 8705 8706// Based off of the plugin by Clint Helfers, with permission. 8707jQuery.fn.delay = function( time, type ) { 8708 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 8709 type = type || "fx"; 8710 8711 return this.queue( type, function( next, hooks ) { 8712 var timeout = window.setTimeout( next, time ); 8713 hooks.stop = function() { 8714 window.clearTimeout( timeout ); 8715 }; 8716 } ); 8717}; 8718 8719 8720( function() { 8721 var input = document.createElement( "input" ), 8722 select = document.createElement( "select" ), 8723 opt = select.appendChild( document.createElement( "option" ) ); 8724 8725 input.type = "checkbox"; 8726 8727 // Support: Android <=4.3 only 8728 // Default value for a checkbox should be "on" 8729 support.checkOn = input.value !== ""; 8730 8731 // Support: IE <=11 only 8732 // Must access selectedIndex to make default options select 8733 support.optSelected = opt.selected; 8734 8735 // Support: IE <=11 only 8736 // An input loses its value after becoming a radio 8737 input = document.createElement( "input" ); 8738 input.value = "t"; 8739 input.type = "radio"; 8740 support.radioValue = input.value === "t"; 8741} )(); 8742 8743 8744var boolHook, 8745 attrHandle = jQuery.expr.attrHandle; 8746 8747jQuery.fn.extend( { 8748 attr: function( name, value ) { 8749 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 8750 }, 8751 8752 removeAttr: function( name ) { 8753 return this.each( function() { 8754 jQuery.removeAttr( this, name ); 8755 } ); 8756 } 8757} ); 8758 8759jQuery.extend( { 8760 attr: function( elem, name, value ) { 8761 var ret, hooks, 8762 nType = elem.nodeType; 8763 8764 // Don't get/set attributes on text, comment and attribute nodes 8765 if ( nType === 3 || nType === 8 || nType === 2 ) { 8766 return; 8767 } 8768 8769 // Fallback to prop when attributes are not supported 8770 if ( typeof elem.getAttribute === "undefined" ) { 8771 return jQuery.prop( elem, name, value ); 8772 } 8773 8774 // Attribute hooks are determined by the lowercase version 8775 // Grab necessary hook if one is defined 8776 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 8777 hooks = jQuery.attrHooks[ name.toLowerCase() ] || 8778 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 8779 } 8780 8781 if ( value !== undefined ) { 8782 if ( value === null ) { 8783 jQuery.removeAttr( elem, name ); 8784 return; 8785 } 8786 8787 if ( hooks && "set" in hooks && 8788 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 8789 return ret; 8790 } 8791 8792 elem.setAttribute( name, value + "" ); 8793 return value; 8794 } 8795 8796 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 8797 return ret; 8798 } 8799 8800 ret = jQuery.find.attr( elem, name ); 8801 8802 // Non-existent attributes return null, we normalize to undefined 8803 return ret == null ? undefined : ret; 8804 }, 8805 8806 attrHooks: { 8807 type: { 8808 set: function( elem, value ) { 8809 if ( !support.radioValue && value === "radio" && 8810 nodeName( elem, "input" ) ) { 8811 var val = elem.value; 8812 elem.setAttribute( "type", value ); 8813 if ( val ) { 8814 elem.value = val; 8815 } 8816 return value; 8817 } 8818 } 8819 } 8820 }, 8821 8822 removeAttr: function( elem, value ) { 8823 var name, 8824 i = 0, 8825 8826 // Attribute names can contain non-HTML whitespace characters 8827 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 8828 attrNames = value && value.match( rnothtmlwhite ); 8829 8830 if ( attrNames && elem.nodeType === 1 ) { 8831 while ( ( name = attrNames[ i++ ] ) ) { 8832 elem.removeAttribute( name ); 8833 } 8834 } 8835 } 8836} ); 8837 8838// Hooks for boolean attributes 8839boolHook = { 8840 set: function( elem, value, name ) { 8841 if ( value === false ) { 8842 8843 // Remove boolean attributes when set to false 8844 jQuery.removeAttr( elem, name ); 8845 } else { 8846 elem.setAttribute( name, name ); 8847 } 8848 return name; 8849 } 8850}; 8851 8852jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { 8853 var getter = attrHandle[ name ] || jQuery.find.attr; 8854 8855 attrHandle[ name ] = function( elem, name, isXML ) { 8856 var ret, handle, 8857 lowercaseName = name.toLowerCase(); 8858 8859 if ( !isXML ) { 8860 8861 // Avoid an infinite loop by temporarily removing this function from the getter 8862 handle = attrHandle[ lowercaseName ]; 8863 attrHandle[ lowercaseName ] = ret; 8864 ret = getter( elem, name, isXML ) != null ? 8865 lowercaseName : 8866 null; 8867 attrHandle[ lowercaseName ] = handle; 8868 } 8869 return ret; 8870 }; 8871} ); 8872 8873 8874 8875 8876var rfocusable = /^(?:input|select|textarea|button)$/i, 8877 rclickable = /^(?:a|area)$/i; 8878 8879jQuery.fn.extend( { 8880 prop: function( name, value ) { 8881 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 8882 }, 8883 8884 removeProp: function( name ) { 8885 return this.each( function() { 8886 delete this[ jQuery.propFix[ name ] || name ]; 8887 } ); 8888 } 8889} ); 8890 8891jQuery.extend( { 8892 prop: function( elem, name, value ) { 8893 var ret, hooks, 8894 nType = elem.nodeType; 8895 8896 // Don't get/set properties on text, comment and attribute nodes 8897 if ( nType === 3 || nType === 8 || nType === 2 ) { 8898 return; 8899 } 8900 8901 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 8902 8903 // Fix name and attach hooks 8904 name = jQuery.propFix[ name ] || name; 8905 hooks = jQuery.propHooks[ name ]; 8906 } 8907 8908 if ( value !== undefined ) { 8909 if ( hooks && "set" in hooks && 8910 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 8911 return ret; 8912 } 8913 8914 return ( elem[ name ] = value ); 8915 } 8916 8917 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 8918 return ret; 8919 } 8920 8921 return elem[ name ]; 8922 }, 8923 8924 propHooks: { 8925 tabIndex: { 8926 get: function( elem ) { 8927 8928 // Support: IE <=9 - 11 only 8929 // elem.tabIndex doesn't always return the 8930 // correct value when it hasn't been explicitly set 8931 // Use proper attribute retrieval (trac-12072) 8932 var tabindex = jQuery.find.attr( elem, "tabindex" ); 8933 8934 if ( tabindex ) { 8935 return parseInt( tabindex, 10 ); 8936 } 8937 8938 if ( 8939 rfocusable.test( elem.nodeName ) || 8940 rclickable.test( elem.nodeName ) && 8941 elem.href 8942 ) { 8943 return 0; 8944 } 8945 8946 return -1; 8947 } 8948 } 8949 }, 8950 8951 propFix: { 8952 "for": "htmlFor", 8953 "class": "className" 8954 } 8955} ); 8956 8957// Support: IE <=11 only 8958// Accessing the selectedIndex property 8959// forces the browser to respect setting selected 8960// on the option 8961// The getter ensures a default option is selected 8962// when in an optgroup 8963// eslint rule "no-unused-expressions" is disabled for this code 8964// since it considers such accessions noop 8965if ( !support.optSelected ) { 8966 jQuery.propHooks.selected = { 8967 get: function( elem ) { 8968 8969 /* eslint no-unused-expressions: "off" */ 8970 8971 var parent = elem.parentNode; 8972 if ( parent && parent.parentNode ) { 8973 parent.parentNode.selectedIndex; 8974 } 8975 return null; 8976 }, 8977 set: function( elem ) { 8978 8979 /* eslint no-unused-expressions: "off" */ 8980 8981 var parent = elem.parentNode; 8982 if ( parent ) { 8983 parent.selectedIndex; 8984 8985 if ( parent.parentNode ) { 8986 parent.parentNode.selectedIndex; 8987 } 8988 } 8989 } 8990 }; 8991} 8992 8993jQuery.each( [ 8994 "tabIndex", 8995 "readOnly", 8996 "maxLength", 8997 "cellSpacing", 8998 "cellPadding", 8999 "rowSpan", 9000 "colSpan", 9001 "useMap", 9002 "frameBorder", 9003 "contentEditable" 9004], function() { 9005 jQuery.propFix[ this.toLowerCase() ] = this; 9006} ); 9007 9008 9009 9010 9011 // Strip and collapse whitespace according to HTML spec 9012 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 9013 function stripAndCollapse( value ) { 9014 var tokens = value.match( rnothtmlwhite ) || []; 9015 return tokens.join( " " ); 9016 } 9017 9018 9019function getClass( elem ) { 9020 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 9021} 9022 9023function classesToArray( value ) { 9024 if ( Array.isArray( value ) ) { 9025 return value; 9026 } 9027 if ( typeof value === "string" ) { 9028 return value.match( rnothtmlwhite ) || []; 9029 } 9030 return []; 9031} 9032 9033jQuery.fn.extend( { 9034 addClass: function( value ) { 9035 var classNames, cur, curValue, className, i, finalValue; 9036 9037 if ( isFunction( value ) ) { 9038 return this.each( function( j ) { 9039 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 9040 } ); 9041 } 9042 9043 classNames = classesToArray( value ); 9044 9045 if ( classNames.length ) { 9046 return this.each( function() { 9047 curValue = getClass( this ); 9048 cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 9049 9050 if ( cur ) { 9051 for ( i = 0; i < classNames.length; i++ ) { 9052 className = classNames[ i ]; 9053 if ( cur.indexOf( " " + className + " " ) < 0 ) { 9054 cur += className + " "; 9055 } 9056 } 9057 9058 // Only assign if different to avoid unneeded rendering. 9059 finalValue = stripAndCollapse( cur ); 9060 if ( curValue !== finalValue ) { 9061 this.setAttribute( "class", finalValue ); 9062 } 9063 } 9064 } ); 9065 } 9066 9067 return this; 9068 }, 9069 9070 removeClass: function( value ) { 9071 var classNames, cur, curValue, className, i, finalValue; 9072 9073 if ( isFunction( value ) ) { 9074 return this.each( function( j ) { 9075 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 9076 } ); 9077 } 9078 9079 if ( !arguments.length ) { 9080 return this.attr( "class", "" ); 9081 } 9082 9083 classNames = classesToArray( value ); 9084 9085 if ( classNames.length ) { 9086 return this.each( function() { 9087 curValue = getClass( this ); 9088 9089 // This expression is here for better compressibility (see addClass) 9090 cur = this.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 9091 9092 if ( cur ) { 9093 for ( i = 0; i < classNames.length; i++ ) { 9094 className = classNames[ i ]; 9095 9096 // Remove *all* instances 9097 while ( cur.indexOf( " " + className + " " ) > -1 ) { 9098 cur = cur.replace( " " + className + " ", " " ); 9099 } 9100 } 9101 9102 // Only assign if different to avoid unneeded rendering. 9103 finalValue = stripAndCollapse( cur ); 9104 if ( curValue !== finalValue ) { 9105 this.setAttribute( "class", finalValue ); 9106 } 9107 } 9108 } ); 9109 } 9110 9111 return this; 9112 }, 9113 9114 toggleClass: function( value, stateVal ) { 9115 var classNames, className, i, self, 9116 type = typeof value, 9117 isValidValue = type === "string" || Array.isArray( value ); 9118 9119 if ( isFunction( value ) ) { 9120 return this.each( function( i ) { 9121 jQuery( this ).toggleClass( 9122 value.call( this, i, getClass( this ), stateVal ), 9123 stateVal 9124 ); 9125 } ); 9126 } 9127 9128 if ( typeof stateVal === "boolean" && isValidValue ) { 9129 return stateVal ? this.addClass( value ) : this.removeClass( value ); 9130 } 9131 9132 classNames = classesToArray( value ); 9133 9134 return this.each( function() { 9135 if ( isValidValue ) { 9136 9137 // Toggle individual class names 9138 self = jQuery( this ); 9139 9140 for ( i = 0; i < classNames.length; i++ ) { 9141 className = classNames[ i ]; 9142 9143 // Check each className given, space separated list 9144 if ( self.hasClass( className ) ) { 9145 self.removeClass( className ); 9146 } else { 9147 self.addClass( className ); 9148 } 9149 } 9150 9151 // Toggle whole class name 9152 } else if ( value === undefined || type === "boolean" ) { 9153 className = getClass( this ); 9154 if ( className ) { 9155 9156 // Store className if set 9157 dataPriv.set( this, "__className__", className ); 9158 } 9159 9160 // If the element has a class name or if we're passed `false`, 9161 // then remove the whole classname (if there was one, the above saved it). 9162 // Otherwise bring back whatever was previously saved (if anything), 9163 // falling back to the empty string if nothing was stored. 9164 if ( this.setAttribute ) { 9165 this.setAttribute( "class", 9166 className || value === false ? 9167 "" : 9168 dataPriv.get( this, "__className__" ) || "" 9169 ); 9170 } 9171 } 9172 } ); 9173 }, 9174 9175 hasClass: function( selector ) { 9176 var className, elem, 9177 i = 0; 9178 9179 className = " " + selector + " "; 9180 while ( ( elem = this[ i++ ] ) ) { 9181 if ( elem.nodeType === 1 && 9182 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 9183 return true; 9184 } 9185 } 9186 9187 return false; 9188 } 9189} ); 9190 9191 9192 9193 9194var rreturn = /\r/g; 9195 9196jQuery.fn.extend( { 9197 val: function( value ) { 9198 var hooks, ret, valueIsFunction, 9199 elem = this[ 0 ]; 9200 9201 if ( !arguments.length ) { 9202 if ( elem ) { 9203 hooks = jQuery.valHooks[ elem.type ] || 9204 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 9205 9206 if ( hooks && 9207 "get" in hooks && 9208 ( ret = hooks.get( elem, "value" ) ) !== undefined 9209 ) { 9210 return ret; 9211 } 9212 9213 ret = elem.value; 9214 9215 // Handle most common string cases 9216 if ( typeof ret === "string" ) { 9217 return ret.replace( rreturn, "" ); 9218 } 9219 9220 // Handle cases where value is null/undef or number 9221 return ret == null ? "" : ret; 9222 } 9223 9224 return; 9225 } 9226 9227 valueIsFunction = isFunction( value ); 9228 9229 return this.each( function( i ) { 9230 var val; 9231 9232 if ( this.nodeType !== 1 ) { 9233 return; 9234 } 9235 9236 if ( valueIsFunction ) { 9237 val = value.call( this, i, jQuery( this ).val() ); 9238 } else { 9239 val = value; 9240 } 9241 9242 // Treat null/undefined as ""; convert numbers to string 9243 if ( val == null ) { 9244 val = ""; 9245 9246 } else if ( typeof val === "number" ) { 9247 val += ""; 9248 9249 } else if ( Array.isArray( val ) ) { 9250 val = jQuery.map( val, function( value ) { 9251 return value == null ? "" : value + ""; 9252 } ); 9253 } 9254 9255 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 9256 9257 // If set returns undefined, fall back to normal setting 9258 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 9259 this.value = val; 9260 } 9261 } ); 9262 } 9263} ); 9264 9265jQuery.extend( { 9266 valHooks: { 9267 option: { 9268 get: function( elem ) { 9269 9270 var val = jQuery.find.attr( elem, "value" ); 9271 return val != null ? 9272 val : 9273 9274 // Support: IE <=10 - 11 only 9275 // option.text throws exceptions (trac-14686, trac-14858) 9276 // Strip and collapse whitespace 9277 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 9278 stripAndCollapse( jQuery.text( elem ) ); 9279 } 9280 }, 9281 select: { 9282 get: function( elem ) { 9283 var value, option, i, 9284 options = elem.options, 9285 index = elem.selectedIndex, 9286 one = elem.type === "select-one", 9287 values = one ? null : [], 9288 max = one ? index + 1 : options.length; 9289 9290 if ( index < 0 ) { 9291 i = max; 9292 9293 } else { 9294 i = one ? index : 0; 9295 } 9296 9297 // Loop through all the selected options 9298 for ( ; i < max; i++ ) { 9299 option = options[ i ]; 9300 9301 // Support: IE <=9 only 9302 // IE8-9 doesn't update selected after form reset (trac-2551) 9303 if ( ( option.selected || i === index ) && 9304 9305 // Don't return options that are disabled or in a disabled optgroup 9306 !option.disabled && 9307 ( !option.parentNode.disabled || 9308 !nodeName( option.parentNode, "optgroup" ) ) ) { 9309 9310 // Get the specific value for the option 9311 value = jQuery( option ).val(); 9312 9313 // We don't need an array for one selects 9314 if ( one ) { 9315 return value; 9316 } 9317 9318 // Multi-Selects return an array 9319 values.push( value ); 9320 } 9321 } 9322 9323 return values; 9324 }, 9325 9326 set: function( elem, value ) { 9327 var optionSet, option, 9328 options = elem.options, 9329 values = jQuery.makeArray( value ), 9330 i = options.length; 9331 9332 while ( i-- ) { 9333 option = options[ i ]; 9334 9335 /* eslint-disable no-cond-assign */ 9336 9337 if ( option.selected = 9338 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 9339 ) { 9340 optionSet = true; 9341 } 9342 9343 /* eslint-enable no-cond-assign */ 9344 } 9345 9346 // Force browsers to behave consistently when non-matching value is set 9347 if ( !optionSet ) { 9348 elem.selectedIndex = -1; 9349 } 9350 return values; 9351 } 9352 } 9353 } 9354} ); 9355 9356// Radios and checkboxes getter/setter 9357jQuery.each( [ "radio", "checkbox" ], function() { 9358 jQuery.valHooks[ this ] = { 9359 set: function( elem, value ) { 9360 if ( Array.isArray( value ) ) { 9361 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 9362 } 9363 } 9364 }; 9365 if ( !support.checkOn ) { 9366 jQuery.valHooks[ this ].get = function( elem ) { 9367 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 9368 }; 9369 } 9370} ); 9371 9372 9373 9374 9375// Return jQuery for attributes-only inclusion 9376var location = window.location; 9377 9378var nonce = { guid: Date.now() }; 9379 9380var rquery = ( /\?/ ); 9381 9382 9383 9384// Cross-browser xml parsing 9385jQuery.parseXML = function( data ) { 9386 var xml, parserErrorElem; 9387 if ( !data || typeof data !== "string" ) { 9388 return null; 9389 } 9390 9391 // Support: IE 9 - 11 only 9392 // IE throws on parseFromString with invalid input. 9393 try { 9394 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 9395 } catch ( e ) {} 9396 9397 parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; 9398 if ( !xml || parserErrorElem ) { 9399 jQuery.error( "Invalid XML: " + ( 9400 parserErrorElem ? 9401 jQuery.map( parserErrorElem.childNodes, function( el ) { 9402 return el.textContent; 9403 } ).join( "\n" ) : 9404 data 9405 ) ); 9406 } 9407 return xml; 9408}; 9409 9410 9411var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 9412 stopPropagationCallback = function( e ) { 9413 e.stopPropagation(); 9414 }; 9415 9416jQuery.extend( jQuery.event, { 9417 9418 trigger: function( event, data, elem, onlyHandlers ) { 9419 9420 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, 9421 eventPath = [ elem || document ], 9422 type = hasOwn.call( event, "type" ) ? event.type : event, 9423 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 9424 9425 cur = lastElement = tmp = elem = elem || document; 9426 9427 // Don't do events on text and comment nodes 9428 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 9429 return; 9430 } 9431 9432 // focus/blur morphs to focusin/out; ensure we're not firing them right now 9433 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 9434 return; 9435 } 9436 9437 if ( type.indexOf( "." ) > -1 ) { 9438 9439 // Namespaced trigger; create a regexp to match event type in handle() 9440 namespaces = type.split( "." ); 9441 type = namespaces.shift(); 9442 namespaces.sort(); 9443 } 9444 ontype = type.indexOf( ":" ) < 0 && "on" + type; 9445 9446 // Caller can pass in a jQuery.Event object, Object, or just an event type string 9447 event = event[ jQuery.expando ] ? 9448 event : 9449 new jQuery.Event( type, typeof event === "object" && event ); 9450 9451 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 9452 event.isTrigger = onlyHandlers ? 2 : 3; 9453 event.namespace = namespaces.join( "." ); 9454 event.rnamespace = event.namespace ? 9455 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 9456 null; 9457 9458 // Clean up the event in case it is being reused 9459 event.result = undefined; 9460 if ( !event.target ) { 9461 event.target = elem; 9462 } 9463 9464 // Clone any incoming data and prepend the event, creating the handler arg list 9465 data = data == null ? 9466 [ event ] : 9467 jQuery.makeArray( data, [ event ] ); 9468 9469 // Allow special events to draw outside the lines 9470 special = jQuery.event.special[ type ] || {}; 9471 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 9472 return; 9473 } 9474 9475 // Determine event propagation path in advance, per W3C events spec (trac-9951) 9476 // Bubble up to document, then to window; watch for a global ownerDocument var (trac-9724) 9477 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { 9478 9479 bubbleType = special.delegateType || type; 9480 if ( !rfocusMorph.test( bubbleType + type ) ) { 9481 cur = cur.parentNode; 9482 } 9483 for ( ; cur; cur = cur.parentNode ) { 9484 eventPath.push( cur ); 9485 tmp = cur; 9486 } 9487 9488 // Only add window if we got to document (e.g., not plain obj or detached DOM) 9489 if ( tmp === ( elem.ownerDocument || document ) ) { 9490 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 9491 } 9492 } 9493 9494 // Fire handlers on the event path 9495 i = 0; 9496 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 9497 lastElement = cur; 9498 event.type = i > 1 ? 9499 bubbleType : 9500 special.bindType || type; 9501 9502 // jQuery handler 9503 handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && 9504 dataPriv.get( cur, "handle" ); 9505 if ( handle ) { 9506 handle.apply( cur, data ); 9507 } 9508 9509 // Native handler 9510 handle = ontype && cur[ ontype ]; 9511 if ( handle && handle.apply && acceptData( cur ) ) { 9512 event.result = handle.apply( cur, data ); 9513 if ( event.result === false ) { 9514 event.preventDefault(); 9515 } 9516 } 9517 } 9518 event.type = type; 9519 9520 // If nobody prevented the default action, do it now 9521 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 9522 9523 if ( ( !special._default || 9524 special._default.apply( eventPath.pop(), data ) === false ) && 9525 acceptData( elem ) ) { 9526 9527 // Call a native DOM method on the target with the same name as the event. 9528 // Don't do default actions on window, that's where global variables be (trac-6170) 9529 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { 9530 9531 // Don't re-trigger an onFOO event when we call its FOO() method 9532 tmp = elem[ ontype ]; 9533 9534 if ( tmp ) { 9535 elem[ ontype ] = null; 9536 } 9537 9538 // Prevent re-triggering of the same event, since we already bubbled it above 9539 jQuery.event.triggered = type; 9540 9541 if ( event.isPropagationStopped() ) { 9542 lastElement.addEventListener( type, stopPropagationCallback ); 9543 } 9544 9545 elem[ type ](); 9546 9547 if ( event.isPropagationStopped() ) { 9548 lastElement.removeEventListener( type, stopPropagationCallback ); 9549 } 9550 9551 jQuery.event.triggered = undefined; 9552 9553 if ( tmp ) { 9554 elem[ ontype ] = tmp; 9555 } 9556 } 9557 } 9558 } 9559 9560 return event.result; 9561 }, 9562 9563 // Piggyback on a donor event to simulate a different one 9564 // Used only for `focus(in | out)` events 9565 simulate: function( type, elem, event ) { 9566 var e = jQuery.extend( 9567 new jQuery.Event(), 9568 event, 9569 { 9570 type: type, 9571 isSimulated: true 9572 } 9573 ); 9574 9575 jQuery.event.trigger( e, null, elem ); 9576 } 9577 9578} ); 9579 9580jQuery.fn.extend( { 9581 9582 trigger: function( type, data ) { 9583 return this.each( function() { 9584 jQuery.event.trigger( type, data, this ); 9585 } ); 9586 }, 9587 triggerHandler: function( type, data ) { 9588 var elem = this[ 0 ]; 9589 if ( elem ) { 9590 return jQuery.event.trigger( type, data, elem, true ); 9591 } 9592 } 9593} ); 9594 9595 9596var 9597 rbracket = /\[\]$/, 9598 rCRLF = /\r?\n/g, 9599 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 9600 rsubmittable = /^(?:input|select|textarea|keygen)/i; 9601 9602function buildParams( prefix, obj, traditional, add ) { 9603 var name; 9604 9605 if ( Array.isArray( obj ) ) { 9606 9607 // Serialize array item. 9608 jQuery.each( obj, function( i, v ) { 9609 if ( traditional || rbracket.test( prefix ) ) { 9610 9611 // Treat each array item as a scalar. 9612 add( prefix, v ); 9613 9614 } else { 9615 9616 // Item is non-scalar (array or object), encode its numeric index. 9617 buildParams( 9618 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 9619 v, 9620 traditional, 9621 add 9622 ); 9623 } 9624 } ); 9625 9626 } else if ( !traditional && toType( obj ) === "object" ) { 9627 9628 // Serialize object item. 9629 for ( name in obj ) { 9630 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 9631 } 9632 9633 } else { 9634 9635 // Serialize scalar item. 9636 add( prefix, obj ); 9637 } 9638} 9639 9640// Serialize an array of form elements or a set of 9641// key/values into a query string 9642jQuery.param = function( a, traditional ) { 9643 var prefix, 9644 s = [], 9645 add = function( key, valueOrFunction ) { 9646 9647 // If value is a function, invoke it and use its return value 9648 var value = isFunction( valueOrFunction ) ? 9649 valueOrFunction() : 9650 valueOrFunction; 9651 9652 s[ s.length ] = encodeURIComponent( key ) + "=" + 9653 encodeURIComponent( value == null ? "" : value ); 9654 }; 9655 9656 if ( a == null ) { 9657 return ""; 9658 } 9659 9660 // If an array was passed in, assume that it is an array of form elements. 9661 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 9662 9663 // Serialize the form elements 9664 jQuery.each( a, function() { 9665 add( this.name, this.value ); 9666 } ); 9667 9668 } else { 9669 9670 // If traditional, encode the "old" way (the way 1.3.2 or older 9671 // did it), otherwise encode params recursively. 9672 for ( prefix in a ) { 9673 buildParams( prefix, a[ prefix ], traditional, add ); 9674 } 9675 } 9676 9677 // Return the resulting serialization 9678 return s.join( "&" ); 9679}; 9680 9681jQuery.fn.extend( { 9682 serialize: function() { 9683 return jQuery.param( this.serializeArray() ); 9684 }, 9685 serializeArray: function() { 9686 return this.map( function() { 9687 9688 // Can add propHook for "elements" to filter or add form elements 9689 var elements = jQuery.prop( this, "elements" ); 9690 return elements ? jQuery.makeArray( elements ) : this; 9691 } ).filter( function() { 9692 var type = this.type; 9693 9694 // Use .is( ":disabled" ) so that fieldset[disabled] works 9695 return this.name && !jQuery( this ).is( ":disabled" ) && 9696 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 9697 ( this.checked || !rcheckableType.test( type ) ); 9698 } ).map( function( _i, elem ) { 9699 var val = jQuery( this ).val(); 9700 9701 if ( val == null ) { 9702 return null; 9703 } 9704 9705 if ( Array.isArray( val ) ) { 9706 return jQuery.map( val, function( val ) { 9707 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 9708 } ); 9709 } 9710 9711 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 9712 } ).get(); 9713 } 9714} ); 9715 9716 9717var 9718 r20 = /%20/g, 9719 rhash = /#.*$/, 9720 rantiCache = /([?&])_=[^&]*/, 9721 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 9722 9723 // trac-7653, trac-8125, trac-8152: local protocol detection 9724 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 9725 rnoContent = /^(?:GET|HEAD)$/, 9726 rprotocol = /^\/\//, 9727 9728 /* Prefilters 9729 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 9730 * 2) These are called: 9731 * - BEFORE asking for a transport 9732 * - AFTER param serialization (s.data is a string if s.processData is true) 9733 * 3) key is the dataType 9734 * 4) the catchall symbol "*" can be used 9735 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 9736 */ 9737 prefilters = {}, 9738 9739 /* Transports bindings 9740 * 1) key is the dataType 9741 * 2) the catchall symbol "*" can be used 9742 * 3) selection will start with transport dataType and THEN go to "*" if needed 9743 */ 9744 transports = {}, 9745 9746 // Avoid comment-prolog char sequence (trac-10098); must appease lint and evade compression 9747 allTypes = "*/".concat( "*" ), 9748 9749 // Anchor tag for parsing the document origin 9750 originAnchor = document.createElement( "a" ); 9751 9752originAnchor.href = location.href; 9753 9754// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 9755function addToPrefiltersOrTransports( structure ) { 9756 9757 // dataTypeExpression is optional and defaults to "*" 9758 return function( dataTypeExpression, func ) { 9759 9760 if ( typeof dataTypeExpression !== "string" ) { 9761 func = dataTypeExpression; 9762 dataTypeExpression = "*"; 9763 } 9764 9765 var dataType, 9766 i = 0, 9767 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; 9768 9769 if ( isFunction( func ) ) { 9770 9771 // For each dataType in the dataTypeExpression 9772 while ( ( dataType = dataTypes[ i++ ] ) ) { 9773 9774 // Prepend if requested 9775 if ( dataType[ 0 ] === "+" ) { 9776 dataType = dataType.slice( 1 ) || "*"; 9777 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 9778 9779 // Otherwise append 9780 } else { 9781 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 9782 } 9783 } 9784 } 9785 }; 9786} 9787 9788// Base inspection function for prefilters and transports 9789function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 9790 9791 var inspected = {}, 9792 seekingTransport = ( structure === transports ); 9793 9794 function inspect( dataType ) { 9795 var selected; 9796 inspected[ dataType ] = true; 9797 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 9798 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 9799 if ( typeof dataTypeOrTransport === "string" && 9800 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 9801 9802 options.dataTypes.unshift( dataTypeOrTransport ); 9803 inspect( dataTypeOrTransport ); 9804 return false; 9805 } else if ( seekingTransport ) { 9806 return !( selected = dataTypeOrTransport ); 9807 } 9808 } ); 9809 return selected; 9810 } 9811 9812 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 9813} 9814 9815// A special extend for ajax options 9816// that takes "flat" options (not to be deep extended) 9817// Fixes trac-9887 9818function ajaxExtend( target, src ) { 9819 var key, deep, 9820 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 9821 9822 for ( key in src ) { 9823 if ( src[ key ] !== undefined ) { 9824 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 9825 } 9826 } 9827 if ( deep ) { 9828 jQuery.extend( true, target, deep ); 9829 } 9830 9831 return target; 9832} 9833 9834/* Handles responses to an ajax request: 9835 * - finds the right dataType (mediates between content-type and expected dataType) 9836 * - returns the corresponding response 9837 */ 9838function ajaxHandleResponses( s, jqXHR, responses ) { 9839 9840 var ct, type, finalDataType, firstDataType, 9841 contents = s.contents, 9842 dataTypes = s.dataTypes; 9843 9844 // Remove auto dataType and get content-type in the process 9845 while ( dataTypes[ 0 ] === "*" ) { 9846 dataTypes.shift(); 9847 if ( ct === undefined ) { 9848 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 9849 } 9850 } 9851 9852 // Check if we're dealing with a known content-type 9853 if ( ct ) { 9854 for ( type in contents ) { 9855 if ( contents[ type ] && contents[ type ].test( ct ) ) { 9856 dataTypes.unshift( type ); 9857 break; 9858 } 9859 } 9860 } 9861 9862 // Check to see if we have a response for the expected dataType 9863 if ( dataTypes[ 0 ] in responses ) { 9864 finalDataType = dataTypes[ 0 ]; 9865 } else { 9866 9867 // Try convertible dataTypes 9868 for ( type in responses ) { 9869 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 9870 finalDataType = type; 9871 break; 9872 } 9873 if ( !firstDataType ) { 9874 firstDataType = type; 9875 } 9876 } 9877 9878 // Or just use first one 9879 finalDataType = finalDataType || firstDataType; 9880 } 9881 9882 // If we found a dataType 9883 // We add the dataType to the list if needed 9884 // and return the corresponding response 9885 if ( finalDataType ) { 9886 if ( finalDataType !== dataTypes[ 0 ] ) { 9887 dataTypes.unshift( finalDataType ); 9888 } 9889 return responses[ finalDataType ]; 9890 } 9891} 9892 9893/* Chain conversions given the request and the original response 9894 * Also sets the responseXXX fields on the jqXHR instance 9895 */ 9896function ajaxConvert( s, response, jqXHR, isSuccess ) { 9897 var conv2, current, conv, tmp, prev, 9898 converters = {}, 9899 9900 // Work with a copy of dataTypes in case we need to modify it for conversion 9901 dataTypes = s.dataTypes.slice(); 9902 9903 // Create converters map with lowercased keys 9904 if ( dataTypes[ 1 ] ) { 9905 for ( conv in s.converters ) { 9906 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 9907 } 9908 } 9909 9910 current = dataTypes.shift(); 9911 9912 // Convert to each sequential dataType 9913 while ( current ) { 9914 9915 if ( s.responseFields[ current ] ) { 9916 jqXHR[ s.responseFields[ current ] ] = response; 9917 } 9918 9919 // Apply the dataFilter if provided 9920 if ( !prev && isSuccess && s.dataFilter ) { 9921 response = s.dataFilter( response, s.dataType ); 9922 } 9923 9924 prev = current; 9925 current = dataTypes.shift(); 9926 9927 if ( current ) { 9928 9929 // There's only work to do if current dataType is non-auto 9930 if ( current === "*" ) { 9931 9932 current = prev; 9933 9934 // Convert response if prev dataType is non-auto and differs from current 9935 } else if ( prev !== "*" && prev !== current ) { 9936 9937 // Seek a direct converter 9938 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 9939 9940 // If none found, seek a pair 9941 if ( !conv ) { 9942 for ( conv2 in converters ) { 9943 9944 // If conv2 outputs current 9945 tmp = conv2.split( " " ); 9946 if ( tmp[ 1 ] === current ) { 9947 9948 // If prev can be converted to accepted input 9949 conv = converters[ prev + " " + tmp[ 0 ] ] || 9950 converters[ "* " + tmp[ 0 ] ]; 9951 if ( conv ) { 9952 9953 // Condense equivalence converters 9954 if ( conv === true ) { 9955 conv = converters[ conv2 ]; 9956 9957 // Otherwise, insert the intermediate dataType 9958 } else if ( converters[ conv2 ] !== true ) { 9959 current = tmp[ 0 ]; 9960 dataTypes.unshift( tmp[ 1 ] ); 9961 } 9962 break; 9963 } 9964 } 9965 } 9966 } 9967 9968 // Apply converter (if not an equivalence) 9969 if ( conv !== true ) { 9970 9971 // Unless errors are allowed to bubble, catch and return them 9972 if ( conv && s.throws ) { 9973 response = conv( response ); 9974 } else { 9975 try { 9976 response = conv( response ); 9977 } catch ( e ) { 9978 return { 9979 state: "parsererror", 9980 error: conv ? e : "No conversion from " + prev + " to " + current 9981 }; 9982 } 9983 } 9984 } 9985 } 9986 } 9987 } 9988 9989 return { state: "success", data: response }; 9990} 9991 9992jQuery.extend( { 9993 9994 // Counter for holding the number of active queries 9995 active: 0, 9996 9997 // Last-Modified header cache for next request 9998 lastModified: {}, 9999 etag: {}, 10000 10001 ajaxSettings: { 10002 url: location.href, 10003 type: "GET", 10004 isLocal: rlocalProtocol.test( location.protocol ), 10005 global: true, 10006 processData: true, 10007 async: true, 10008 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 10009 10010 /* 10011 timeout: 0, 10012 data: null, 10013 dataType: null, 10014 username: null, 10015 password: null, 10016 cache: null, 10017 throws: false, 10018 traditional: false, 10019 headers: {}, 10020 */ 10021 10022 accepts: { 10023 "*": allTypes, 10024 text: "text/plain", 10025 html: "text/html", 10026 xml: "application/xml, text/xml", 10027 json: "application/json, text/javascript" 10028 }, 10029 10030 contents: { 10031 xml: /\bxml\b/, 10032 html: /\bhtml/, 10033 json: /\bjson\b/ 10034 }, 10035 10036 responseFields: { 10037 xml: "responseXML", 10038 text: "responseText", 10039 json: "responseJSON" 10040 }, 10041 10042 // Data converters 10043 // Keys separate source (or catchall "*") and destination types with a single space 10044 converters: { 10045 10046 // Convert anything to text 10047 "* text": String, 10048 10049 // Text to html (true = no transformation) 10050 "text html": true, 10051 10052 // Evaluate text as a json expression 10053 "text json": JSON.parse, 10054 10055 // Parse text as xml 10056 "text xml": jQuery.parseXML 10057 }, 10058 10059 // For options that shouldn't be deep extended: 10060 // you can add your own custom options here if 10061 // and when you create one that shouldn't be 10062 // deep extended (see ajaxExtend) 10063 flatOptions: { 10064 url: true, 10065 context: true 10066 } 10067 }, 10068 10069 // Creates a full fledged settings object into target 10070 // with both ajaxSettings and settings fields. 10071 // If target is omitted, writes into ajaxSettings. 10072 ajaxSetup: function( target, settings ) { 10073 return settings ? 10074 10075 // Building a settings object 10076 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 10077 10078 // Extending ajaxSettings 10079 ajaxExtend( jQuery.ajaxSettings, target ); 10080 }, 10081 10082 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 10083 ajaxTransport: addToPrefiltersOrTransports( transports ), 10084 10085 // Main method 10086 ajax: function( url, options ) { 10087 10088 // If url is an object, simulate pre-1.5 signature 10089 if ( typeof url === "object" ) { 10090 options = url; 10091 url = undefined; 10092 } 10093 10094 // Force options to be an object 10095 options = options || {}; 10096 10097 var transport, 10098 10099 // URL without anti-cache param 10100 cacheURL, 10101 10102 // Response headers 10103 responseHeadersString, 10104 responseHeaders, 10105 10106 // timeout handle 10107 timeoutTimer, 10108 10109 // Url cleanup var 10110 urlAnchor, 10111 10112 // Request state (becomes false upon send and true upon completion) 10113 completed, 10114 10115 // To know if global events are to be dispatched 10116 fireGlobals, 10117 10118 // Loop variable 10119 i, 10120 10121 // uncached part of the url 10122 uncached, 10123 10124 // Create the final options object 10125 s = jQuery.ajaxSetup( {}, options ), 10126 10127 // Callbacks context 10128 callbackContext = s.context || s, 10129 10130 // Context for global events is callbackContext if it is a DOM node or jQuery collection 10131 globalEventContext = s.context && 10132 ( callbackContext.nodeType || callbackContext.jquery ) ? 10133 jQuery( callbackContext ) : 10134 jQuery.event, 10135 10136 // Deferreds 10137 deferred = jQuery.Deferred(), 10138 completeDeferred = jQuery.Callbacks( "once memory" ), 10139 10140 // Status-dependent callbacks 10141 statusCode = s.statusCode || {}, 10142 10143 // Headers (they are sent all at once) 10144 requestHeaders = {}, 10145 requestHeadersNames = {}, 10146 10147 // Default abort message 10148 strAbort = "canceled", 10149 10150 // Fake xhr 10151 jqXHR = { 10152 readyState: 0, 10153 10154 // Builds headers hashtable if needed 10155 getResponseHeader: function( key ) { 10156 var match; 10157 if ( completed ) { 10158 if ( !responseHeaders ) { 10159 responseHeaders = {}; 10160 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 10161 responseHeaders[ match[ 1 ].toLowerCase() + " " ] = 10162 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) 10163 .concat( match[ 2 ] ); 10164 } 10165 } 10166 match = responseHeaders[ key.toLowerCase() + " " ]; 10167 } 10168 return match == null ? null : match.join( ", " ); 10169 }, 10170 10171 // Raw string 10172 getAllResponseHeaders: function() { 10173 return completed ? responseHeadersString : null; 10174 }, 10175 10176 // Caches the header 10177 setRequestHeader: function( name, value ) { 10178 if ( completed == null ) { 10179 name = requestHeadersNames[ name.toLowerCase() ] = 10180 requestHeadersNames[ name.toLowerCase() ] || name; 10181 requestHeaders[ name ] = value; 10182 } 10183 return this; 10184 }, 10185 10186 // Overrides response content-type header 10187 overrideMimeType: function( type ) { 10188 if ( completed == null ) { 10189 s.mimeType = type; 10190 } 10191 return this; 10192 }, 10193 10194 // Status-dependent callbacks 10195 statusCode: function( map ) { 10196 var code; 10197 if ( map ) { 10198 if ( completed ) { 10199 10200 // Execute the appropriate callbacks 10201 jqXHR.always( map[ jqXHR.status ] ); 10202 } else { 10203 10204 // Lazy-add the new callbacks in a way that preserves old ones 10205 for ( code in map ) { 10206 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 10207 } 10208 } 10209 } 10210 return this; 10211 }, 10212 10213 // Cancel the request 10214 abort: function( statusText ) { 10215 var finalText = statusText || strAbort; 10216 if ( transport ) { 10217 transport.abort( finalText ); 10218 } 10219 done( 0, finalText ); 10220 return this; 10221 } 10222 }; 10223 10224 // Attach deferreds 10225 deferred.promise( jqXHR ); 10226 10227 // Add protocol if not provided (prefilters might expect it) 10228 // Handle falsy url in the settings object (trac-10093: consistency with old signature) 10229 // We also use the url parameter if available 10230 s.url = ( ( url || s.url || location.href ) + "" ) 10231 .replace( rprotocol, location.protocol + "//" ); 10232 10233 // Alias method option to type as per ticket trac-12004 10234 s.type = options.method || options.type || s.method || s.type; 10235 10236 // Extract dataTypes list 10237 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; 10238 10239 // A cross-domain request is in order when the origin doesn't match the current origin. 10240 if ( s.crossDomain == null ) { 10241 urlAnchor = document.createElement( "a" ); 10242 10243 // Support: IE <=8 - 11, Edge 12 - 15 10244 // IE throws exception on accessing the href property if url is malformed, 10245 // e.g. http://example.com:80x/ 10246 try { 10247 urlAnchor.href = s.url; 10248 10249 // Support: IE <=8 - 11 only 10250 // Anchor's host property isn't correctly set when s.url is relative 10251 urlAnchor.href = urlAnchor.href; 10252 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 10253 urlAnchor.protocol + "//" + urlAnchor.host; 10254 } catch ( e ) { 10255 10256 // If there is an error parsing the URL, assume it is crossDomain, 10257 // it can be rejected by the transport if it is invalid 10258 s.crossDomain = true; 10259 } 10260 } 10261 10262 // Convert data if not already a string 10263 if ( s.data && s.processData && typeof s.data !== "string" ) { 10264 s.data = jQuery.param( s.data, s.traditional ); 10265 } 10266 10267 // Apply prefilters 10268 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 10269 10270 // If request was aborted inside a prefilter, stop there 10271 if ( completed ) { 10272 return jqXHR; 10273 } 10274 10275 // We can fire global events as of now if asked to 10276 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (trac-15118) 10277 fireGlobals = jQuery.event && s.global; 10278 10279 // Watch for a new set of requests 10280 if ( fireGlobals && jQuery.active++ === 0 ) { 10281 jQuery.event.trigger( "ajaxStart" ); 10282 } 10283 10284 // Uppercase the type 10285 s.type = s.type.toUpperCase(); 10286 10287 // Determine if request has content 10288 s.hasContent = !rnoContent.test( s.type ); 10289 10290 // Save the URL in case we're toying with the If-Modified-Since 10291 // and/or If-None-Match header later on 10292 // Remove hash to simplify url manipulation 10293 cacheURL = s.url.replace( rhash, "" ); 10294 10295 // More options handling for requests with no content 10296 if ( !s.hasContent ) { 10297 10298 // Remember the hash so we can put it back 10299 uncached = s.url.slice( cacheURL.length ); 10300 10301 // If data is available and should be processed, append data to url 10302 if ( s.data && ( s.processData || typeof s.data === "string" ) ) { 10303 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; 10304 10305 // trac-9682: remove data so that it's not used in an eventual retry 10306 delete s.data; 10307 } 10308 10309 // Add or update anti-cache param if needed 10310 if ( s.cache === false ) { 10311 cacheURL = cacheURL.replace( rantiCache, "$1" ); 10312 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + 10313 uncached; 10314 } 10315 10316 // Put hash and anti-cache on the URL that will be requested (gh-1732) 10317 s.url = cacheURL + uncached; 10318 10319 // Change '%20' to '+' if this is encoded form body content (gh-2658) 10320 } else if ( s.data && s.processData && 10321 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { 10322 s.data = s.data.replace( r20, "+" ); 10323 } 10324 10325 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 10326 if ( s.ifModified ) { 10327 if ( jQuery.lastModified[ cacheURL ] ) { 10328 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 10329 } 10330 if ( jQuery.etag[ cacheURL ] ) { 10331 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 10332 } 10333 } 10334 10335 // Set the correct header, if data is being sent 10336 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 10337 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 10338 } 10339 10340 // Set the Accepts header for the server, depending on the dataType 10341 jqXHR.setRequestHeader( 10342 "Accept", 10343 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 10344 s.accepts[ s.dataTypes[ 0 ] ] + 10345 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 10346 s.accepts[ "*" ] 10347 ); 10348 10349 // Check for headers option 10350 for ( i in s.headers ) { 10351 jqXHR.setRequestHeader( i, s.headers[ i ] ); 10352 } 10353 10354 // Allow custom headers/mimetypes and early abort 10355 if ( s.beforeSend && 10356 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { 10357 10358 // Abort if not done already and return 10359 return jqXHR.abort(); 10360 } 10361 10362 // Aborting is no longer a cancellation 10363 strAbort = "abort"; 10364 10365 // Install callbacks on deferreds 10366 completeDeferred.add( s.complete ); 10367 jqXHR.done( s.success ); 10368 jqXHR.fail( s.error ); 10369 10370 // Get transport 10371 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 10372 10373 // If no transport, we auto-abort 10374 if ( !transport ) { 10375 done( -1, "No Transport" ); 10376 } else { 10377 jqXHR.readyState = 1; 10378 10379 // Send global event 10380 if ( fireGlobals ) { 10381 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 10382 } 10383 10384 // If request was aborted inside ajaxSend, stop there 10385 if ( completed ) { 10386 return jqXHR; 10387 } 10388 10389 // Timeout 10390 if ( s.async && s.timeout > 0 ) { 10391 timeoutTimer = window.setTimeout( function() { 10392 jqXHR.abort( "timeout" ); 10393 }, s.timeout ); 10394 } 10395 10396 try { 10397 completed = false; 10398 transport.send( requestHeaders, done ); 10399 } catch ( e ) { 10400 10401 // Rethrow post-completion exceptions 10402 if ( completed ) { 10403 throw e; 10404 } 10405 10406 // Propagate others as results 10407 done( -1, e ); 10408 } 10409 } 10410 10411 // Callback for when everything is done 10412 function done( status, nativeStatusText, responses, headers ) { 10413 var isSuccess, success, error, response, modified, 10414 statusText = nativeStatusText; 10415 10416 // Ignore repeat invocations 10417 if ( completed ) { 10418 return; 10419 } 10420 10421 completed = true; 10422 10423 // Clear timeout if it exists 10424 if ( timeoutTimer ) { 10425 window.clearTimeout( timeoutTimer ); 10426 } 10427 10428 // Dereference transport for early garbage collection 10429 // (no matter how long the jqXHR object will be used) 10430 transport = undefined; 10431 10432 // Cache response headers 10433 responseHeadersString = headers || ""; 10434 10435 // Set readyState 10436 jqXHR.readyState = status > 0 ? 4 : 0; 10437 10438 // Determine if successful 10439 isSuccess = status >= 200 && status < 300 || status === 304; 10440 10441 // Get response data 10442 if ( responses ) { 10443 response = ajaxHandleResponses( s, jqXHR, responses ); 10444 } 10445 10446 // Use a noop converter for missing script but not if jsonp 10447 if ( !isSuccess && 10448 jQuery.inArray( "script", s.dataTypes ) > -1 && 10449 jQuery.inArray( "json", s.dataTypes ) < 0 ) { 10450 s.converters[ "text script" ] = function() {}; 10451 } 10452 10453 // Convert no matter what (that way responseXXX fields are always set) 10454 response = ajaxConvert( s, response, jqXHR, isSuccess ); 10455 10456 // If successful, handle type chaining 10457 if ( isSuccess ) { 10458 10459 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 10460 if ( s.ifModified ) { 10461 modified = jqXHR.getResponseHeader( "Last-Modified" ); 10462 if ( modified ) { 10463 jQuery.lastModified[ cacheURL ] = modified; 10464 } 10465 modified = jqXHR.getResponseHeader( "etag" ); 10466 if ( modified ) { 10467 jQuery.etag[ cacheURL ] = modified; 10468 } 10469 } 10470 10471 // if no content 10472 if ( status === 204 || s.type === "HEAD" ) { 10473 statusText = "nocontent"; 10474 10475 // if not modified 10476 } else if ( status === 304 ) { 10477 statusText = "notmodified"; 10478 10479 // If we have data, let's convert it 10480 } else { 10481 statusText = response.state; 10482 success = response.data; 10483 error = response.error; 10484 isSuccess = !error; 10485 } 10486 } else { 10487 10488 // Extract error from statusText and normalize for non-aborts 10489 error = statusText; 10490 if ( status || !statusText ) { 10491 statusText = "error"; 10492 if ( status < 0 ) { 10493 status = 0; 10494 } 10495 } 10496 } 10497 10498 // Set data for the fake xhr object 10499 jqXHR.status = status; 10500 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 10501 10502 // Success/Error 10503 if ( isSuccess ) { 10504 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 10505 } else { 10506 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 10507 } 10508 10509 // Status-dependent callbacks 10510 jqXHR.statusCode( statusCode ); 10511 statusCode = undefined; 10512 10513 if ( fireGlobals ) { 10514 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 10515 [ jqXHR, s, isSuccess ? success : error ] ); 10516 } 10517 10518 // Complete 10519 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 10520 10521 if ( fireGlobals ) { 10522 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 10523 10524 // Handle the global AJAX counter 10525 if ( !( --jQuery.active ) ) { 10526 jQuery.event.trigger( "ajaxStop" ); 10527 } 10528 } 10529 } 10530 10531 return jqXHR; 10532 }, 10533 10534 getJSON: function( url, data, callback ) { 10535 return jQuery.get( url, data, callback, "json" ); 10536 }, 10537 10538 getScript: function( url, callback ) { 10539 return jQuery.get( url, undefined, callback, "script" ); 10540 } 10541} ); 10542 10543jQuery.each( [ "get", "post" ], function( _i, method ) { 10544 jQuery[ method ] = function( url, data, callback, type ) { 10545 10546 // Shift arguments if data argument was omitted 10547 if ( isFunction( data ) ) { 10548 type = type || callback; 10549 callback = data; 10550 data = undefined; 10551 } 10552 10553 // The url can be an options object (which then must have .url) 10554 return jQuery.ajax( jQuery.extend( { 10555 url: url, 10556 type: method, 10557 dataType: type, 10558 data: data, 10559 success: callback 10560 }, jQuery.isPlainObject( url ) && url ) ); 10561 }; 10562} ); 10563 10564jQuery.ajaxPrefilter( function( s ) { 10565 var i; 10566 for ( i in s.headers ) { 10567 if ( i.toLowerCase() === "content-type" ) { 10568 s.contentType = s.headers[ i ] || ""; 10569 } 10570 } 10571} ); 10572 10573 10574jQuery._evalUrl = function( url, options, doc ) { 10575 return jQuery.ajax( { 10576 url: url, 10577 10578 // Make this explicit, since user can override this through ajaxSetup (trac-11264) 10579 type: "GET", 10580 dataType: "script", 10581 cache: true, 10582 async: false, 10583 global: false, 10584 10585 // Only evaluate the response if it is successful (gh-4126) 10586 // dataFilter is not invoked for failure responses, so using it instead 10587 // of the default converter is kludgy but it works. 10588 converters: { 10589 "text script": function() {} 10590 }, 10591 dataFilter: function( response ) { 10592 jQuery.globalEval( response, options, doc ); 10593 } 10594 } ); 10595}; 10596 10597 10598jQuery.fn.extend( { 10599 wrapAll: function( html ) { 10600 var wrap; 10601 10602 if ( this[ 0 ] ) { 10603 if ( isFunction( html ) ) { 10604 html = html.call( this[ 0 ] ); 10605 } 10606 10607 // The elements to wrap the target around 10608 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 10609 10610 if ( this[ 0 ].parentNode ) { 10611 wrap.insertBefore( this[ 0 ] ); 10612 } 10613 10614 wrap.map( function() { 10615 var elem = this; 10616 10617 while ( elem.firstElementChild ) { 10618 elem = elem.firstElementChild; 10619 } 10620 10621 return elem; 10622 } ).append( this ); 10623 } 10624 10625 return this; 10626 }, 10627 10628 wrapInner: function( html ) { 10629 if ( isFunction( html ) ) { 10630 return this.each( function( i ) { 10631 jQuery( this ).wrapInner( html.call( this, i ) ); 10632 } ); 10633 } 10634 10635 return this.each( function() { 10636 var self = jQuery( this ), 10637 contents = self.contents(); 10638 10639 if ( contents.length ) { 10640 contents.wrapAll( html ); 10641 10642 } else { 10643 self.append( html ); 10644 } 10645 } ); 10646 }, 10647 10648 wrap: function( html ) { 10649 var htmlIsFunction = isFunction( html ); 10650 10651 return this.each( function( i ) { 10652 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); 10653 } ); 10654 }, 10655 10656 unwrap: function( selector ) { 10657 this.parent( selector ).not( "body" ).each( function() { 10658 jQuery( this ).replaceWith( this.childNodes ); 10659 } ); 10660 return this; 10661 } 10662} ); 10663 10664 10665jQuery.expr.pseudos.hidden = function( elem ) { 10666 return !jQuery.expr.pseudos.visible( elem ); 10667}; 10668jQuery.expr.pseudos.visible = function( elem ) { 10669 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); 10670}; 10671 10672 10673 10674 10675jQuery.ajaxSettings.xhr = function() { 10676 try { 10677 return new window.XMLHttpRequest(); 10678 } catch ( e ) {} 10679}; 10680 10681var xhrSuccessStatus = { 10682 10683 // File protocol always yields status code 0, assume 200 10684 0: 200, 10685 10686 // Support: IE <=9 only 10687 // trac-1450: sometimes IE returns 1223 when it should be 204 10688 1223: 204 10689 }, 10690 xhrSupported = jQuery.ajaxSettings.xhr(); 10691 10692support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 10693support.ajax = xhrSupported = !!xhrSupported; 10694 10695jQuery.ajaxTransport( function( options ) { 10696 var callback, errorCallback; 10697 10698 // Cross domain only allowed if supported through XMLHttpRequest 10699 if ( support.cors || xhrSupported && !options.crossDomain ) { 10700 return { 10701 send: function( headers, complete ) { 10702 var i, 10703 xhr = options.xhr(); 10704 10705 xhr.open( 10706 options.type, 10707 options.url, 10708 options.async, 10709 options.username, 10710 options.password 10711 ); 10712 10713 // Apply custom fields if provided 10714 if ( options.xhrFields ) { 10715 for ( i in options.xhrFields ) { 10716 xhr[ i ] = options.xhrFields[ i ]; 10717 } 10718 } 10719 10720 // Override mime type if needed 10721 if ( options.mimeType && xhr.overrideMimeType ) { 10722 xhr.overrideMimeType( options.mimeType ); 10723 } 10724 10725 // X-Requested-With header 10726 // For cross-domain requests, seeing as conditions for a preflight are 10727 // akin to a jigsaw puzzle, we simply never set it to be sure. 10728 // (it can always be set on a per-request basis or even using ajaxSetup) 10729 // For same-domain requests, won't change header if already provided. 10730 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 10731 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 10732 } 10733 10734 // Set headers 10735 for ( i in headers ) { 10736 xhr.setRequestHeader( i, headers[ i ] ); 10737 } 10738 10739 // Callback 10740 callback = function( type ) { 10741 return function() { 10742 if ( callback ) { 10743 callback = errorCallback = xhr.onload = 10744 xhr.onerror = xhr.onabort = xhr.ontimeout = 10745 xhr.onreadystatechange = null; 10746 10747 if ( type === "abort" ) { 10748 xhr.abort(); 10749 } else if ( type === "error" ) { 10750 10751 // Support: IE <=9 only 10752 // On a manual native abort, IE9 throws 10753 // errors on any property access that is not readyState 10754 if ( typeof xhr.status !== "number" ) { 10755 complete( 0, "error" ); 10756 } else { 10757 complete( 10758 10759 // File: protocol always yields status 0; see trac-8605, trac-14207 10760 xhr.status, 10761 xhr.statusText 10762 ); 10763 } 10764 } else { 10765 complete( 10766 xhrSuccessStatus[ xhr.status ] || xhr.status, 10767 xhr.statusText, 10768 10769 // Support: IE <=9 only 10770 // IE9 has no XHR2 but throws on binary (trac-11426) 10771 // For XHR2 non-text, let the caller handle it (gh-2498) 10772 ( xhr.responseType || "text" ) !== "text" || 10773 typeof xhr.responseText !== "string" ? 10774 { binary: xhr.response } : 10775 { text: xhr.responseText }, 10776 xhr.getAllResponseHeaders() 10777 ); 10778 } 10779 } 10780 }; 10781 }; 10782 10783 // Listen to events 10784 xhr.onload = callback(); 10785 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); 10786 10787 // Support: IE 9 only 10788 // Use onreadystatechange to replace onabort 10789 // to handle uncaught aborts 10790 if ( xhr.onabort !== undefined ) { 10791 xhr.onabort = errorCallback; 10792 } else { 10793 xhr.onreadystatechange = function() { 10794 10795 // Check readyState before timeout as it changes 10796 if ( xhr.readyState === 4 ) { 10797 10798 // Allow onerror to be called first, 10799 // but that will not handle a native abort 10800 // Also, save errorCallback to a variable 10801 // as xhr.onerror cannot be accessed 10802 window.setTimeout( function() { 10803 if ( callback ) { 10804 errorCallback(); 10805 } 10806 } ); 10807 } 10808 }; 10809 } 10810 10811 // Create the abort callback 10812 callback = callback( "abort" ); 10813 10814 try { 10815 10816 // Do send the request (this may raise an exception) 10817 xhr.send( options.hasContent && options.data || null ); 10818 } catch ( e ) { 10819 10820 // trac-14683: Only rethrow if this hasn't been notified as an error yet 10821 if ( callback ) { 10822 throw e; 10823 } 10824 } 10825 }, 10826 10827 abort: function() { 10828 if ( callback ) { 10829 callback(); 10830 } 10831 } 10832 }; 10833 } 10834} ); 10835 10836 10837 10838 10839// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 10840jQuery.ajaxPrefilter( function( s ) { 10841 if ( s.crossDomain ) { 10842 s.contents.script = false; 10843 } 10844} ); 10845 10846// Install script dataType 10847jQuery.ajaxSetup( { 10848 accepts: { 10849 script: "text/javascript, application/javascript, " + 10850 "application/ecmascript, application/x-ecmascript" 10851 }, 10852 contents: { 10853 script: /\b(?:java|ecma)script\b/ 10854 }, 10855 converters: { 10856 "text script": function( text ) { 10857 jQuery.globalEval( text ); 10858 return text; 10859 } 10860 } 10861} ); 10862 10863// Handle cache's special case and crossDomain 10864jQuery.ajaxPrefilter( "script", function( s ) { 10865 if ( s.cache === undefined ) { 10866 s.cache = false; 10867 } 10868 if ( s.crossDomain ) { 10869 s.type = "GET"; 10870 } 10871} ); 10872 10873// Bind script tag hack transport 10874jQuery.ajaxTransport( "script", function( s ) { 10875 10876 // This transport only deals with cross domain or forced-by-attrs requests 10877 if ( s.crossDomain || s.scriptAttrs ) { 10878 var script, callback; 10879 return { 10880 send: function( _, complete ) { 10881 script = jQuery( "<script>" ) 10882 .attr( s.scriptAttrs || {} ) 10883 .prop( { charset: s.scriptCharset, src: s.url } ) 10884 .on( "load error", callback = function( evt ) { 10885 script.remove(); 10886 callback = null; 10887 if ( evt ) { 10888 complete( evt.type === "error" ? 404 : 200, evt.type ); 10889 } 10890 } ); 10891 10892 // Use native DOM manipulation to avoid our domManip AJAX trickery 10893 document.head.appendChild( script[ 0 ] ); 10894 }, 10895 abort: function() { 10896 if ( callback ) { 10897 callback(); 10898 } 10899 } 10900 }; 10901 } 10902} ); 10903 10904 10905 10906 10907var oldCallbacks = [], 10908 rjsonp = /(=)\?(?=&|$)|\?\?/; 10909 10910// Default jsonp settings 10911jQuery.ajaxSetup( { 10912 jsonp: "callback", 10913 jsonpCallback: function() { 10914 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); 10915 this[ callback ] = true; 10916 return callback; 10917 } 10918} ); 10919 10920// Detect, normalize options and install callbacks for jsonp requests 10921jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 10922 10923 var callbackName, overwritten, responseContainer, 10924 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 10925 "url" : 10926 typeof s.data === "string" && 10927 ( s.contentType || "" ) 10928 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 10929 rjsonp.test( s.data ) && "data" 10930 ); 10931 10932 // Handle iff the expected data type is "jsonp" or we have a parameter to set 10933 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 10934 10935 // Get callback name, remembering preexisting value associated with it 10936 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 10937 s.jsonpCallback() : 10938 s.jsonpCallback; 10939 10940 // Insert callback into url or form data 10941 if ( jsonProp ) { 10942 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 10943 } else if ( s.jsonp !== false ) { 10944 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 10945 } 10946 10947 // Use data converter to retrieve json after script execution 10948 s.converters[ "script json" ] = function() { 10949 if ( !responseContainer ) { 10950 jQuery.error( callbackName + " was not called" ); 10951 } 10952 return responseContainer[ 0 ]; 10953 }; 10954 10955 // Force json dataType 10956 s.dataTypes[ 0 ] = "json"; 10957 10958 // Install callback 10959 overwritten = window[ callbackName ]; 10960 window[ callbackName ] = function() { 10961 responseContainer = arguments; 10962 }; 10963 10964 // Clean-up function (fires after converters) 10965 jqXHR.always( function() { 10966 10967 // If previous value didn't exist - remove it 10968 if ( overwritten === undefined ) { 10969 jQuery( window ).removeProp( callbackName ); 10970 10971 // Otherwise restore preexisting value 10972 } else { 10973 window[ callbackName ] = overwritten; 10974 } 10975 10976 // Save back as free 10977 if ( s[ callbackName ] ) { 10978 10979 // Make sure that re-using the options doesn't screw things around 10980 s.jsonpCallback = originalSettings.jsonpCallback; 10981 10982 // Save the callback name for future use 10983 oldCallbacks.push( callbackName ); 10984 } 10985 10986 // Call if it was a function and we have a response 10987 if ( responseContainer && isFunction( overwritten ) ) { 10988 overwritten( responseContainer[ 0 ] ); 10989 } 10990 10991 responseContainer = overwritten = undefined; 10992 } ); 10993 10994 // Delegate to script 10995 return "script"; 10996 } 10997} ); 10998 10999 11000 11001 11002// Support: Safari 8 only 11003// In Safari 8 documents created via document.implementation.createHTMLDocument 11004// collapse sibling forms: the second one becomes a child of the first one. 11005// Because of that, this security measure has to be disabled in Safari 8. 11006// https://bugs.webkit.org/show_bug.cgi?id=137337 11007support.createHTMLDocument = ( function() { 11008 var body = document.implementation.createHTMLDocument( "" ).body; 11009 body.innerHTML = "<form></form><form></form>"; 11010 return body.childNodes.length === 2; 11011} )(); 11012 11013 11014// Argument "data" should be string of html 11015// context (optional): If specified, the fragment will be created in this context, 11016// defaults to document 11017// keepScripts (optional): If true, will include scripts passed in the html string 11018jQuery.parseHTML = function( data, context, keepScripts ) { 11019 if ( typeof data !== "string" ) { 11020 return []; 11021 } 11022 if ( typeof context === "boolean" ) { 11023 keepScripts = context; 11024 context = false; 11025 } 11026 11027 var base, parsed, scripts; 11028 11029 if ( !context ) { 11030 11031 // Stop scripts or inline event handlers from being executed immediately 11032 // by using document.implementation 11033 if ( support.createHTMLDocument ) { 11034 context = document.implementation.createHTMLDocument( "" ); 11035 11036 // Set the base href for the created document 11037 // so any parsed elements with URLs 11038 // are based on the document's URL (gh-2965) 11039 base = context.createElement( "base" ); 11040 base.href = document.location.href; 11041 context.head.appendChild( base ); 11042 } else { 11043 context = document; 11044 } 11045 } 11046 11047 parsed = rsingleTag.exec( data ); 11048 scripts = !keepScripts && []; 11049 11050 // Single tag 11051 if ( parsed ) { 11052 return [ context.createElement( parsed[ 1 ] ) ]; 11053 } 11054 11055 parsed = buildFragment( [ data ], context, scripts ); 11056 11057 if ( scripts && scripts.length ) { 11058 jQuery( scripts ).remove(); 11059 } 11060 11061 return jQuery.merge( [], parsed.childNodes ); 11062}; 11063 11064 11065/** 11066 * Load a url into a page 11067 */ 11068jQuery.fn.load = function( url, params, callback ) { 11069 var selector, type, response, 11070 self = this, 11071 off = url.indexOf( " " ); 11072 11073 if ( off > -1 ) { 11074 selector = stripAndCollapse( url.slice( off ) ); 11075 url = url.slice( 0, off ); 11076 } 11077 11078 // If it's a function 11079 if ( isFunction( params ) ) { 11080 11081 // We assume that it's the callback 11082 callback = params; 11083 params = undefined; 11084 11085 // Otherwise, build a param string 11086 } else if ( params && typeof params === "object" ) { 11087 type = "POST"; 11088 } 11089 11090 // If we have elements to modify, make the request 11091 if ( self.length > 0 ) { 11092 jQuery.ajax( { 11093 url: url, 11094 11095 // If "type" variable is undefined, then "GET" method will be used. 11096 // Make value of this field explicit since 11097 // user can override it through ajaxSetup method 11098 type: type || "GET", 11099 dataType: "html", 11100 data: params 11101 } ).done( function( responseText ) { 11102 11103 // Save response for use in complete callback 11104 response = arguments; 11105 11106 self.html( selector ? 11107 11108 // If a selector was specified, locate the right elements in a dummy div 11109 // Exclude scripts to avoid IE 'Permission Denied' errors 11110 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 11111 11112 // Otherwise use the full result 11113 responseText ); 11114 11115 // If the request succeeds, this function gets "data", "status", "jqXHR" 11116 // but they are ignored because response was set above. 11117 // If it fails, this function gets "jqXHR", "status", "error" 11118 } ).always( callback && function( jqXHR, status ) { 11119 self.each( function() { 11120 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 11121 } ); 11122 } ); 11123 } 11124 11125 return this; 11126}; 11127 11128 11129 11130 11131jQuery.expr.pseudos.animated = function( elem ) { 11132 return jQuery.grep( jQuery.timers, function( fn ) { 11133 return elem === fn.elem; 11134 } ).length; 11135}; 11136 11137 11138 11139 11140jQuery.offset = { 11141 setOffset: function( elem, options, i ) { 11142 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 11143 position = jQuery.css( elem, "position" ), 11144 curElem = jQuery( elem ), 11145 props = {}; 11146 11147 // Set position first, in-case top/left are set even on static elem 11148 if ( position === "static" ) { 11149 elem.style.position = "relative"; 11150 } 11151 11152 curOffset = curElem.offset(); 11153 curCSSTop = jQuery.css( elem, "top" ); 11154 curCSSLeft = jQuery.css( elem, "left" ); 11155 calculatePosition = ( position === "absolute" || position === "fixed" ) && 11156 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 11157 11158 // Need to be able to calculate position if either 11159 // top or left is auto and position is either absolute or fixed 11160 if ( calculatePosition ) { 11161 curPosition = curElem.position(); 11162 curTop = curPosition.top; 11163 curLeft = curPosition.left; 11164 11165 } else { 11166 curTop = parseFloat( curCSSTop ) || 0; 11167 curLeft = parseFloat( curCSSLeft ) || 0; 11168 } 11169 11170 if ( isFunction( options ) ) { 11171 11172 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 11173 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 11174 } 11175 11176 if ( options.top != null ) { 11177 props.top = ( options.top - curOffset.top ) + curTop; 11178 } 11179 if ( options.left != null ) { 11180 props.left = ( options.left - curOffset.left ) + curLeft; 11181 } 11182 11183 if ( "using" in options ) { 11184 options.using.call( elem, props ); 11185 11186 } else { 11187 curElem.css( props ); 11188 } 11189 } 11190}; 11191 11192jQuery.fn.extend( { 11193 11194 // offset() relates an element's border box to the document origin 11195 offset: function( options ) { 11196 11197 // Preserve chaining for setter 11198 if ( arguments.length ) { 11199 return options === undefined ? 11200 this : 11201 this.each( function( i ) { 11202 jQuery.offset.setOffset( this, options, i ); 11203 } ); 11204 } 11205 11206 var rect, win, 11207 elem = this[ 0 ]; 11208 11209 if ( !elem ) { 11210 return; 11211 } 11212 11213 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) 11214 // Support: IE <=11 only 11215 // Running getBoundingClientRect on a 11216 // disconnected node in IE throws an error 11217 if ( !elem.getClientRects().length ) { 11218 return { top: 0, left: 0 }; 11219 } 11220 11221 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 11222 rect = elem.getBoundingClientRect(); 11223 win = elem.ownerDocument.defaultView; 11224 return { 11225 top: rect.top + win.pageYOffset, 11226 left: rect.left + win.pageXOffset 11227 }; 11228 }, 11229 11230 // position() relates an element's margin box to its offset parent's padding box 11231 // This corresponds to the behavior of CSS absolute positioning 11232 position: function() { 11233 if ( !this[ 0 ] ) { 11234 return; 11235 } 11236 11237 var offsetParent, offset, doc, 11238 elem = this[ 0 ], 11239 parentOffset = { top: 0, left: 0 }; 11240 11241 // position:fixed elements are offset from the viewport, which itself always has zero offset 11242 if ( jQuery.css( elem, "position" ) === "fixed" ) { 11243 11244 // Assume position:fixed implies availability of getBoundingClientRect 11245 offset = elem.getBoundingClientRect(); 11246 11247 } else { 11248 offset = this.offset(); 11249 11250 // Account for the *real* offset parent, which can be the document or its root element 11251 // when a statically positioned element is identified 11252 doc = elem.ownerDocument; 11253 offsetParent = elem.offsetParent || doc.documentElement; 11254 while ( offsetParent && 11255 ( offsetParent === doc.body || offsetParent === doc.documentElement ) && 11256 jQuery.css( offsetParent, "position" ) === "static" ) { 11257 11258 offsetParent = offsetParent.parentNode; 11259 } 11260 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { 11261 11262 // Incorporate borders into its offset, since they are outside its content origin 11263 parentOffset = jQuery( offsetParent ).offset(); 11264 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); 11265 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); 11266 } 11267 } 11268 11269 // Subtract parent offsets and element margins 11270 return { 11271 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 11272 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 11273 }; 11274 }, 11275 11276 // This method will return documentElement in the following cases: 11277 // 1) For the element inside the iframe without offsetParent, this method will return 11278 // documentElement of the parent window 11279 // 2) For the hidden or detached element 11280 // 3) For body or html element, i.e. in case of the html node - it will return itself 11281 // 11282 // but those exceptions were never presented as a real life use-cases 11283 // and might be considered as more preferable results. 11284 // 11285 // This logic, however, is not guaranteed and can change at any point in the future 11286 offsetParent: function() { 11287 return this.map( function() { 11288 var offsetParent = this.offsetParent; 11289 11290 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 11291 offsetParent = offsetParent.offsetParent; 11292 } 11293 11294 return offsetParent || documentElement; 11295 } ); 11296 } 11297} ); 11298 11299// Create scrollLeft and scrollTop methods 11300jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 11301 var top = "pageYOffset" === prop; 11302 11303 jQuery.fn[ method ] = function( val ) { 11304 return access( this, function( elem, method, val ) { 11305 11306 // Coalesce documents and windows 11307 var win; 11308 if ( isWindow( elem ) ) { 11309 win = elem; 11310 } else if ( elem.nodeType === 9 ) { 11311 win = elem.defaultView; 11312 } 11313 11314 if ( val === undefined ) { 11315 return win ? win[ prop ] : elem[ method ]; 11316 } 11317 11318 if ( win ) { 11319 win.scrollTo( 11320 !top ? val : win.pageXOffset, 11321 top ? val : win.pageYOffset 11322 ); 11323 11324 } else { 11325 elem[ method ] = val; 11326 } 11327 }, method, val, arguments.length ); 11328 }; 11329} ); 11330 11331// Support: Safari <=7 - 9.1, Chrome <=37 - 49 11332// Add the top/left cssHooks using jQuery.fn.position 11333// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 11334// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 11335// getComputedStyle returns percent when specified for top/left/bottom/right; 11336// rather than make the css module depend on the offset module, just check for it here 11337jQuery.each( [ "top", "left" ], function( _i, prop ) { 11338 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 11339 function( elem, computed ) { 11340 if ( computed ) { 11341 computed = curCSS( elem, prop ); 11342 11343 // If curCSS returns percentage, fallback to offset 11344 return rnumnonpx.test( computed ) ? 11345 jQuery( elem ).position()[ prop ] + "px" : 11346 computed; 11347 } 11348 } 11349 ); 11350} ); 11351 11352 11353// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 11354jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 11355 jQuery.each( { 11356 padding: "inner" + name, 11357 content: type, 11358 "": "outer" + name 11359 }, function( defaultExtra, funcName ) { 11360 11361 // Margin is only for outerHeight, outerWidth 11362 jQuery.fn[ funcName ] = function( margin, value ) { 11363 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 11364 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 11365 11366 return access( this, function( elem, type, value ) { 11367 var doc; 11368 11369 if ( isWindow( elem ) ) { 11370 11371 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 11372 return funcName.indexOf( "outer" ) === 0 ? 11373 elem[ "inner" + name ] : 11374 elem.document.documentElement[ "client" + name ]; 11375 } 11376 11377 // Get document width or height 11378 if ( elem.nodeType === 9 ) { 11379 doc = elem.documentElement; 11380 11381 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 11382 // whichever is greatest 11383 return Math.max( 11384 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 11385 elem.body[ "offset" + name ], doc[ "offset" + name ], 11386 doc[ "client" + name ] 11387 ); 11388 } 11389 11390 return value === undefined ? 11391 11392 // Get width or height on the element, requesting but not forcing parseFloat 11393 jQuery.css( elem, type, extra ) : 11394 11395 // Set width or height on the element 11396 jQuery.style( elem, type, value, extra ); 11397 }, type, chainable ? margin : undefined, chainable ); 11398 }; 11399 } ); 11400} ); 11401 11402 11403jQuery.each( [ 11404 "ajaxStart", 11405 "ajaxStop", 11406 "ajaxComplete", 11407 "ajaxError", 11408 "ajaxSuccess", 11409 "ajaxSend" 11410], function( _i, type ) { 11411 jQuery.fn[ type ] = function( fn ) { 11412 return this.on( type, fn ); 11413 }; 11414} ); 11415 11416 11417 11418 11419jQuery.fn.extend( { 11420 11421 bind: function( types, data, fn ) { 11422 return this.on( types, null, data, fn ); 11423 }, 11424 unbind: function( types, fn ) { 11425 return this.off( types, null, fn ); 11426 }, 11427 11428 delegate: function( selector, types, data, fn ) { 11429 return this.on( types, selector, data, fn ); 11430 }, 11431 undelegate: function( selector, types, fn ) { 11432 11433 // ( namespace ) or ( selector, types [, fn] ) 11434 return arguments.length === 1 ? 11435 this.off( selector, "**" ) : 11436 this.off( types, selector || "**", fn ); 11437 }, 11438 11439 hover: function( fnOver, fnOut ) { 11440 return this 11441 .on( "mouseenter", fnOver ) 11442 .on( "mouseleave", fnOut || fnOver ); 11443 } 11444} ); 11445 11446jQuery.each( 11447 ( "blur focus focusin focusout resize scroll click dblclick " + 11448 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 11449 "change select submit keydown keypress keyup contextmenu" ).split( " " ), 11450 function( _i, name ) { 11451 11452 // Handle event binding 11453 jQuery.fn[ name ] = function( data, fn ) { 11454 return arguments.length > 0 ? 11455 this.on( name, null, data, fn ) : 11456 this.trigger( name ); 11457 }; 11458 } 11459); 11460 11461 11462 11463 11464// Support: Android <=4.0 only 11465// Make sure we trim BOM and NBSP 11466// Require that the "whitespace run" starts from a non-whitespace 11467// to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position. 11468var rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g; 11469 11470// Bind a function to a context, optionally partially applying any 11471// arguments. 11472// jQuery.proxy is deprecated to promote standards (specifically Function#bind) 11473// However, it is not slated for removal any time soon 11474jQuery.proxy = function( fn, context ) { 11475 var tmp, args, proxy; 11476 11477 if ( typeof context === "string" ) { 11478 tmp = fn[ context ]; 11479 context = fn; 11480 fn = tmp; 11481 } 11482 11483 // Quick check to determine if target is callable, in the spec 11484 // this throws a TypeError, but we will just return undefined. 11485 if ( !isFunction( fn ) ) { 11486 return undefined; 11487 } 11488 11489 // Simulated bind 11490 args = slice.call( arguments, 2 ); 11491 proxy = function() { 11492 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 11493 }; 11494 11495 // Set the guid of unique handler to the same of original handler, so it can be removed 11496 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 11497 11498 return proxy; 11499}; 11500 11501jQuery.holdReady = function( hold ) { 11502 if ( hold ) { 11503 jQuery.readyWait++; 11504 } else { 11505 jQuery.ready( true ); 11506 } 11507}; 11508jQuery.isArray = Array.isArray; 11509jQuery.parseJSON = JSON.parse; 11510jQuery.nodeName = nodeName; 11511jQuery.isFunction = isFunction; 11512jQuery.isWindow = isWindow; 11513jQuery.camelCase = camelCase; 11514jQuery.type = toType; 11515 11516jQuery.now = Date.now; 11517 11518jQuery.isNumeric = function( obj ) { 11519 11520 // As of jQuery 3.0, isNumeric is limited to 11521 // strings and numbers (primitives or objects) 11522 // that can be coerced to finite numbers (gh-2662) 11523 var type = jQuery.type( obj ); 11524 return ( type === "number" || type === "string" ) && 11525 11526 // parseFloat NaNs numeric-cast false positives ("") 11527 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 11528 // subtraction forces infinities to NaN 11529 !isNaN( obj - parseFloat( obj ) ); 11530}; 11531 11532jQuery.trim = function( text ) { 11533 return text == null ? 11534 "" : 11535 ( text + "" ).replace( rtrim, "$1" ); 11536}; 11537 11538 11539 11540// Register as a named AMD module, since jQuery can be concatenated with other 11541// files that may use define, but not via a proper concatenation script that 11542// understands anonymous AMD modules. A named AMD is safest and most robust 11543// way to register. Lowercase jquery is used because AMD module names are 11544// derived from file names, and jQuery is normally delivered in a lowercase 11545// file name. Do this after creating the global so that if an AMD module wants 11546// to call noConflict to hide this version of jQuery, it will work. 11547 11548// Note that for maximum portability, libraries that are not jQuery should 11549// declare themselves as anonymous modules, and avoid setting a global if an 11550// AMD loader is present. jQuery is a special case. For more information, see 11551// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 11552 11553if ( t
11553rue ) { 11554 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() { 11555 return jQuery; 11556 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 11557 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 11558} 11559 11560 11561 11562 11563var 11564 11565 // Map over jQuery in case of overwrite 11566 _jQuery = window.jQuery, 11567 11568 // Map over the $ in case of overwrite 11569 _$ = window.$; 11570 11571jQuery.noConflict = function( deep ) { 11572 if ( window.$ === jQuery ) { 11573 window.$ = _$; 11574 } 11575 11576 if ( deep && window.jQuery === jQuery ) { 11577 window.jQuery = _jQuery; 11578 } 11579 11580 return jQuery; 11581}; 11582 11583// Expose jQuery and $ identifiers, even in AMD 11584// (trac-7102#comment:10, https://github.com/jquery/jquery/pull/557) 11585// and CommonJS for browser emulators (trac-13566) 11586if ( typeof noGlobal === "undefined" ) { 11587 window.jQuery = window.$ = jQuery; 11588} 11589 11590 11591 11592 11593return jQuery; 11594} ); 11595 11596 11597/***/ }) 11598 11599/******/ }); 11600/************************************************************************/ 11601/******/ // The module cache 11602/******/ var __webpack_module_cache__ = {}; 11603/******/ 11604/******/ // The require function 11605/******/ function __webpack_require__(moduleId) { 11606/******/ // Check if module is in cache 11607/******/ var cachedModule = __webpack_module_cache__[moduleId]; 11608/******/ if (cachedModule !== undefined) { 11609/******/ return cachedModule.exports; 11610/******/ } 11611/******/ // Create a new module (and put it into the cache) 11612/******/ var module = __webpack_module_cache__[moduleId] = { 11613/******/ // no module.id needed 11614/******/ // no module.loaded needed 11615/******/ exports: {} 11616/******/ }; 11617/******/ 11618/******/ // Execute the module function 11619/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); 11620/******/ 11621/******/ // Return the exports of the module 11622/******/ return module.exports; 11623/******/ } 11624/******/ 11625/************************************************************************/ 11626/******/ /* webpack/runtime/compat get default export */ 11627/******/ (() => { 11628/******/ // getDefaultExport function for compatibility with non-harmony modules 11629/******/ __webpack_require__.n = (module) => { 11630/******/ var getter = module && module.__esModule ? 11631/******/ () => (module['default']) : 11632/******/ () => (module); 11633/******/ __webpack_require__.d(getter, { a: getter }); 11634/******/ return getter; 11635/******/ }; 11636/******/ })(); 11637/******/ 11638/******/ /* webpack/runtime/define property getters */ 11639/******/ (() => { 11640/******/ // define getter functions for harmony exports 11641/******/ __webpack_require__.d = (exports, definition) => { 11642/******/ for(var key in definition) { 11643/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 11644/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 11645/******/ } 11646/******/ } 11647/******/ }; 11648/******/ })(); 11649/******/ 11650/******/ /* webpack/runtime/hasOwnProperty shorthand */ 11651/******/ (() => { 11652/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 11653/******/ })(); 11654/******/ 11655/************************************************************************/ 11656var __webpack_exports__ = {}; 11657// This entry needs to be wrapped in an IIFE because it needs to be in strict mode. 11658(() => { 11659"use strict"; 11660 11661// EXTERNAL MODULE: ./node_modules/jquery/dist/jquery.js 11662var jquery = __webpack_require__(692); 11663var jquery_default = /*#__PURE__*/__webpack_require__.n(jquery); 11664// EXTERNAL MODULE: ./wp-content/themes/sfrtheme/assets/js/css_browser_selector.js 11665var css_browser_selector = __webpack_require__(360); 11666;// ./wp-content/themes/sfrtheme/assets/js/input-address.js 11667 11668jquery_default()(document).ready(function () { 11669 ajaxEligibiliteAddress(); 11670 jquery_default()('#input-city').change(function () { 11671 jquery_default()('#input-street').val('').prop("disabled", true); 11672 jquery_default()('#input-number').val('').prop("disabled", true); 11673 jquery_default()('#input-lat').val(''); 11674 jquery_default()('#input-lon').val(''); 11675 jquery_default()('#button-submit').prop("disabled", true); 11676 if (!jquery_default()(this).val()) { 11677 return; 11678 } 11679 jquery_default()('#input-street').parents('.reverse').addClass('loading'); 11680 var params = { 11681 'postal_code': jquery_default()(this).val().split(',')[1] 11682 }; 11683 jquery_default().ajax({ 11684 url: sfrJSVars.ajaxurl, 11685 method: 'POST', 11686 data: { 11687 'action': 'ajaxGetStreetNames', 11688 'params': params 11689 }, 11690 success: function (data) { 11691 var streetNames = JSON.parse(data); 11692 jquery_default()('#input-street').parents('.reverse').removeClass('loading'); 11693 jquery_default()("#input-street").prop("disabled", false); 11694 jquery_default()("#input-street").easyAutocomplete({ 11695 data: streetNames, 11696 requestDelay: 500, 11697 list: { 11698 match: { 11699 enabled: true 11700 }, 11701 onClickEvent: getStreetNumbers 11702 }, 11703 theme: "square" 11704 }); 11705 }, 11706 error: function (request, error) { 11707 console.log(error); 11708 } 11709 }); 11710 }); 11711 function getStreetNumbers() { 11712 jquery_default()('#input-number').val('').prop("disabled", true); 11713 jquery_default()('#input-lat').val(''); 11714 jquery_default()('#input-lon').val(''); 11715 jquery_default()('#button-submit').prop("disabled", true); 11716 if (!jquery_default()("#input-street").val()) { 11717 return; 11718 } 11719 jquery_default()('#input-number').parents('.reverse').addClass('loading'); 11720 var params = { 11721 'postal_code': jquery_default()("#input-city").val().split(',')[1], 11722 'street_name': jquery_default()("#input-street").val() 11723 }; 11724 jquery_default().ajax({ 11725 url: sfrJSVars.ajaxurl, 11726 method: 'POST', 11727 data: { 11728 'action': 'ajaxGetStreetNumbers', 11729 'params': params 11730 }, 11731 success: function (data) { 11732 var streetNumbers = JSON.parse(data); 11733 jquery_default()('#input-number').parents('.reverse').removeClass('loading'); 11734 jquery_default()("#input-number").prop("disabled", false); 11735 jquery_default()("#input-number").data('defaultval', streetNumbers[
117350]); 11736 jquery_default()('#button-submit').prop("disabled", false); 11737 jquery_default()("#input-number").easyAutocomplete({ 11738 data: streetNumbers, 11739 requestDelay: 500, 11740 list: { 11741 match: { 11742 enabled: true 11743 } 11744 }, 11745 theme: "square" 11746 }); 11747 }, 11748 error: function (request, error) { 11749 console.log(error); 11750 } 11751 }); 11752 } 11753}); 11754function ajaxEligibiliteAddress() { 11755 /* Eligibilité - Appel AJAX pour formulaire adresse - géolocalisation */ 11756 jquery_default()('#eligibilite-address-form input, #eligibilite-address-form select').change(function () { 11757 jquery_default()('#eligibilite-address-form').removeClass('error_addr, error_fields'); 11758 }); 11759 //carrouselInit(); 11760 if (document.getElementById('eligibilite-address-form')) { 11761 document.getElementById('eligibilite-address-form').addEventListener('submit', function (e) { 11762 e.preventDefault(); 11763 var number = jquery_default()("#input-number").data('defaultval'); 11764 if (jquery_default()('#input-number').val() != '') { 11765 jquery_default()('#eac-container-input-number ul li').each(function () { 11766 if (jquery_default()(this).text() == jquery_default()('#input-number').val()) { 11767 number = jquery_default()('#input-number').val(); 11768 } 11769 }); 11770 } 11771 if (jquery_default()('#input-street').val() != '' && jquery_default()('option:selected', '#input-city').text() != '') { 11772 jquery_default()('#input-lat').val(''); 11773 jquery_default()('#input-lon').val(''); 11774 jquery_default()('#eligibilite-address-form .button').addClass('loading'); 11775 var params = { 11776 'postal_code': jquery_default()("#input-city").val().split(',')[1], 11777 'street_name': jquery_default()("#input-street").val(), 11778 'street_number': number 11779 }; 11780 jquery_default().ajax({ 11781 url: sfrJSVars.ajaxurl, 11782 method: 'POST', 11783 data: { 11784 'action': 'ajaxGetLatLon', 11785 'params': params 11786 }, 11787 success: function (data) { 11788 var streetLatLong = JSON.parse(data); 11789 //console.log(streetLatLong); 11790 jquery_default()('#eligibilite-address-form .button').removeClass('loading'); 11791 jquery_default()('#eligibilite-input-address').hide(); 11792 jquery_default()('#eligibilite .back').removeClass('masked'); 11793 jquery_default()('#eligibilite-map').css('display', 'flex'); 11794 eligibiliteMap(streetLatLong.lat, streetLatLong.lon, jquery_default()('#input-number').val(), jquery_default()('#input-street').val(), jquery_default()('option:selected', '#input-city').text()); 11795 }, 11796 error: function (request, error) { 11797 console.log(error); 11798 } 11799 }); 11800 } else { 11801 jquery_default()('#eligibilite-address-form').addClass('error_fields'); 11802 } 11803 }, { 11804 passive: false 11805 }); 11806 } 11807} 11808function eligibiliteMap(lat, lng, number, street, city) { 11809 var mymap = L.map('eligibilite-mapbox').setView([lat, lng], 17); 11810 L.tileLayer("https://data.geopf.fr/wmts?" + "&REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0" + "&STYLE=normal" + "&TILEMATRIXSET=PM" + "&FORMAT=image/jpeg" + "&LAYER=ORTHOIMAGERY.ORTHOPHOTOS" + "&TILEMATRIX={z}" + "&TILEROW={y}" + "&TILECOL={x}", { 11811 minZoom: 12, 11812 maxZoom: 19, 11813 attribution: "IGN-F/Geoportail", 11814 tileSize: 256 // les tuiles du Géooportail font 256x256px 11815 }).addTo(mymap); 11816 var myIcon = L.icon({ 11817 iconUrl: sfrJSVars.mapmarker.sizes.large, 11818 iconAnchor: [sfrJSVars.mapmarker.sizes['large-width'] / 2, sfrJSVars.mapmarker.sizes['large-height']] 11819 }); 11820 var myMarker = L.marker([lat, lng], { 11821 icon: myIcon 11822 }); 11823 myMarker.addTo(mymap); 11824 jquery_default()('#elegibilite-geo-lat').val(lat); 11825 jquery_default()('#elegibilite-geo-lng').val(lng); 11826 mymap.on('click', function (e) { 11827 jquery_default()('#elegibilite-geo-lat').val(e.latlng.lat); 11828 jquery_default()('#elegibilite-geo-lng').val(e.latlng.lng); 11829 myMarker.setLatLng([e.latlng.lat, e.latlng.lng]).update(); 11830 }); 11831 jquery_default()('#eligibilite .back').unbind().on('click', function () { 11832 mymap.off(); 11833 mymap.remove(); 11834 jquery_default()('#eligibilite-input-address').css('display', 'flex'); 11835 ; 11836 jquery_default()('#eligibilite .back').addClass('masked'); 11837 jquery_default()('#eligibilite-map').hide(); 11838 }); 11839 document.getElementById('form-elegibilite-geo').addEventListener('submit', function (e) { 11840 e.preventDefault(); 11841 ajaxEligibiliteResults(jquery_default()('#elegibilite-geo-lat').val(), jquery_default()('#elegibilite-geo-lng').val(), number, street, city); 11842 }, { 11843 passive: false 11844 }); 11845} 11846function ajaxEligibiliteResults(lat, lng, number, street, city) { 11847 jquery_default()('#eligibilite-map .button').addClass('loading'); 11848 jquery_default().ajax({ 11849 url: sfrJSVars.ajaxurl, 11850 method: 'POST', 11851 data: { 11852 'action': 'ajaxEligibiliteResults', 11853 'params': { 11854 lat: lat, 11855 lng: lng, 11856 number: number, 11857 street: street, 11858 city: city 11859 } 11860 }, 11861 success: function (data) { 11862 //$('#eligibilite-map .button').removeClass('loading'); 11863 if (data == "done") { 11864 window.location.href = sfrJSVars.box_ff_page_link + '#ff'; 11865 //console.log(data); 11866 } else { 11867 jquery_default()('#eligibilite-map .button').removeClass('loading'); 11868 alert(data); 11869 } 11870 }, 11871 error: function (request, error) { 11872 //$('#eligibilite-map .button').removeClass('loading'); 11873 console.log(request, error); 11874 } 11875 }); 11876} 11877;// ./wp-content/themes/sfrtheme/assets/js/axeptio.js 11878 11879const axeptioOpenSettings = { 11880 automatic: true, 11881 currentStepIndex: 0 11882}; 11883const maxOpenAttempts = 40; 11884const openRetryDelayMs = 250; 11885const maxShowButtonAttempts = 6; 11886const showButtonRetryDelayMs = 400; 11887function getAxeptioShadowRoot() { 11888 const host = document.querySelector('.axeptio_mount .needsclick'); 11889 return host?.shadowRoot ?? null; 11890} 11891function isAxeptioWidgetVisible() { 11892 const root = getAxeptioShadowRoot(); 11893 if (!root) { 11894 return false;
11895 } 11896 return Boolean(root.querySelector('[data-testid="modal-container"], [data-testid="widget-container"], .axeptio_widget')); 11897} 11898function hasDuplicateAxeptioWidgets() { 11899 const root = getAxeptioShadowRoot(); 11900 if (!root) { 11901 return false; 11902 } 11903 return root.querySelectorAll('#axeptio_btn_acceptAll').length > 1; 11904} 11905function isAxeptioSdkReady() { 11906 return typeof window.openAxeptioCookies === 'function' || window.axeptioSDK && typeof window.axeptioSDK.openCookies === 'function'; 11907} 11908function isAxeptioAutoOpenPending() { 11909 if (window.__axeptioConsentCompleted) { 11910 return false; 11911 } 11912 if (!document.querySelector('.axeptio_mount') || isAxeptioWidgetVisible()) { 11913 return false; 11914 } 11915 return true; 11916} 11917function forceShowAxeptioButton(attempt = 0) { 11918 if (typeof window.showAxeptioButton === 'function') { 11919 window.showAxeptioButton(); 11920 } 11921 if (attempt < maxShowButtonAttempts) { 11922 window.setTimeout(() => forceShowAxeptioButton(attempt + 1), showButtonRetryDelayMs); 11923 } 11924} 11925function registerAxeptioConsentTracking() { 11926 window._axcb = window._axcb || []; 11927 window._axcb.push(function (sdk) { 11928 if (!sdk || typeof sdk.on !== 'function') { 11929 return; 11930 } 11931 sdk.on('cookies:complete', function () { 11932 window.__axeptioConsentCompleted = true; 11933 forceShowAxeptioButton(); 11934 }, { 11935 replay: true 11936 }); 11937 }); 11938} 11939function getAxeptioOpenSettings() { 11940 if (window.__axeptioConsentCompleted) { 11941 return { 11942 automatic: true, 11943 currentStepIndex: 1 11944 }; 11945 } 11946 return axeptioOpenSettings; 11947} 11948function openAxeptioViaSdk() { 11949 const settings = getAxeptioOpenSettings(); 11950 if (typeof window.hideAxeptioButton === 'function') { 11951 window.hideAxeptioButton(); 11952 } 11953 if (typeof window.openAxeptioCookies === 'function') { 11954 window.openAxeptioCookies(settings); 11955 return; 11956 } 11957 if (window.axeptioSDK?.openCookies) { 11958 window.axeptioSDK.openCookies(settings); 11959 } 11960} 11961function tryOpenAxeptioPanel(attempt = 0) { 11962 if (isAxeptioWidgetVisible() || hasDuplicateAxeptioWidgets()) { 11963 return; 11964 } 11965 if (!isAxeptioSdkReady()) { 11966 window._axcb = window._axcb || []; 11967 window._axcb.push(() => tryOpenAxeptioPanel(0)); 11968 return; 11969 } 11970 if (isAxeptioAutoOpenPending() && attempt < maxOpenAttempts) { 11971 window.setTimeout(() => tryOpenAxeptioPanel(attempt + 1), openRetryDelayMs); 11972 return; 11973 } 11974 if (isAxeptioWidgetVisible() || hasDuplicateAxeptioWidgets()) { 11975 return; 11976 } 11977 openAxeptioViaSdk(); 11978} 11979function openAxeptioPanel(event) { 11980 if (event) { 11981 event.preventDefault(); 11982 } 11983 tryOpenAxeptioPanel(); 11984} 11985registerAxeptioConsentTracking(); 11986jquery_default()(document).on('click', '.open-axeptio-cookies', openAxeptioPanel); 11987;// ./node_modules/swiper/shared/ssr-window.esm.mjs 11988/** 11989 * SSR Window 5.0.1 11990 * Better handling for window object in SSR environment 11991 * https://github.com/nolimits4web/ssr-window 11992 * 11993 * Copyright 2025, Vladimir Kharlampidi 11994 * 11995 * Licensed under MIT 11996 * 11997 * Released on: June 27, 2025 11998 */ 11999/* eslint-disable no-param-reassign */ 12000function ssr_window_esm_isObject(obj) { 12001 return obj !== null && typeof obj === 'object' && 'constructor' in obj && obj.constructor === Object; 12002} 12003function extend(target, src) { 12004 if (target === void 0) { 12005 target = {}; 12006 } 12007 if (src === void 0) { 12008 src = {}; 12009 } 12010 const noExtend = ['__proto__', 'constructor', 'prototype']; 12011 Object.keys(src).filter(key => noExtend.indexOf(key) < 0).forEach(key => { 12012 if (typeof target[key] === 'undefined') target[key] = src[key];else if (ssr_window_esm_isObject(src[key]) && ssr_window_esm_isObject(target[key]) && Object.keys(src[key]).length > 0) { 12013 extend(target[key], src[key]); 12014 } 12015 }); 12016} 12017const ssrDocument = { 12018 body: {}, 12019 addEventListener() {}, 12020 removeEventListener() {}, 12021 activeElement: { 12022 blur() {}, 12023 nodeName: '' 12024 }, 12025 querySelector() { 12026 return null; 12027 }, 12028 querySelectorAll() { 12029 return []; 12030 }, 12031 getElementById() { 12032 return null; 12033 }, 12034 createEvent() { 12035 return { 12036 initEvent() {} 12037 }; 12038 }, 12039 createElement() { 12040 return { 12041 children: [], 12042 childNodes: [], 12043 style: {}, 12044 setAttribute() {}, 12045 getElementsByTagName() { 12046 return []; 12047 } 12048 }; 12049 }, 12050 createElementNS() { 12051 return {}; 12052 }, 12053 importNode() { 12054 return null; 12055 }, 12056 location: { 12057 hash: '', 12058 host: '', 12059 hostname: '', 12060 href: '', 12061 origin: '', 12062 pathname: '', 12063 protocol: '', 12064 search: '' 12065 } 12066}; 12067function ssr_window_esm_getDocument() { 12068 const doc = typeof document !== 'undefined' ? document : {}; 12069 extend(doc, ssrDocument); 12070 return doc; 12071} 12072const ssrWindow = { 12073 document: ssrDocument, 12074 navigator: { 12075 userAgent: '' 12076 }, 12077 location: { 12078 hash: '', 12079 host: '', 12080 hostname: '', 12081 href: '', 12082 origin: '', 12083 pathname: '', 12084 protocol: '', 12085 search: '' 12086 }, 12087 history: { 12088 replaceState() {}, 12089 pushState() {}, 12090 go() {}, 12091 back() {} 12092 }, 12093 CustomEvent: function CustomEvent() { 12094 return this; 12095 }, 12096 addEventListener() {}, 12097 removeEventListener() {}, 12098 getComputedStyle() { 12099 return { 12100 getPropertyValue() { 12101 return ''; 12102 } 12103 }; 12104 }, 12105 Image() {}, 12106 Date() {}, 12107 screen: {}, 12108 setTimeout() {},
vendor: 1,033 bytes, lines 12109-12161
12109 clearTimeout() {}, 12110 matchMedia() { 12111 return {}; 12112 }, 12113 requestAnimationFrame(callback) { 12114 if (typeof setTimeout === 'undefined') { 12115 callback(); 12116 return null; 12117 } 12118 return setTimeout(callback, 0); 12119 }, 12120 cancelAnimationFrame(id) { 12121 if (typeof setTimeout === 'undefined') { 12122 return; 12123 } 12124 clearTimeout(id); 12125 } 12126}; 12127function ssr_window_esm_getWindow() { 12128 const win = typeof window !== 'undefined' ? window : {}; 12129 extend(win, ssrWindow); 12130 return win; 12131} 12132 12133 12134 12135;// ./node_modules/swiper/shared/utils.mjs 12136 12137 12138function utils_classesToTokens(classes) { 12139 if (classes === void 0) { 12140 classes = ''; 12141 } 12142 return classes.trim().split(' ').filter(c => !!c.trim()); 12143} 12144 12145function deleteProps(obj) { 12146 const object = obj; 12147 Object.keys(object).forEach(key => { 12148 try { 12149 object[key] = null; 12150 } catch (e) { 12151 // no getter for object 12152 } 12153 try { 12154 delete object[key]; 12155 } catch (e) { 12156 // something got wrong 12157 } 12158 }); 12159} 12160function utils_nextTick(callback, delay) { 12161 if (delay === void 0) {
vendor: 4,801 bytes, lines 12162-12291
12162 delay = 0; 12163 } 12164 return setTimeout(callback, delay); 12165} 12166function utils_now() { 12167 return Date.now(); 12168} 12169function utils_getComputedStyle(el) { 12170 const window = ssr_window_esm_getWindow(); 12171 let style; 12172 if (window.getComputedStyle) { 12173 style = window.getComputedStyle(el, null); 12174 } 12175 if (!style && el.currentStyle) { 12176 style = el.currentStyle; 12177 } 12178 if (!style) { 12179 style = el.style; 12180 } 12181 return style; 12182} 12183function utils_getTranslate(el, axis) { 12184 if (axis === void 0) { 12185 axis = 'x'; 12186 } 12187 const window = ssr_window_esm_getWindow(); 12188 let matrix; 12189 let curTransform; 12190 let transformMatrix; 12191 const curStyle = utils_getComputedStyle(el); 12192 if (window.WebKitCSSMatrix) { 12193 curTransform = curStyle.transform || curStyle.webkitTransform; 12194 if (curTransform.split(',').length > 6) { 12195 curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', '); 12196 } 12197 // Some old versions of Webkit choke when 'none' is passed; pass 12198 // empty string instead in this case 12199 transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform); 12200 } else { 12201 transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,'); 12202 matrix = transformMatrix.toString().split(','); 12203 } 12204 if (axis === 'x') { 12205 // Latest Chrome and webkits Fix 12206 if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41; 12207 // Crazy IE10 Matrix 12208 else if (matrix.length === 16) curTransform = parseFloat(matrix[12]); 12209 // Normal Browsers 12210 else curTransform = parseFloat(matrix[4]); 12211 } 12212 if (axis === 'y') { 12213 // Latest Chrome and webkits Fix 12214 if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42; 12215 // Crazy IE10 Matrix 12216 else if (matrix.length === 16) curTransform = parseFloat(matrix[13]); 12217 // Normal Browsers 12218 else curTransform = parseFloat(matrix[5]); 12219 } 12220 return curTransform || 0; 12221} 12222function utils_isObject(o) { 12223 return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) === 'Object'; 12224} 12225function isNode(node) { 12226 // eslint-disable-next-line 12227 if (typeof window !== 'undefined' && typeof window.HTMLElement !== 'undefined') { 12228 return node instanceof HTMLElement; 12229 } 12230 return node && (node.nodeType === 1 || node.nodeType === 11); 12231} 12232function utils_extend() { 12233 const to = Object(arguments.length <= 0 ? undefined : arguments[0]); 12234 const noExtend = ['__proto__', 'constructor', 'prototype']; 12235 for (let i = 1; i < arguments.length; i += 1) { 12236 const nextSource = i < 0 || arguments.length <= i ? undefined : arguments[i]; 12237 if (nextSource !== undefined && nextSource !== null && !isNode(nextSource)) { 12238 const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0); 12239 for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) { 12240 const nextKey = keysArray[nextIndex]; 12241 const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey); 12242 if (desc !== undefined && desc.enumerable) { 12243 if (utils_isObject(to[nextKey]) && utils_isObject(nextSource[nextKey])) { 12244 if (nextSource[nextKey].__swiper__) { 12245 to[nextKey] = nextSource[nextKey]; 12246 } else { 12247 utils_extend(to[nextKey], nextSource[nextKey]); 12248 } 12249 } else if (!utils_isObject(to[nextKey]) && utils_isObject(nextSource[nextKey])) { 12250 to[nextKey] = {}; 12251 if (nextSource[nextKey].__swiper__) { 12252 to[nextKey] = nextSource[nextKey]; 12253 } else { 12254 utils_extend(to[nextKey], nextSource[nextKey]); 12255 } 12256 } else { 12257 to[nextKey] = nextSource[nextKey]; 12258 } 12259 } 12260 } 12261 } 12262 } 12263 return to; 12264} 12265function utils_setCSSProperty(el, varName, varValue) { 12266 el.style.setProperty(varName, varValue); 12267} 12268function animateCSSModeScroll(_ref) { 12269 let { 12270 swiper, 12271 targetPosition, 12272 side 12273 } = _ref; 12274 const window = ssr_window_esm_getWindow(); 12275 const startPosition = -swiper.translate; 12276 let startTime = null; 12277 let time; 12278 const duration = swiper.params.speed; 12279 swiper.wrapperEl.style.scrollSnapType = 'none'; 12280 window.cancelAnimationFrame(swiper.cssModeFrameID); 12281 const dir = targetPosition > startPosition ? 'next' : 'prev'; 12282 const isOutOfBound = (current, target) => { 12283 return dir === 'next' && current >= target || dir === 'prev' && current <= target; 12284 }; 12285 const animate = () => { 12286 time = new Date().getTime(); 12287 if (startTime === null) { 12288 startTime = time; 12289 } 12290 const progress = Math.max(Math.min((time - startTime) / duration, 1), 0); 12291 const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
vendor: 6,281 bytes, lines 12292-12492
12292 let currentPosition = startPosition + easeProgress * (targetPosition - startPosition); 12293 if (isOutOfBound(currentPosition, targetPosition)) { 12294 currentPosition = targetPosition; 12295 } 12296 swiper.wrapperEl.scrollTo({ 12297 [side]: currentPosition 12298 }); 12299 if (isOutOfBound(currentPosition, targetPosition)) { 12300 swiper.wrapperEl.style.overflow = 'hidden'; 12301 swiper.wrapperEl.style.scrollSnapType = ''; 12302 setTimeout(() => { 12303 swiper.wrapperEl.style.overflow = ''; 12304 swiper.wrapperEl.scrollTo({ 12305 [side]: currentPosition 12306 }); 12307 }); 12308 window.cancelAnimationFrame(swiper.cssModeFrameID); 12309 return; 12310 } 12311 swiper.cssModeFrameID = window.requestAnimationFrame(animate); 12312 }; 12313 animate(); 12314} 12315function utils_getSlideTransformEl(slideEl) { 12316 return slideEl.querySelector('.swiper-slide-transform') || slideEl.shadowRoot && slideEl.shadowRoot.querySelector('.swiper-slide-transform') || slideEl; 12317} 12318function utils_elementChildren(element, selector) { 12319 if (selector === void 0) { 12320 selector = ''; 12321 } 12322 const window = ssr_window_esm_getWindow(); 12323 const children = [...element.children]; 12324 if (window.HTMLSlotElement && element instanceof HTMLSlotElement) { 12325 children.push(...element.assignedElements()); 12326 } 12327 if (!selector) { 12328 return children; 12329 } 12330 return children.filter(el => el.matches(selector)); 12331} 12332function elementIsChildOfSlot(el, slot) { 12333 // Breadth-first search through all parent's children and assigned elements 12334 const elementsQueue = [slot]; 12335 while (elementsQueue.length > 0) { 12336 const elementToCheck = elementsQueue.shift(); 12337 if (el === elementToCheck) { 12338 return true; 12339 } 12340 elementsQueue.push(...elementToCheck.children, ...(elementToCheck.shadowRoot ? elementToCheck.shadowRoot.children : []), ...(elementToCheck.assignedElements ? elementToCheck.assignedElements() : [])); 12341 } 12342} 12343function elementIsChildOf(el, parent) { 12344 const window = ssr_window_esm_getWindow(); 12345 let isChild = parent.contains(el); 12346 if (!isChild && window.HTMLSlotElement && parent instanceof HTMLSlotElement) { 12347 const children = [...parent.assignedElements()]; 12348 isChild = children.includes(el); 12349 if (!isChild) { 12350 isChild = elementIsChildOfSlot(el, parent); 12351 } 12352 } 12353 return isChild; 12354} 12355function showWarning(text) { 12356 try { 12357 console.warn(text); 12358 return; 12359 } catch (err) { 12360 // err 12361 } 12362} 12363function utils_createElement(tag, classes) { 12364 if (classes === void 0) { 12365 classes = []; 12366 } 12367 const el = document.createElement(tag); 12368 el.classList.add(...(Array.isArray(classes) ? classes : utils_classesToTokens(classes))); 12369 return el; 12370} 12371function utils_elementOffset(el) { 12372 const window = getWindow(); 12373 const document = getDocument(); 12374 const box = el.getBoundingClientRect(); 12375 const body = document.body; 12376 const clientTop = el.clientTop || body.clientTop || 0; 12377 const clientLeft = el.clientLeft || body.clientLeft || 0; 12378 const scrollTop = el === window ? window.scrollY : el.scrollTop; 12379 const scrollLeft = el === window ? window.scrollX : el.scrollLeft; 12380 return { 12381 top: box.top + scrollTop - clientTop, 12382 left: box.left + scrollLeft - clientLeft 12383 }; 12384} 12385function elementPrevAll(el, selector) { 12386 const prevEls = []; 12387 while (el.previousElementSibling) { 12388 const prev = el.previousElementSibling; // eslint-disable-line 12389 if (selector) { 12390 if (prev.matches(selector)) prevEls.push(prev); 12391 } else prevEls.push(prev); 12392 el = prev; 12393 } 12394 return prevEls; 12395} 12396function elementNextAll(el, selector) { 12397 const nextEls = []; 12398 while (el.nextElementSibling) { 12399 const next = el.nextElementSibling; // eslint-disable-line 12400 if (selector) { 12401 if (next.matches(selector)) nextEls.push(next); 12402 } else nextEls.push(next); 12403 el = next; 12404 } 12405 return nextEls; 12406} 12407function elementStyle(el, prop) { 12408 const window = ssr_window_esm_getWindow(); 12409 return window.getComputedStyle(el, null).getPropertyValue(prop); 12410} 12411function utils_elementIndex(el) { 12412 let child = el; 12413 let i; 12414 if (child) { 12415 i = 0; 12416 // eslint-disable-next-line 12417 while ((child = child.previousSibling) !== null) { 12418 if (child.nodeType === 1) i += 1; 12419 } 12420 return i; 12421 } 12422 return undefined; 12423} 12424function utils_elementParents(el, selector) { 12425 const parents = []; // eslint-disable-line 12426 let parent = el.parentElement; // eslint-disable-line 12427 while (parent) { 12428 if (selector) { 12429 if (parent.matches(selector)) parents.push(parent); 12430 } else { 12431 parents.push(parent); 12432 } 12433 parent = parent.parentElement; 12434 } 12435 return parents; 12436} 12437function utils_elementTransitionEnd(el, callback) { 12438 function fireCallBack(e) { 12439 if (e.target !== el) return; 12440 callback.call(el, e); 12441 el.removeEventListener('transitionend', fireCallBack); 12442 } 12443 if (callback) { 12444 el.addEventListener('transitionend', fireCallBack); 12445 } 12446} 12447function elementOuterSize(el, size, includeMargins) { 12448 const window = ssr_window_esm_getWindow(); 12449 if (includeMargins) { 12450 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')); 12451 } 12452 return el.offsetWidth; 12453} 12454function utils_makeElementsArray(el) { 12455 return (Array.isArray(el) ? el : [el]).filter(e => !!e); 12456} 12457function utils_getRotateFix(swiper) { 12458 return v => { 12459 if (Math.abs(v) > 0 && swiper.browser && swiper.browser.need3dFix && Math.abs(v) % 90 === 0) { 12460 return v + 0.001; 12461 } 12462 return v; 12463 }; 12464} 12465function utils_setInnerHTML(el, html) { 12466 if (html === void 0) { 12467 html = ''; 12468 } 12469 if (typeof trustedTypes !== 'undefined') { 12470 el.innerHTML = trustedTypes.createPolicy('html', { 12471 createHTML: s => s 12472 }).createHTML(html); 12473 } else { 12474 el.innerHTML = html; 12475 } 12476} 12477 12478 12479 12480;// ./node_modules/swiper/shared/swiper-core.mjs 12481 12482 12483 12484let support; 12485function calcSupport() { 12486 const window = ssr_window_esm_getWindow(); 12487 const document = ssr_window_esm_getDocument(); 12488 return { 12489 smoothScroll: document.documentElement && document.documentElement.style && 'scrollBehavior' in document.documentElement.style, 12490 touch: !!('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch) 12491 }; 12492}
vendor: 6,684 bytes, lines 12493-12712
12493function getSupport() { 12494 if (!support) { 12495 support = calcSupport(); 12496 } 12497 return support; 12498} 12499 12500let deviceCached; 12501function calcDevice(_temp) { 12502 let { 12503 userAgent 12504 } = _temp === void 0 ? {} : _temp; 12505 const support = getSupport(); 12506 const window = ssr_window_esm_getWindow(); 12507 const platform = window.navigator.platform; 12508 const ua = userAgent || window.navigator.userAgent; 12509 const device = { 12510 ios: false, 12511 android: false 12512 }; 12513 const screenWidth = window.screen.width; 12514 const screenHeight = window.screen.height; 12515 const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line 12516 let ipad = ua.match(/(iPad).*OS\s([\d_]+)/); 12517 const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/); 12518 const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/); 12519 const windows = platform === 'Win32'; 12520 let macos = platform === 'MacIntel'; 12521 12522 // iPadOs 13 fix 12523 const iPadScreens = ['1024x1366', '1366x1024', '834x1194', '1194x834', '834x1112', '1112x834', '768x1024', '1024x768', '820x1180', '1180x820', '810x1080', '1080x810']; 12524 if (!ipad && macos && support.touch && iPadScreens.indexOf(`${screenWidth}x${screenHeight}`) >= 0) { 12525 ipad = ua.match(/(Version)\/([\d.]+)/); 12526 if (!ipad) ipad = [0, 1, '13_0_0']; 12527 macos = false; 12528 } 12529 12530 // Android 12531 if (android && !windows) { 12532 device.os = 'android'; 12533 device.android = true; 12534 } 12535 if (ipad || iphone || ipod) { 12536 device.os = 'ios'; 12537 device.ios = true; 12538 } 12539 12540 // Export object 12541 return device; 12542} 12543function getDevice(overrides) { 12544 if (overrides === void 0) { 12545 overrides = {}; 12546 } 12547 if (!deviceCached) { 12548 deviceCached = calcDevice(overrides); 12549 } 12550 return deviceCached; 12551} 12552 12553let browser; 12554function calcBrowser() { 12555 const window = ssr_window_esm_getWindow(); 12556 const device = getDevice(); 12557 let needPerspectiveFix = false; 12558 function isSafari() { 12559 const ua = window.navigator.userAgent.toLowerCase(); 12560 return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0; 12561 } 12562 if (isSafari()) { 12563 const ua = String(window.navigator.userAgent); 12564 if (ua.includes('Version/')) { 12565 const [major, minor] = ua.split('Version/')[1].split(' ')[0].split('.').map(num => Number(num)); 12566 needPerspectiveFix = major < 16 || major === 16 && minor < 2; 12567 } 12568 } 12569 const isWebView = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent); 12570 const isSafariBrowser = isSafari(); 12571 const need3dFix = isSafariBrowser || isWebView && device.ios; 12572 return { 12573 isSafari: needPerspectiveFix || isSafariBrowser, 12574 needPerspectiveFix, 12575 need3dFix, 12576 isWebView 12577 }; 12578} 12579function getBrowser() { 12580 if (!browser) { 12581 browser = calcBrowser(); 12582 } 12583 return browser; 12584} 12585 12586function Resize(_ref) { 12587 let { 12588 swiper, 12589 on, 12590 emit 12591 } = _ref; 12592 const window = ssr_window_esm_getWindow(); 12593 let observer = null; 12594 let animationFrame = null; 12595 const resizeHandler = () => { 12596 if (!swiper || swiper.destroyed || !swiper.initialized) return; 12597 emit('beforeResize'); 12598 emit('resize'); 12599 }; 12600 const createObserver = () => { 12601 if (!swiper || swiper.destroyed || !swiper.initialized) return; 12602 observer = new ResizeObserver(entries => { 12603 animationFrame = window.requestAnimationFrame(() => { 12604 const { 12605 width, 12606 height 12607 } = swiper; 12608 let newWidth = width; 12609 let newHeight = height; 12610 entries.forEach(_ref2 => { 12611 let { 12612 contentBoxSize, 12613 contentRect, 12614 target 12615 } = _ref2; 12616 if (target && target !== swiper.el) return; 12617 newWidth = contentRect ? contentRect.width : (contentBoxSize[0] || contentBoxSize).inlineSize; 12618 newHeight = contentRect ? contentRect.height : (contentBoxSize[0] || contentBoxSize).blockSize; 12619 }); 12620 if (newWidth !== width || newHeight !== height) { 12621 resizeHandler(); 12622 } 12623 }); 12624 }); 12625 observer.observe(swiper.el); 12626 }; 12627 const removeObserver = () => { 12628 if (animationFrame) { 12629 window.cancelAnimationFrame(animationFrame); 12630 } 12631 if (observer && observer.unobserve && swiper.el) { 12632 observer.unobserve(swiper.el); 12633 observer = null; 12634 } 12635 }; 12636 const orientationChangeHandler = () => { 12637 if (!swiper || swiper.destroyed || !swiper.initialized) return; 12638 emit('orientationchange'); 12639 }; 12640 on('init', () => { 12641 if (swiper.params.resizeObserver && typeof window.ResizeObserver !== 'undefined') { 12642 createObserver(); 12643 return; 12644 } 12645 window.addEventListener('resize', resizeHandler); 12646 window.addEventListener('orientationchange', orientationChangeHandler); 12647 }); 12648 on('destroy', () => { 12649 removeObserver(); 12650 window.removeEventListener('resize', resizeHandler); 12651 window.removeEventListener('orientationchange', orientationChangeHandler); 12652 }); 12653} 12654 12655function Observer(_ref) { 12656 let { 12657 swiper, 12658 extendParams, 12659 on, 12660 emit 12661 } = _ref; 12662 const observers = []; 12663 const window = ssr_window_esm_getWindow(); 12664 const attach = function (target, options) { 12665 if (options === void 0) { 12666 options = {}; 12667 } 12668 const ObserverFunc = window.MutationObserver || window.WebkitMutationObserver; 12669 const observer = new ObserverFunc(mutations => { 12670 // The observerUpdate event should only be triggered 12671 // once despite the number of mutations. Additional 12672 // triggers are redundant and are very costly 12673 if (swiper.__preventObserver__) return; 12674 if (mutations.length === 1) { 12675 emit('observerUpdate', mutations[0]); 12676 return; 12677 } 12678 const observerUpdate = function observerUpdate() { 12679 emit('observerUpdate', mutations[0]); 12680 }; 12681 if (window.requestAnimationFrame) { 12682 window.requestAnimationFrame(observerUpdate); 12683 } else { 12684 window.setTimeout(observerUpdate, 0); 12685 } 12686 }); 12687 observer.observe(target, { 12688 attributes: typeof options.attributes === 'undefined' ? true : options.attributes, 12689 childList: swiper.isElement || (typeof options.childList === 'undefined' ? true : options).childList, 12690 characterData: typeof options.characterData === 'undefined' ? true : options.characterData 12691 }); 12692 observers.push(observer); 12693 }; 12694 const init = () => { 12695 if (!swiper.params.observer) return; 12696 if (swiper.params.observeParents) { 12697 const containerParents = utils_elementParents(swiper.hostEl); 12698 for (let i = 0; i < containerParents.length; i += 1) { 12699 attach(containerParents[i]); 12700 } 12701 } 12702 // Observe container 12703 attach(swiper.hostEl, { 12704 childList: swiper.params.observeSlideChildren 12705 }); 12706 12707 // Observe wrapper 12708 attach(swiper.wrapperEl, { 12709 attributes: false 12710 }); 12711 }; 12712 const destroy = () => {
vendor: 5,654 bytes, lines 12713-12884
12713 observers.forEach(observer => { 12714 observer.disconnect(); 12715 }); 12716 observers.splice(0, observers.length); 12717 }; 12718 extendParams({ 12719 observer: false, 12720 observeParents: false, 12721 observeSlideChildren: false 12722 }); 12723 on('init', init); 12724 on('destroy', destroy); 12725} 12726 12727/* eslint-disable no-underscore-dangle */ 12728 12729var eventsEmitter = { 12730 on(events, handler, priority) { 12731 const self = this; 12732 if (!self.eventsListeners || self.destroyed) return self; 12733 if (typeof handler !== 'function') return self; 12734 const method = priority ? 'unshift' : 'push'; 12735 events.split(' ').forEach(event => { 12736 if (!self.eventsListeners[event]) self.eventsListeners[event] = []; 12737 self.eventsListeners[event][method](handler); 12738 }); 12739 return self; 12740 }, 12741 once(events, handler, priority) { 12742 const self = this; 12743 if (!self.eventsListeners || self.destroyed) return self; 12744 if (typeof handler !== 'function') return self; 12745 function onceHandler() { 12746 self.off(events, onceHandler); 12747 if (onceHandler.__emitterProxy) { 12748 delete onceHandler.__emitterProxy; 12749 } 12750 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 12751 args[_key] = arguments[_key]; 12752 } 12753 handler.apply(self, args); 12754 } 12755 onceHandler.__emitterProxy = handler; 12756 return self.on(events, onceHandler, priority); 12757 }, 12758 onAny(handler, priority) { 12759 const self = this; 12760 if (!self.eventsListeners || self.destroyed) return self; 12761 if (typeof handler !== 'function') return self; 12762 const method = priority ? 'unshift' : 'push'; 12763 if (self.eventsAnyListeners.indexOf(handler) < 0) { 12764 self.eventsAnyListeners[method](handler); 12765 } 12766 return self; 12767 }, 12768 offAny(handler) { 12769 const self = this; 12770 if (!self.eventsListeners || self.destroyed) return self; 12771 if (!self.eventsAnyListeners) return self; 12772 const index = self.eventsAnyListeners.indexOf(handler); 12773 if (index >= 0) { 12774 self.eventsAnyListeners.splice(index, 1); 12775 } 12776 return self; 12777 }, 12778 off(events, handler) { 12779 const self = this; 12780 if (!self.eventsListeners || self.destroyed) return self; 12781 if (!self.eventsListeners) return self; 12782 events.split(' ').forEach(event => { 12783 if (typeof handler === 'undefined') { 12784 self.eventsListeners[event] = []; 12785 } else if (self.eventsListeners[event]) { 12786 self.eventsListeners[event].forEach((eventHandler, index) => { 12787 if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler.__emitterProxy === handler) { 12788 self.eventsListeners[event].splice(index, 1); 12789 } 12790 }); 12791 } 12792 }); 12793 return self; 12794 }, 12795 emit() { 12796 const self = this; 12797 if (!self.eventsListeners || self.destroyed) return self; 12798 if (!self.eventsListeners) return self; 12799 let events; 12800 let data; 12801 let context; 12802 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 12803 args[_key2] = arguments[_key2]; 12804 } 12805 if (typeof args[0] === 'string' || Array.isArray(args[0])) { 12806 events = args[0]; 12807 data = args.slice(1, args.length); 12808 context = self; 12809 } else { 12810 events = args[0].events; 12811 data = args[0].data; 12812 context = args[0].context || self; 12813 } 12814 data.unshift(context); 12815 const eventsArray = Array.isArray(events) ? events : events.split(' '); 12816 eventsArray.forEach(event => { 12817 if (self.eventsAnyListeners && self.eventsAnyListeners.length) { 12818 self.eventsAnyListeners.forEach(eventHandler => { 12819 eventHandler.apply(context, [event, ...data]); 12820 }); 12821 } 12822 if (self.eventsListeners && self.eventsListeners[event]) { 12823 self.eventsListeners[event].forEach(eventHandler => { 12824 eventHandler.apply(context, data); 12825 }); 12826 } 12827 }); 12828 return self; 12829 } 12830}; 12831 12832function updateSize() { 12833 const swiper = this; 12834 let width; 12835 let height; 12836 const el = swiper.el; 12837 if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) { 12838 width = swiper.params.width; 12839 } else { 12840 width = el.clientWidth; 12841 } 12842 if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) { 12843 height = swiper.params.height; 12844 } else { 12845 height = el.clientHeight; 12846 } 12847 if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) { 12848 return; 12849 } 12850 12851 // Subtract paddings 12852 width = width - parseInt(elementStyle(el, 'padding-left') || 0, 10) - parseInt(elementStyle(el, 'padding-right') || 0, 10); 12853 height = height - parseInt(elementStyle(el, 'padding-top') || 0, 10) - parseInt(elementStyle(el, 'padding-bottom') || 0, 10); 12854 if (Number.isNaN(width)) width = 0; 12855 if (Number.isNaN(height)) height = 0; 12856 Object.assign(swiper, { 12857 width, 12858 height, 12859 size: swiper.isHorizontal() ? width : height 12860 }); 12861} 12862 12863function updateSlides() { 12864 const swiper = this; 12865 function getDirectionPropertyValue(node, label) { 12866 return parseFloat(node.getPropertyValue(swiper.getDirectionLabel(label)) || 0); 12867 } 12868 const params = swiper.params; 12869 const { 12870 wrapperEl, 12871 slidesEl, 12872 size: swiperSize, 12873 rtlTranslate: rtl, 12874 wrongRTL 12875 } = swiper; 12876 const isVirtual = swiper.virtual && params.virtual.enabled; 12877 const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length; 12878 const slides = utils_elementChildren(slidesEl, `.${swiper.params.slideClass}, swiper-slide`); 12879 const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length; 12880 let snapGrid = []; 12881 const slidesGrid = []; 12882 const slidesSizesGrid = []; 12883 let offsetBefore = params.slidesOffsetBefore; 12884 if (typeof offsetBefore === 'function') {
vendor: 7,357 bytes, lines 12885-13065
12885 offsetBefore = params.slidesOffsetBefore.call(swiper); 12886 } 12887 let offsetAfter = params.slidesOffsetAfter; 12888 if (typeof offsetAfter === 'function') { 12889 offsetAfter = params.slidesOffsetAfter.call(swiper); 12890 } 12891 const previousSnapGridLength = swiper.snapGrid.length; 12892 const previousSlidesGridLength = swiper.slidesGrid.length; 12893 let spaceBetween = params.spaceBetween; 12894 let slidePosition = -offsetBefore; 12895 let prevSlideSize = 0; 12896 let index = 0; 12897 if (typeof swiperSize === 'undefined') { 12898 return; 12899 } 12900 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) { 12901 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize; 12902 } else if (typeof spaceBetween === 'string') { 12903 spaceBetween = parseFloat(spaceBetween); 12904 } 12905 swiper.virtualSize = -spaceBetween; 12906 12907 // reset margins 12908 slides.forEach(slideEl => { 12909 if (rtl) { 12910 slideEl.style.marginLeft = ''; 12911 } else { 12912 slideEl.style.marginRight = ''; 12913 } 12914 slideEl.style.marginBottom = ''; 12915 slideEl.style.marginTop = ''; 12916 }); 12917 12918 // reset cssMode offsets 12919 if (params.centeredSlides && params.cssMode) { 12920 utils_setCSSProperty(wrapperEl, '--swiper-centered-offset-before', ''); 12921 utils_setCSSProperty(wrapperEl, '--swiper-centered-offset-after', ''); 12922 } 12923 const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid; 12924 if (gridEnabled) { 12925 swiper.grid.initSlides(slides); 12926 } else if (swiper.grid) { 12927 swiper.grid.unsetSlides(); 12928 } 12929 12930 // Calc slides 12931 let slideSize; 12932 const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => { 12933 return typeof params.breakpoints[key].slidesPerView !== 'undefined'; 12934 }).length > 0; 12935 for (let i = 0; i < slidesLength; i += 1) { 12936 slideSize = 0; 12937 let slide; 12938 if (slides[i]) slide = slides[i]; 12939 if (gridEnabled) { 12940 swiper.grid.updateSlide(i, slide, slides); 12941 } 12942 if (slides[i] && elementStyle(slide, 'display') === 'none') continue; // eslint-disable-line 12943 12944 if (params.slidesPerView === 'auto') { 12945 if (shouldResetSlideSize) { 12946 slides[i].style[swiper.getDirectionLabel('width')] = ``; 12947 } 12948 const slideStyles = getComputedStyle(slide); 12949 const currentTransform = slide.style.transform; 12950 const currentWebKitTransform = slide.style.webkitTransform; 12951 if (currentTransform) { 12952 slide.style.transform = 'none'; 12953 } 12954 if (currentWebKitTransform) { 12955 slide.style.webkitTransform = 'none'; 12956 } 12957 if (params.roundLengths) { 12958 slideSize = swiper.isHorizontal() ? elementOuterSize(slide, 'width', true) : elementOuterSize(slide, 'height', true); 12959 } else { 12960 // eslint-disable-next-line 12961 const width = getDirectionPropertyValue(slideStyles, 'width'); 12962 const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left'); 12963 const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right'); 12964 const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left'); 12965 const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right'); 12966 const boxSizing = slideStyles.getPropertyValue('box-sizing'); 12967 if (boxSizing && boxSizing === 'border-box') { 12968 slideSize = width + marginLeft + marginRight; 12969 } else { 12970 const { 12971 clientWidth, 12972 offsetWidth 12973 } = slide; 12974 slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth); 12975 } 12976 } 12977 if (currentTransform) { 12978 slide.style.transform = currentTransform; 12979 } 12980 if (currentWebKitTransform) { 12981 slide.style.webkitTransform = currentWebKitTransform; 12982 } 12983 if (params.roundLengths) slideSize = Math.floor(slideSize); 12984 } else { 12985 slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView; 12986 if (params.roundLengths) slideSize = Math.floor(slideSize); 12987 if (slides[i]) { 12988 slides[i].style[swiper.getDirectionLabel('width')] = `${slideSize}px`; 12989 } 12990 } 12991 if (slides[i]) { 12992 slides[i].swiperSlideSize = slideSize; 12993 } 12994 slidesSizesGrid.push(slideSize); 12995 if (params.centeredSlides) { 12996 slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween; 12997 if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween; 12998 if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween; 12999 if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0; 13000 if (params.roundLengths) slidePosition = Math.floor(slidePosition); 13001 if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition); 13002 slidesGrid.push(slidePosition); 13003 } else { 13004 if (params.roundLengths) slidePosition = Math.floor(slidePosition); 13005 if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition); 13006 slidesGrid.push(slidePosition); 13007 slidePosition = slidePosition + slideSize + spaceBetween; 13008 } 13009 swiper.virtualSize += slideSize + spaceBetween; 13010 prevSlideSize = slideSize; 13011 index += 1; 13012 } 13013 swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter; 13014 if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) { 13015 wrapperEl.style.width = `${swiper.virtualSize + spaceBetween}px`; 13016 } 13017 if (params.setWrapperSize) { 13018 wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`; 13019 } 13020 if (gridEnabled) { 13021 swiper.grid.updateWrapperSize(slideSize, snapGrid); 13022 } 13023 13024 // Remove last grid elements depending on width 13025 if (!params.centeredSlides) { 13026 const newSlidesGrid = []; 13027 for (let i = 0; i < snapGrid.length; i += 1) { 13028 let slidesGridItem = snapGrid[i]; 13029 if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem); 13030 if (snapGrid[i] <= swiper.virtualSize - swiperSize) { 13031 newSlidesGrid.push(slidesGridItem); 13032 } 13033 } 13034 snapGrid = newSlidesGrid; 13035 if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) { 13036 snapGrid.push(swiper.virtualSize - swiperSize); 13037 } 13038 } 13039 if (isVirtual && params.loop) { 13040 const size = slidesSizesGrid[0] + spaceBetween; 13041 if (params.slidesPerGroup > 1) { 13042 const groups = Math.ceil((swiper.virtual.slidesBefore + swiper.virtual.slidesAfter) / params.slidesPerGroup); 13043 const groupSize = size * params.slidesPerGroup; 13044 for (let i = 0; i < groups; i += 1) { 13045 snapGrid.push(snapGrid[snapGrid.length - 1] + groupSize); 13046 } 13047 } 13048 for (let i = 0; i < swiper.virtual.slidesBefore + swiper.virtual.slidesAfter; i += 1) { 13049 if (params.slidesPerGroup === 1) { 13050 snapGrid.push(snapGrid[snapGrid.length - 1] + size); 13051 } 13052 slidesGrid.push(slidesGrid[slidesGrid.length - 1] + size); 13053 swiper.virtualSize += size; 13054 } 13055 } 13056 if (snapGrid.length === 0) snapGrid = [0]; 13057 if (spaceBetween !== 0) { 13058 const key = swiper.isHorizontal() && rtl ? 'marginLeft' : swiper.getDirectionLabel('marginRight'); 13059 slides.filter((_, slideIndex) => { 13060 if (!params.cssMode || params.loop) return true; 13061 if (slideIndex === slides.length - 1) { 13062 return false; 13063 } 13064 return true; 13065 }
vendor: 3,541 bytes, lines 13065-13157
13065).forEach(slideEl => { 13066 slideEl.style[key] = `${spaceBetween}px`; 13067 }); 13068 } 13069 if (params.centeredSlides && params.centeredSlidesBounds) { 13070 let allSlidesSize = 0; 13071 slidesSizesGrid.forEach(slideSizeValue => { 13072 allSlidesSize += slideSizeValue + (spaceBetween || 0); 13073 }); 13074 allSlidesSize -= spaceBetween; 13075 const maxSnap = allSlidesSize > swiperSize ? allSlidesSize - swiperSize : 0; 13076 snapGrid = snapGrid.map(snap => { 13077 if (snap <= 0) return -offsetBefore; 13078 if (snap > maxSnap) return maxSnap + offsetAfter; 13079 return snap; 13080 }); 13081 } 13082 if (params.centerInsufficientSlides) { 13083 let allSlidesSize = 0; 13084 slidesSizesGrid.forEach(slideSizeValue => { 13085 allSlidesSize += slideSizeValue + (spaceBetween || 0); 13086 }); 13087 allSlidesSize -= spaceBetween; 13088 const offsetSize = (params.slidesOffsetBefore || 0) + (params.slidesOffsetAfter || 0); 13089 if (allSlidesSize + offsetSize < swiperSize) { 13090 const allSlidesOffset = (swiperSize - allSlidesSize - offsetSize) / 2; 13091 snapGrid.forEach((snap, snapIndex) => { 13092 snapGrid[snapIndex] = snap - allSlidesOffset; 13093 }); 13094 slidesGrid.forEach((snap, snapIndex) => { 13095 slidesGrid[snapIndex] = snap + allSlidesOffset; 13096 }); 13097 } 13098 } 13099 Object.assign(swiper, { 13100 slides, 13101 snapGrid, 13102 slidesGrid, 13103 slidesSizesGrid 13104 }); 13105 if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) { 13106 utils_setCSSProperty(wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`); 13107 utils_setCSSProperty(wrapperEl, '--swiper-centered-offset-after', `${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`); 13108 const addToSnapGrid = -swiper.snapGrid[0]; 13109 const addToSlidesGrid = -swiper.slidesGrid[0]; 13110 swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid); 13111 swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid); 13112 } 13113 if (slidesLength !== previousSlidesLength) { 13114 swiper.emit('slidesLengthChange'); 13115 } 13116 if (snapGrid.length !== previousSnapGridLength) { 13117 if (swiper.params.watchOverflow) swiper.checkOverflow(); 13118 swiper.emit('snapGridLengthChange'); 13119 } 13120 if (slidesGrid.length !== previousSlidesGridLength) { 13121 swiper.emit('slidesGridLengthChange'); 13122 } 13123 if (params.watchSlidesProgress) { 13124 swiper.updateSlidesOffset(); 13125 } 13126 swiper.emit('slidesUpdated'); 13127 if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) { 13128 const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`; 13129 const hasClassBackfaceClassAdded = swiper.el.classList.contains(backFaceHiddenClass); 13130 if (slidesLength <= params.maxBackfaceHiddenSlides) { 13131 if (!hasClassBackfaceClassAdded) swiper.el.classList.add(backFaceHiddenClass); 13132 } else if (hasClassBackfaceClassAdded) { 13133 swiper.el.classList.remove(backFaceHiddenClass); 13134 } 13135 } 13136} 13137 13138function updateAutoHeight(speed) { 13139 const swiper = this; 13140 const activeSlides = []; 13141 const isVirtual = swiper.virtual && swiper.params.virtual.enabled; 13142 let newHeight = 0; 13143 let i; 13144 if (typeof speed === 'number') { 13145 swiper.setTransition(speed); 13146 } else if (speed === true) { 13147 swiper.setTransition(swiper.params.speed); 13148 } 13149 const getSlideByIndex = index => { 13150 if (isVirtual) { 13151 return swiper.slides[swiper.getSlideIndexByData(index)]; 13152 } 13153 return swiper.slides[index]; 13154 }; 13155 // Find slides currently in view 13156 if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) { 13157 if (swiper.params.centeredSlides) {
vendor: 3,398 bytes, lines 13158-13239
13158 (swiper.visibleSlides || []).forEach(slide => { 13159 activeSlides.push(slide); 13160 }); 13161 } else { 13162 for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) { 13163 const index = swiper.activeIndex + i; 13164 if (index > swiper.slides.length && !isVirtual) break; 13165 activeSlides.push(getSlideByIndex(index)); 13166 } 13167 } 13168 } else { 13169 activeSlides.push(getSlideByIndex(swiper.activeIndex)); 13170 } 13171 13172 // Find new height from highest slide in view 13173 for (i = 0; i < activeSlides.length; i += 1) { 13174 if (typeof activeSlides[i] !== 'undefined') { 13175 const height = activeSlides[i].offsetHeight; 13176 newHeight = height > newHeight ? height : newHeight; 13177 } 13178 } 13179 13180 // Update Height 13181 if (newHeight || newHeight === 0) swiper.wrapperEl.style.height = `${newHeight}px`; 13182} 13183 13184function updateSlidesOffset() { 13185 const swiper = this; 13186 const slides = swiper.slides; 13187 // eslint-disable-next-line 13188 const minusOffset = swiper.isElement ? swiper.isHorizontal() ? swiper.wrapperEl.offsetLeft : swiper.wrapperEl.offsetTop : 0; 13189 for (let i = 0; i < slides.length; i += 1) { 13190 slides[i].swiperSlideOffset = (swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop) - minusOffset - swiper.cssOverflowAdjustment(); 13191 } 13192} 13193 13194const toggleSlideClasses$1 = (slideEl, condition, className) => { 13195 if (condition && !slideEl.classList.contains(className)) { 13196 slideEl.classList.add(className); 13197 } else if (!condition && slideEl.classList.contains(className)) { 13198 slideEl.classList.remove(className); 13199 } 13200}; 13201function updateSlidesProgress(translate) { 13202 if (translate === void 0) { 13203 translate = this && this.translate || 0; 13204 } 13205 const swiper = this; 13206 const params = swiper.params; 13207 const { 13208 slides, 13209 rtlTranslate: rtl, 13210 snapGrid 13211 } = swiper; 13212 if (slides.length === 0) return; 13213 if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset(); 13214 let offsetCenter = -translate; 13215 if (rtl) offsetCenter = translate; 13216 swiper.visibleSlidesIndexes = []; 13217 swiper.visibleSlides = []; 13218 let spaceBetween = params.spaceBetween; 13219 if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) { 13220 spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiper.size; 13221 } else if (typeof spaceBetween === 'string') { 13222 spaceBetween = parseFloat(spaceBetween); 13223 } 13224 for (let i = 0; i < slides.length; i += 1) { 13225 const slide = slides[i]; 13226 let slideOffset = slide.swiperSlideOffset; 13227 if (params.cssMode && params.centeredSlides) { 13228 slideOffset -= slides[0].swiperSlideOffset; 13229 } 13230 const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween); 13231 const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (slide.swiperSlideSize + spaceBetween); 13232 const slideBefore = -(offsetCenter - slideOffset); 13233 const slideAfter = slideBefore + swiper.slidesSizesGrid[i]; 13234 const isFullyVisible = slideBefore >= 0 && slideBefore <= swiper.size - swiper.slidesSizesGrid[i]; 13235 const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper.size || slideBefore <= 0 && slideAfter >= swiper.size; 13236 if (isVisible) { 13237 swiper.visibleSlides.push(slide); 13238 swiper.visibleSlidesIndexes.push(i); 13239 }
vendor: 11,267 bytes, lines 13240-13552
13240 toggleSlideClasses$1(slide, isVisible, params.slideVisibleClass); 13241 toggleSlideClasses$1(slide, isFullyVisible, params.slideFullyVisibleClass); 13242 slide.progress = rtl ? -slideProgress : slideProgress; 13243 slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress; 13244 } 13245} 13246 13247function updateProgress(translate) { 13248 const swiper = this; 13249 if (typeof translate === 'undefined') { 13250 const multiplier = swiper.rtlTranslate ? -1 : 1; 13251 // eslint-disable-next-line 13252 translate = swiper && swiper.translate && swiper.translate * multiplier || 0; 13253 } 13254 const params = swiper.params; 13255 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); 13256 let { 13257 progress, 13258 isBeginning, 13259 isEnd, 13260 progressLoop 13261 } = swiper; 13262 const wasBeginning = isBeginning; 13263 const wasEnd = isEnd; 13264 if (translatesDiff === 0) { 13265 progress = 0; 13266 isBeginning = true; 13267 isEnd = true; 13268 } else { 13269 progress = (translate - swiper.minTranslate()) / translatesDiff; 13270 const isBeginningRounded = Math.abs(translate - swiper.minTranslate()) < 1; 13271 const isEndRounded = Math.abs(translate - swiper.maxTranslate()) < 1; 13272 isBeginning = isBeginningRounded || progress <= 0; 13273 isEnd = isEndRounded || progress >= 1; 13274 if (isBeginningRounded) progress = 0; 13275 if (isEndRounded) progress = 1; 13276 } 13277 if (params.loop) { 13278 const firstSlideIndex = swiper.getSlideIndexByData(0); 13279 const lastSlideIndex = swiper.getSlideIndexByData(swiper.slides.length - 1); 13280 const firstSlideTranslate = swiper.slidesGrid[firstSlideIndex]; 13281 const lastSlideTranslate = swiper.slidesGrid[lastSlideIndex]; 13282 const translateMax = swiper.slidesGrid[swiper.slidesGrid.length - 1]; 13283 const translateAbs = Math.abs(translate); 13284 if (translateAbs >= firstSlideTranslate) { 13285 progressLoop = (translateAbs - firstSlideTranslate) / translateMax; 13286 } else { 13287 progressLoop = (translateAbs + translateMax - lastSlideTranslate) / translateMax; 13288 } 13289 if (progressLoop > 1) progressLoop -= 1; 13290 } 13291 Object.assign(swiper, { 13292 progress, 13293 progressLoop, 13294 isBeginning, 13295 isEnd 13296 }); 13297 if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate); 13298 if (isBeginning && !wasBeginning) { 13299 swiper.emit('reachBeginning toEdge'); 13300 } 13301 if (isEnd && !wasEnd) { 13302 swiper.emit('reachEnd toEdge'); 13303 } 13304 if (wasBeginning && !isBeginning || wasEnd && !isEnd) { 13305 swiper.emit('fromEdge'); 13306 } 13307 swiper.emit('progress', progress); 13308} 13309 13310const toggleSlideClasses = (slideEl, condition, className) => { 13311 if (condition && !slideEl.classList.contains(className)) { 13312 slideEl.classList.add(className); 13313 } else if (!condition && slideEl.classList.contains(className)) { 13314 slideEl.classList.remove(className); 13315 } 13316}; 13317function updateSlidesClasses() { 13318 const swiper = this; 13319 const { 13320 slides, 13321 params, 13322 slidesEl, 13323 activeIndex 13324 } = swiper; 13325 const isVirtual = swiper.virtual && params.virtual.enabled; 13326 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1; 13327 const getFilteredSlide = selector => { 13328 return utils_elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0]; 13329 }; 13330 let activeSlide; 13331 let prevSlide; 13332 let nextSlide; 13333 if (isVirtual) { 13334 if (params.loop) { 13335 let slideIndex = activeIndex - swiper.virtual.slidesBefore; 13336 if (slideIndex < 0) slideIndex = swiper.virtual.slides.length + slideIndex; 13337 if (slideIndex >= swiper.virtual.slides.length) slideIndex -= swiper.virtual.slides.length; 13338 activeSlide = getFilteredSlide(`[data-swiper-slide-index="${slideIndex}"]`); 13339 } else { 13340 activeSlide = getFilteredSlide(`[data-swiper-slide-index="${activeIndex}"]`); 13341 } 13342 } else { 13343 if (gridEnabled) { 13344 activeSlide = slides.find(slideEl => slideEl.column === activeIndex); 13345 nextSlide = slides.find(slideEl => slideEl.column === activeIndex + 1); 13346 prevSlide = slides.find(slideEl => slideEl.column === activeIndex - 1); 13347 } else { 13348 activeSlide = slides[activeIndex]; 13349 } 13350 } 13351 if (activeSlide) { 13352 if (!gridEnabled) { 13353 // Next Slide 13354 nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0]; 13355 if (params.loop && !nextSlide) { 13356 nextSlide = slides[0]; 13357 } 13358 13359 // Prev Slide 13360 prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0]; 13361 if (params.loop && !prevSlide === 0) { 13362 prevSlide = slides[slides.length - 1]; 13363 } 13364 } 13365 } 13366 slides.forEach(slideEl => { 13367 toggleSlideClasses(slideEl, slideEl === activeSlide, params.slideActiveClass); 13368 toggleSlideClasses(slideEl, slideEl === nextSlide, params.slideNextClass); 13369 toggleSlideClasses(slideEl, slideEl === prevSlide, params.slidePrevClass); 13370 }); 13371 swiper.emitSlidesClasses(); 13372} 13373 13374const processLazyPreloader = (swiper, imageEl) => { 13375 if (!swiper || swiper.destroyed || !swiper.params) return; 13376 const slideSelector = () => swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`; 13377 const slideEl = imageEl.closest(slideSelector()); 13378 if (slideEl) { 13379 let lazyEl = slideEl.querySelector(`.${swiper.params.lazyPreloaderClass}`); 13380 if (!lazyEl && swiper.isElement) { 13381 if (slideEl.shadowRoot) { 13382 lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`); 13383 } else { 13384 // init later 13385 requestAnimationFrame(() => { 13386 if (slideEl.shadowRoot) { 13387 lazyEl = slideEl.shadowRoot.querySelector(`.${swiper.params.lazyPreloaderClass}`); 13388 if (lazyEl) lazyEl.remove(); 13389 } 13390 }); 13391 } 13392 } 13393 if (lazyEl) lazyEl.remove(); 13394 } 13395}; 13396const unlazy = (swiper, index) => { 13397 if (!swiper.slides[index]) return; 13398 const imageEl = swiper.slides[index].querySelector('[loading="lazy"]'); 13399 if (imageEl) imageEl.removeAttribute('loading'); 13400}; 13401const preload = swiper => { 13402 if (!swiper || swiper.destroyed || !swiper.params) return; 13403 let amount = swiper.params.lazyPreloadPrevNext; 13404 const len = swiper.slides.length; 13405 if (!len || !amount || amount < 0) return; 13406 amount = Math.min(amount, len); 13407 const slidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(swiper.params.slidesPerView); 13408 const activeIndex = swiper.activeIndex; 13409 if (swiper.params.grid && swiper.params.grid.rows > 1) { 13410 const activeColumn = activeIndex; 13411 const preloadColumns = [activeColumn - amount]; 13412 preloadColumns.push(...Array.from({ 13413 length: amount 13414 }).map((_, i) => { 13415 return activeColumn + slidesPerView + i; 13416 })); 13417 swiper.slides.forEach((slideEl, i) => { 13418 if (preloadColumns.includes(slideEl.column)) unlazy(swiper, i); 13419 }); 13420 return; 13421 } 13422 const slideIndexLastInView = activeIndex + slidesPerView - 1; 13423 if (swiper.params.rewind || swiper.params.loop) { 13424 for (let i = activeIndex - amount; i <= slideIndexLastInView + amount; i += 1) { 13425 const realIndex = (i % len + len) % len; 13426 if (realIndex < activeIndex || realIndex > slideIndexLastInView) unlazy(swiper, realIndex); 13427 } 13428 } else { 13429 for (let i = Math.max(activeIndex - amount, 0); i <= Math.min(slideIndexLastInView + amount, len - 1); i += 1) { 13430 if (i !== activeIndex && (i > slideIndexLastInView || i < activeIndex)) { 13431 unlazy(swiper, i); 13432 } 13433 } 13434 } 13435}; 13436 13437function getActiveIndexByTranslate(swiper) { 13438 const { 13439 slidesGrid, 13440 params 13441 } = swiper; 13442 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate; 13443 let activeIndex; 13444 for (let i = 0; i < slidesGrid.length; i += 1) { 13445 if (typeof slidesGrid[i + 1] !== 'undefined') { 13446 if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) / 2) { 13447 activeIndex = i; 13448 } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) { 13449 activeIndex = i + 1; 13450 } 13451 } else if (translate >= slidesGrid[i]) { 13452 activeIndex = i; 13453 } 13454 } 13455 // Normalize slideIndex 13456 if (params.normalizeSlideIndex) { 13457 if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0; 13458 } 13459 return activeIndex; 13460} 13461function updateActiveIndex(newActiveIndex) { 13462 const swiper = this; 13463 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate; 13464 const { 13465 snapGrid, 13466 params, 13467 activeIndex: previousIndex, 13468 realIndex: previousRealIndex, 13469 snapIndex: previousSnapIndex 13470 } = swiper; 13471 let activeIndex = newActiveIndex; 13472 let snapIndex; 13473 const getVirtualRealIndex = aIndex => { 13474 let realIndex = aIndex - swiper.virtual.slidesBefore; 13475 if (realIndex < 0) { 13476 realIndex = swiper.virtual.slides.length + realIndex; 13477 } 13478 if (realIndex >= swiper.virtual.slides.length) { 13479 realIndex -= swiper.virtual.slides.length; 13480 } 13481 return realIndex; 13482 }; 13483 if (typeof activeIndex === 'undefined') { 13484 activeIndex = getActiveIndexByTranslate(swiper); 13485 } 13486 if (snapGrid.indexOf(translate) >= 0) { 13487 snapIndex = snapGrid.indexOf(translate); 13488 } else { 13489 const skip = Math.min(params.slidesPerGroupSkip, activeIndex); 13490 snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup); 13491 } 13492 if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1; 13493 if (activeIndex === previousIndex && !swiper.params.loop) { 13494 if (snapIndex !== previousSnapIndex) { 13495 swiper.snapIndex = snapIndex; 13496 swiper.emit('snapIndexChange'); 13497 } 13498 return; 13499 } 13500 if (activeIndex === previousIndex && swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) { 13501 swiper.realIndex = getVirtualRealIndex(activeIndex); 13502 return; 13503 } 13504 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1; 13505 13506 // Get real index 13507 let realIndex; 13508 if (swiper.virtual && params.virtual.enabled && params.loop) { 13509 realIndex = getVirtualRealIndex(activeIndex); 13510 } else if (gridEnabled) { 13511 const firstSlideInColumn = swiper.slides.find(slideEl => slideEl.column === activeIndex); 13512 let activeSlideIndex = parseInt(firstSlideInColumn.getAttribute('data-swiper-slide-index'), 10); 13513 if (Number.isNaN(activeSlideIndex)) { 13514 activeSlideIndex = Math.max(swiper.slides.indexOf(firstSlideInColumn), 0); 13515 } 13516 realIndex = Math.floor(activeSlideIndex / params.grid.rows); 13517 } else if (swiper.slides[activeIndex]) { 13518 const slideIndex = swiper.slides[activeIndex].getAttribute('data-swiper-slide-index'); 13519 if (slideIndex) { 13520 realIndex = parseInt(slideIndex, 10); 13521 } else { 13522 realIndex = activeIndex; 13523 } 13524 } else { 13525 realIndex = activeIndex; 13526 } 13527 Object.assign(swiper, { 13528 previousSnapIndex, 13529 snapIndex, 13530 previousRealIndex, 13531 realIndex, 13532 previousIndex, 13533 activeIndex 13534 }); 13535 if (swiper.initialized) { 13536 preload(swiper); 13537 } 13538 swiper.emit('activeIndexChange'); 13539 swiper.emit('snapIndexChange'); 13540 if (swiper.initialized || swiper.params.runCallbacksOnInit) { 13541 if (previousRealIndex !== realIndex) { 13542 swiper.emit('realIndexChange'); 13543 } 13544 swiper.emit('slideChange'); 13545 } 13546} 13547 13548function updateClickedSlide(el, path) { 13549 const swiper = this; 13550 const params = swiper.params; 13551 let slide = el.closest(`.${params.slideClass}, swiper-slide`); 13552 if (!slide && swiper.isElement && path && path.length > 1 && path.includes(el)) {
vendor: 14,247 bytes, lines 13553-14038
13553 [...path.slice(path.indexOf(el) + 1, path.length)].forEach(pathEl => { 13554 if (!slide && pathEl.matches && pathEl.matches(`.${params.slideClass}, swiper-slide`)) { 13555 slide = pathEl; 13556 } 13557 }); 13558 } 13559 let slideFound = false; 13560 let slideIndex; 13561 if (slide) { 13562 for (let i = 0; i < swiper.slides.length; i += 1) { 13563 if (swiper.slides[i] === slide) { 13564 slideFound = true; 13565 slideIndex = i; 13566 break; 13567 } 13568 } 13569 } 13570 if (slide && slideFound) { 13571 swiper.clickedSlide = slide; 13572 if (swiper.virtual && swiper.params.virtual.enabled) { 13573 swiper.clickedIndex = parseInt(slide.getAttribute('data-swiper-slide-index'), 10); 13574 } else { 13575 swiper.clickedIndex = slideIndex; 13576 } 13577 } else { 13578 swiper.clickedSlide = undefined; 13579 swiper.clickedIndex = undefined; 13580 return; 13581 } 13582 if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) { 13583 swiper.slideToClickedSlide(); 13584 } 13585} 13586 13587var update = { 13588 updateSize, 13589 updateSlides, 13590 updateAutoHeight, 13591 updateSlidesOffset, 13592 updateSlidesProgress, 13593 updateProgress, 13594 updateSlidesClasses, 13595 updateActiveIndex, 13596 updateClickedSlide 13597}; 13598 13599function getSwiperTranslate(axis) { 13600 if (axis === void 0) { 13601 axis = this.isHorizontal() ? 'x' : 'y'; 13602 } 13603 const swiper = this; 13604 const { 13605 params, 13606 rtlTranslate: rtl, 13607 translate, 13608 wrapperEl 13609 } = swiper; 13610 if (params.virtualTranslate) { 13611 return rtl ? -translate : translate; 13612 } 13613 if (params.cssMode) { 13614 return translate; 13615 } 13616 let currentTranslate = utils_getTranslate(wrapperEl, axis); 13617 currentTranslate += swiper.cssOverflowAdjustment(); 13618 if (rtl) currentTranslate = -currentTranslate; 13619 return currentTranslate || 0; 13620} 13621 13622function setTranslate(translate, byController) { 13623 const swiper = this; 13624 const { 13625 rtlTranslate: rtl, 13626 params, 13627 wrapperEl, 13628 progress 13629 } = swiper; 13630 let x = 0; 13631 let y = 0; 13632 const z = 0; 13633 if (swiper.isHorizontal()) { 13634 x = rtl ? -translate : translate; 13635 } else { 13636 y = translate; 13637 } 13638 if (params.roundLengths) { 13639 x = Math.floor(x); 13640 y = Math.floor(y); 13641 } 13642 swiper.previousTranslate = swiper.translate; 13643 swiper.translate = swiper.isHorizontal() ? x : y; 13644 if (params.cssMode) { 13645 wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y; 13646 } else if (!params.virtualTranslate) { 13647 if (swiper.isHorizontal()) { 13648 x -= swiper.cssOverflowAdjustment(); 13649 } else { 13650 y -= swiper.cssOverflowAdjustment(); 13651 } 13652 wrapperEl.style.transform = `translate3d(${x}px, ${y}px, ${z}px)`; 13653 } 13654 13655 // Check if we need to update progress 13656 let newProgress; 13657 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); 13658 if (translatesDiff === 0) { 13659 newProgress = 0; 13660 } else { 13661 newProgress = (translate - swiper.minTranslate()) / translatesDiff; 13662 } 13663 if (newProgress !== progress) { 13664 swiper.updateProgress(translate); 13665 } 13666 swiper.emit('setTranslate', swiper.translate, byController); 13667} 13668 13669function minTranslate() { 13670 return -this.snapGrid[0]; 13671} 13672 13673function maxTranslate() { 13674 return -this.snapGrid[this.snapGrid.length - 1]; 13675} 13676 13677function translateTo(translate, speed, runCallbacks, translateBounds, internal) { 13678 if (translate === void 0) { 13679 translate = 0; 13680 } 13681 if (speed === void 0) { 13682 speed = this.params.speed; 13683 } 13684 if (runCallbacks === void 0) { 13685 runCallbacks = true; 13686 } 13687 if (translateBounds === void 0) { 13688 translateBounds = true; 13689 } 13690 const swiper = this; 13691 const { 13692 params, 13693 wrapperEl 13694 } = swiper; 13695 if (swiper.animating && params.preventInteractionOnTransition) { 13696 return false; 13697 } 13698 const minTranslate = swiper.minTranslate(); 13699 const maxTranslate = swiper.maxTranslate(); 13700 let newTranslate; 13701 if (translateBounds && translate > minTranslate) newTranslate = minTranslate;else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;else newTranslate = translate; 13702 13703 // Update progress 13704 swiper.updateProgress(newTranslate); 13705 if (params.cssMode) { 13706 const isH = swiper.isHorizontal(); 13707 if (speed === 0) { 13708 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate; 13709 } else { 13710 if (!swiper.support.smoothScroll) { 13711 animateCSSModeScroll({ 13712 swiper, 13713 targetPosition: -newTranslate, 13714 side: isH ? 'left' : 'top' 13715 }); 13716 return true; 13717 } 13718 wrapperEl.scrollTo({ 13719 [isH ? 'left' : 'top']: -newTranslate, 13720 behavior: 'smooth' 13721 }); 13722 } 13723 return true; 13724 } 13725 if (speed === 0) { 13726 swiper.setTransition(0); 13727 swiper.setTranslate(newTranslate); 13728 if (runCallbacks) { 13729 swiper.emit('beforeTransitionStart', speed, internal); 13730 swiper.emit('transitionEnd'); 13731 } 13732 } else { 13733 swiper.setTransition(speed); 13734 swiper.setTranslate(newTranslate); 13735 if (runCallbacks) { 13736 swiper.emit('beforeTransitionStart', speed, internal); 13737 swiper.emit('transitionStart'); 13738 } 13739 if (!swiper.animating) { 13740 swiper.animating = true; 13741 if (!swiper.onTranslateToWrapperTransitionEnd) { 13742 swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) { 13743 if (!swiper || swiper.destroyed) return; 13744 if (e.target !== this) return; 13745 swiper.wrapperEl.removeEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd); 13746 swiper.onTranslateToWrapperTransitionEnd = null; 13747 delete swiper.onTranslateToWrapperTransitionEnd; 13748 swiper.animating = false; 13749 if (runCallbacks) { 13750 swiper.emit('transitionEnd'); 13751 } 13752 }; 13753 } 13754 swiper.wrapperEl.addEventListener('transitionend', swiper.onTranslateToWrapperTransitionEnd); 13755 } 13756 } 13757 return true; 13758} 13759 13760var translate = { 13761 getTranslate: getSwiperTranslate, 13762 setTranslate, 13763 minTranslate, 13764 maxTranslate, 13765 translateTo 13766}; 13767 13768function setTransition(duration, byController) { 13769 const swiper = this; 13770 if (!swiper.params.cssMode) { 13771 swiper.wrapperEl.style.transitionDuration = `${duration}ms`; 13772 swiper.wrapperEl.style.transitionDelay = duration === 0 ? `0ms` : ''; 13773 } 13774 swiper.emit('setTransition', duration, byController); 13775} 13776 13777function transitionEmit(_ref) { 13778 let { 13779 swiper, 13780 runCallbacks, 13781 direction, 13782 step 13783 } = _ref; 13784 const { 13785 activeIndex, 13786 previousIndex 13787 } = swiper; 13788 let dir = direction; 13789 if (!dir) { 13790 if (activeIndex > previousIndex) dir = 'next';else if (activeIndex < previousIndex) dir = 'prev';else dir = 'reset'; 13791 } 13792 swiper.emit(`transition${step}`); 13793 if (runCallbacks && dir === 'reset') { 13794 swiper.emit(`slideResetTransition${step}`); 13795 } else if (runCallbacks && activeIndex !== previousIndex) { 13796 swiper.emit(`slideChangeTransition${step}`); 13797 if (dir === 'next') { 13798 swiper.emit(`slideNextTransition${step}`); 13799 } else { 13800 swiper.emit(`slidePrevTransition${step}`); 13801 } 13802 } 13803} 13804 13805function transitionStart(runCallbacks, direction) { 13806 if (runCallbacks === void 0) { 13807 runCallbacks = true; 13808 } 13809 const swiper = this; 13810 const { 13811 params 13812 } = swiper; 13813 if (params.cssMode) return; 13814 if (params.autoHeight) { 13815 swiper.updateAutoHeight(); 13816 } 13817 transitionEmit({ 13818 swiper, 13819 runCallbacks, 13820 direction, 13821 step: 'Start' 13822 }); 13823} 13824 13825function transitionEnd(runCallbacks, direction) { 13826 if (runCallbacks === void 0) { 13827 runCallbacks = true; 13828 } 13829 const swiper = this; 13830 const { 13831 params 13832 } = swiper; 13833 swiper.animating = false; 13834 if (params.cssMode) return; 13835 swiper.setTransition(0); 13836 transitionEmit({ 13837 swiper, 13838 runCallbacks, 13839 direction, 13840 step: 'End' 13841 }); 13842} 13843 13844var transition = { 13845 setTransition, 13846 transitionStart, 13847 transitionEnd 13848}; 13849 13850function slideTo(index, speed, runCallbacks, internal, initial) { 13851 if (index === void 0) { 13852 index = 0; 13853 } 13854 if (runCallbacks === void 0) { 13855 runCallbacks = true; 13856 } 13857 if (typeof index === 'string') { 13858 index = parseInt(index, 10); 13859 } 13860 const swiper = this; 13861 let slideIndex = index; 13862 if (slideIndex < 0) slideIndex = 0; 13863 const { 13864 params, 13865 snapGrid, 13866 slidesGrid, 13867 previousIndex, 13868 activeIndex, 13869 rtlTranslate: rtl, 13870 wrapperEl, 13871 enabled 13872 } = swiper; 13873 if (!enabled && !internal && !initial || swiper.destroyed || swiper.animating && params.preventInteractionOnTransition) { 13874 return false; 13875 } 13876 if (typeof speed === 'undefined') { 13877 speed = swiper.params.speed; 13878 } 13879 const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex); 13880 let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup); 13881 if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1; 13882 const translate = -snapGrid[snapIndex]; 13883 // Normalize slideIndex 13884 if (params.normalizeSlideIndex) { 13885 for (let i = 0; i < slidesGrid.length; i += 1) { 13886 const normalizedTranslate = -Math.floor(translate * 100); 13887 const normalizedGrid = Math.floor(slidesGrid[i] * 100); 13888 const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100); 13889 if (typeof slidesGrid[i + 1] !== 'undefined') { 13890 if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (normalizedGridNext - normalizedGrid) / 2) { 13891 slideIndex = i; 13892 } else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) { 13893 slideIndex = i + 1; 13894 } 13895 } else if (normalizedTranslate >= normalizedGrid) { 13896 slideIndex = i; 13897 } 13898 } 13899 } 13900 // Directions locks 13901 if (swiper.initialized && slideIndex !== activeIndex) { 13902 if (!swiper.allowSlideNext && (rtl ? translate > swiper.translate && translate > swiper.minTranslate() : translate < swiper.translate && translate < swiper.minTranslate())) { 13903 return false; 13904 } 13905 if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) { 13906 if ((activeIndex || 0) !== slideIndex) { 13907 return false; 13908 } 13909 } 13910 } 13911 if (slideIndex !== (previousIndex || 0) && runCallbacks) { 13912 swiper.emit('beforeSlideChangeStart'); 13913 } 13914 13915 // Update progress 13916 swiper.updateProgress(translate); 13917 let direction; 13918 if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset'; 13919 13920 // initial virtual 13921 const isVirtual = swiper.virtual && swiper.params.virtual.enabled; 13922 const isInitialVirtual = isVirtual && initial; 13923 // Update Index 13924 if (!isInitialVirtual && (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate)) { 13925 swiper.updateActiveIndex(slideIndex); 13926 // Update Height 13927 if (params.autoHeight) { 13928 swiper.updateAutoHeight(); 13929 } 13930 swiper.updateSlidesClasses(); 13931 if (params.effect !== 'slide') { 13932 swiper.setTranslate(translate); 13933 } 13934 if (direction !== 'reset') { 13935 swiper.transitionStart(runCallbacks, direction); 13936 swiper.transitionEnd(runCallbacks, direction); 13937 } 13938 return false; 13939 } 13940 if (params.cssMode) { 13941 const isH = swiper.isHorizontal(); 13942 const t = rtl ? translate : -translate; 13943 if (speed === 0) { 13944 if (isVirtual) { 13945 swiper.wrapperEl.style.scrollSnapType = 'none'; 13946 swiper._immediateVirtual = true; 13947 } 13948 if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) { 13949 swiper._cssModeVirtualInitialSet = true; 13950 requestAnimationFrame(() => { 13951 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t; 13952 }); 13953 } else { 13954 wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t; 13955 } 13956 if (isVirtual) { 13957 requestAnimationFrame(() => { 13958 swiper.wrapperEl.style.scrollSnapType = ''; 13959 swiper._immediateVirtual = false; 13960 }); 13961 } 13962 } else { 13963 if (!swiper.support.smoothScroll) { 13964 animateCSSModeScroll({ 13965 swiper, 13966 targetPosition: t, 13967 side: isH ? 'left' : 'top' 13968 }); 13969 return true; 13970 } 13971 wrapperEl.scrollTo({ 13972 [isH ? 'left' : 'top']: t, 13973 behavior: 'smooth' 13974 }); 13975 } 13976 return true; 13977 } 13978 const browser = getBrowser(); 13979 const isSafari = browser.isSafari; 13980 if (isVirtual && !initial && isSafari && swiper.isElement) { 13981 swiper.virtual.update(false, false, slideIndex); 13982 } 13983 swiper.setTransition(speed); 13984 swiper.setTranslate(translate); 13985 swiper.updateActiveIndex(slideIndex); 13986 swiper.updateSlidesClasses(); 13987 swiper.emit('beforeTransitionStart', speed, internal); 13988 swiper.transitionStart(runCallbacks, direction); 13989 if (speed === 0) { 13990 swiper.transitionEnd(runCallbacks, direction); 13991 } else if (!swiper.animating) { 13992 swiper.animating = true; 13993 if (!swiper.onSlideToWrapperTransitionEnd) { 13994 swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) { 13995 if (!swiper || swiper.destroyed) return; 13996 if (e.target !== this) return; 13997 swiper.wrapperEl.removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd); 13998 swiper.onSlideToWrapperTransitionEnd = null; 13999 delete swiper.onSlideToWrapperTransitionEnd; 14000 swiper.transitionEnd(runCallbacks, direction); 14001 }; 14002 } 14003 swiper.wrapperEl.addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd); 14004 } 14005 return true; 14006} 14007 14008function slideToLoop(index, speed, runCallbacks, internal) { 14009 if (index === void 0) { 14010 index = 0; 14011 } 14012 if (runCallbacks === void 0) { 14013 runCallbacks = true; 14014 } 14015 if (typeof index === 'string') { 14016 const indexAsNumber = parseInt(index, 10); 14017 index = indexAsNumber; 14018 } 14019 const swiper = this; 14020 if (swiper.destroyed) return; 14021 if (typeof speed === 'undefined') { 14022 speed = swiper.params.speed; 14023 } 14024 const gridEnabled = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1; 14025 let newIndex = index; 14026 if (swiper.params.loop) { 14027 if (swiper.virtual && swiper.params.virtual.enabled) { 14028 // eslint-disable-next-line 14029 newIndex = newIndex + swiper.virtual.slidesBefore; 14030 } else { 14031 let targetSlideIndex; 14032 if (gridEnabled) { 14033 const slideIndex = newIndex * swiper.params.grid.rows; 14034 targetSlideIndex = swiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex).column; 14035 } else { 14036 targetSlideIndex = swiper.getSlideIndexByData(newIndex); 14037 } 14038 const cols = gridEnabled ? Math.ceil(swiper.slides.length /
vendor: 9,245 bytes, lines 14038-14292
14038swiper.params.grid.rows) : swiper.slides.length; 14039 const { 14040 centeredSlides 14041 } = swiper.params; 14042 let slidesPerView = swiper.params.slidesPerView; 14043 if (slidesPerView === 'auto') { 14044 slidesPerView = swiper.slidesPerViewDynamic(); 14045 } else { 14046 slidesPerView = Math.ceil(parseFloat(swiper.params.slidesPerView, 10)); 14047 if (centeredSlides && slidesPerView % 2 === 0) { 14048 slidesPerView = slidesPerView + 1; 14049 } 14050 } 14051 let needLoopFix = cols - targetSlideIndex < slidesPerView; 14052 if (centeredSlides) { 14053 needLoopFix = needLoopFix || targetSlideIndex < Math.ceil(slidesPerView / 2); 14054 } 14055 if (internal && centeredSlides && swiper.params.slidesPerView !== 'auto' && !gridEnabled) { 14056 needLoopFix = false; 14057 } 14058 if (needLoopFix) { 14059 const direction = centeredSlides ? targetSlideIndex < swiper.activeIndex ? 'prev' : 'next' : targetSlideIndex - swiper.activeIndex - 1 < swiper.params.slidesPerView ? 'next' : 'prev'; 14060 swiper.loopFix({ 14061 direction, 14062 slideTo: true, 14063 activeSlideIndex: direction === 'next' ? targetSlideIndex + 1 : targetSlideIndex - cols + 1, 14064 slideRealIndex: direction === 'next' ? swiper.realIndex : undefined 14065 }); 14066 } 14067 if (gridEnabled) { 14068 const slideIndex = newIndex * swiper.params.grid.rows; 14069 newIndex = swiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === slideIndex).column; 14070 } else { 14071 newIndex = swiper.getSlideIndexByData(newIndex); 14072 } 14073 } 14074 } 14075 requestAnimationFrame(() => { 14076 swiper.slideTo(newIndex, speed, runCallbacks, internal); 14077 }); 14078 return swiper; 14079} 14080 14081/* eslint no-unused-vars: "off" */ 14082function slideNext(speed, runCallbacks, internal) { 14083 if (runCallbacks === void 0) { 14084 runCallbacks = true; 14085 } 14086 const swiper = this; 14087 const { 14088 enabled, 14089 params, 14090 animating 14091 } = swiper; 14092 if (!enabled || swiper.destroyed) return swiper; 14093 if (typeof speed === 'undefined') { 14094 speed = swiper.params.speed; 14095 } 14096 let perGroup = params.slidesPerGroup; 14097 if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) { 14098 perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1); 14099 } 14100 const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup; 14101 const isVirtual = swiper.virtual && params.virtual.enabled; 14102 if (params.loop) { 14103 if (animating && !isVirtual && params.loopPreventsSliding) return false; 14104 swiper.loopFix({ 14105 direction: 'next' 14106 }); 14107 // eslint-disable-next-line 14108 swiper._clientLeft = swiper.wrapperEl.clientLeft; 14109 if (swiper.activeIndex === swiper.slides.length - 1 && params.cssMode) { 14110 requestAnimationFrame(() => { 14111 swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal); 14112 }); 14113 return true; 14114 } 14115 } 14116 if (params.rewind && swiper.isEnd) { 14117 return swiper.slideTo(0, speed, runCallbacks, internal); 14118 } 14119 return swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal); 14120} 14121 14122/* eslint no-unused-vars: "off" */ 14123function slidePrev(speed, runCallbacks, internal) { 14124 if (runCallbacks === void 0) { 14125 runCallbacks = true; 14126 } 14127 const swiper = this; 14128 const { 14129 params, 14130 snapGrid, 14131 slidesGrid, 14132 rtlTranslate, 14133 enabled, 14134 animating 14135 } = swiper; 14136 if (!enabled || swiper.destroyed) return swiper; 14137 if (typeof speed === 'undefined') { 14138 speed = swiper.params.speed; 14139 } 14140 const isVirtual = swiper.virtual && params.virtual.enabled; 14141 if (params.loop) { 14142 if (animating && !isVirtual && params.loopPreventsSliding) return false; 14143 swiper.loopFix({ 14144 direction: 'prev' 14145 }); 14146 // eslint-disable-next-line 14147 swiper._clientLeft = swiper.wrapperEl.clientLeft; 14148 } 14149 const translate = rtlTranslate ? swiper.translate : -swiper.translate; 14150 function normalize(val) { 14151 if (val < 0) return -Math.floor(Math.abs(val)); 14152 return Math.floor(val); 14153 } 14154 const normalizedTranslate = normalize(translate); 14155 const normalizedSnapGrid = snapGrid.map(val => normalize(val)); 14156 const isFreeMode = params.freeMode && params.freeMode.enabled; 14157 let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1]; 14158 if (typeof prevSnap === 'undefined' && (params.cssMode || isFreeMode)) { 14159 let prevSnapIndex; 14160 snapGrid.forEach((snap, snapIndex) => { 14161 if (normalizedTranslate >= snap) { 14162 // prevSnap = snap; 14163 prevSnapIndex = snapIndex; 14164 } 14165 }); 14166 if (typeof prevSnapIndex !== 'undefined') { 14167 prevSnap = isFreeMode ? snapGrid[prevSnapIndex] : snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex]; 14168 } 14169 } 14170 let prevIndex = 0; 14171 if (typeof prevSnap !== 'undefined') { 14172 prevIndex = slidesGrid.indexOf(prevSnap); 14173 if (prevIndex < 0) prevIndex = swiper.activeIndex - 1; 14174 if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) { 14175 prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1; 14176 prevIndex = Math.max(prevIndex, 0); 14177 } 14178 } 14179 if (params.rewind && swiper.isBeginning) { 14180 const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1; 14181 return swiper.slideTo(lastIndex, speed, runCallbacks, internal); 14182 } else if (params.loop && swiper.activeIndex === 0 && params.cssMode) { 14183 requestAnimationFrame(() => { 14184 swiper.slideTo(prevIndex, speed, runCallbacks, internal); 14185 }); 14186 return true; 14187 } 14188 return swiper.slideTo(prevIndex, speed, runCallbacks, internal); 14189} 14190 14191/* eslint no-unused-vars: "off" */ 14192function slideReset(speed, runCallbacks, internal) { 14193 if (runCallbacks === void 0) { 14194 runCallbacks = true; 14195 } 14196 const swiper = this; 14197 if (swiper.destroyed) return; 14198 if (typeof speed === 'undefined') { 14199 speed = swiper.params.speed; 14200 } 14201 return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal); 14202} 14203 14204/* eslint no-unused-vars: "off" */ 14205function slideToClosest(speed, runCallbacks, internal, threshold) { 14206 if (runCallbacks === void 0) { 14207 runCallbacks = true; 14208 } 14209 if (threshold === void 0) { 14210 threshold = 0.5; 14211 } 14212 const swiper = this; 14213 if (swiper.destroyed) return; 14214 if (typeof speed === 'undefined') { 14215 speed = swiper.params.speed; 14216 } 14217 let index = swiper.activeIndex; 14218 const skip = Math.min(swiper.params.slidesPerGroupSkip, index); 14219 const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup); 14220 const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate; 14221 if (translate >= swiper.snapGrid[snapIndex]) { 14222 // The current translate is on or after the current snap index, so the choice 14223 // is between the current index and the one after it. 14224 const currentSnap = swiper.snapGrid[snapIndex]; 14225 const nextSnap = swiper.snapGrid[snapIndex + 1]; 14226 if (translate - currentSnap > (nextSnap - currentSnap) * threshold) { 14227 index += swiper.params.slidesPerGroup; 14228 } 14229 } else { 14230 // The current translate is before the current snap index, so the choice 14231 // is between the current index and the one before it. 14232 const prevSnap = swiper.snapGrid[snapIndex - 1]; 14233 const currentSnap = swiper.snapGrid[snapIndex]; 14234 if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) { 14235 index -= swiper.params.slidesPerGroup; 14236 } 14237 } 14238 index = Math.max(index, 0); 14239 index = Math.min(index, swiper.slidesGrid.length - 1); 14240 return swiper.slideTo(index, speed, runCallbacks, internal); 14241} 14242 14243function slideToClickedSlide() { 14244 const swiper = this; 14245 if (swiper.destroyed) return; 14246 const { 14247 params, 14248 slidesEl 14249 } = swiper; 14250 const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView; 14251 let slideToIndex = swiper.getSlideIndexWhenGrid(swiper.clickedIndex); 14252 let realIndex; 14253 const slideSelector = swiper.isElement ? `swiper-slide` : `.${params.slideClass}`; 14254 const isGrid = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1; 14255 if (params.loop) { 14256 if (swiper.animating) return; 14257 realIndex = parseInt(swiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10); 14258 if (params.centeredSlides) { 14259 swiper.slideToLoop(realIndex); 14260 } else if (slideToIndex > (isGrid ? (swiper.slides.length - slidesPerView) / 2 - (swiper.params.grid.rows - 1) : swiper.slides.length - slidesPerView)) { 14261 swiper.loopFix(); 14262 slideToIndex = swiper.getSlideIndex(utils_elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]); 14263 utils_nextTick(() => { 14264 swiper.slideTo(slideToIndex); 14265 }); 14266 } else { 14267 swiper.slideTo(slideToIndex); 14268 } 14269 } else { 14270 swiper.slideTo(slideToIndex); 14271 } 14272} 14273 14274var slide = { 14275 slideTo, 14276 slideToLoop, 14277 slideNext, 14278 slidePrev, 14279 slideReset, 14280 slideToClosest, 14281 slideToClickedSlide 14282}; 14283 14284function loopCreate(slideRealIndex, initial) { 14285 const swiper = this; 14286 const { 14287 params, 14288 slidesEl 14289 } = swiper; 14290 if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return; 14291 const initSlides = () => { 14292 const slides = utils_elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
vendor: 5,612 bytes, lines 14293-14429
14293 slides.forEach((el, index) => { 14294 el.setAttribute('data-swiper-slide-index', index); 14295 }); 14296 }; 14297 const clearBlankSlides = () => { 14298 const slides = utils_elementChildren(slidesEl, `.${params.slideBlankClass}`); 14299 slides.forEach(el => { 14300 el.remove(); 14301 }); 14302 if (slides.length > 0) { 14303 swiper.recalcSlides(); 14304 swiper.updateSlides(); 14305 } 14306 }; 14307 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1; 14308 if (params.loopAddBlankSlides && (params.slidesPerGroup > 1 || gridEnabled)) { 14309 clearBlankSlides(); 14310 } 14311 const slidesPerGroup = params.slidesPerGroup * (gridEnabled ? params.grid.rows : 1); 14312 const shouldFillGroup = swiper.slides.length % slidesPerGroup !== 0; 14313 const shouldFillGrid = gridEnabled && swiper.slides.length % params.grid.rows !== 0; 14314 const addBlankSlides = amountOfSlides => { 14315 for (let i = 0; i < amountOfSlides; i += 1) { 14316 const slideEl = swiper.isElement ? utils_createElement('swiper-slide', [params.slideBlankClass]) : utils_createElement('div', [params.slideClass, params.slideBlankClass]); 14317 swiper.slidesEl.append(slideEl); 14318 } 14319 }; 14320 if (shouldFillGroup) { 14321 if (params.loopAddBlankSlides) { 14322 const slidesToAdd = slidesPerGroup - swiper.slides.length % slidesPerGroup; 14323 addBlankSlides(slidesToAdd); 14324 swiper.recalcSlides(); 14325 swiper.updateSlides(); 14326 } else { 14327 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)'); 14328 } 14329 initSlides(); 14330 } else if (shouldFillGrid) { 14331 if (params.loopAddBlankSlides) { 14332 const slidesToAdd = params.grid.rows - swiper.slides.length % params.grid.rows; 14333 addBlankSlides(slidesToAdd); 14334 swiper.recalcSlides(); 14335 swiper.updateSlides(); 14336 } else { 14337 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)'); 14338 } 14339 initSlides(); 14340 } else { 14341 initSlides(); 14342 } 14343 swiper.loopFix({ 14344 slideRealIndex, 14345 direction: params.centeredSlides ? undefined : 'next', 14346 initial 14347 }); 14348} 14349 14350function loopFix(_temp) { 14351 let { 14352 slideRealIndex, 14353 slideTo = true, 14354 direction, 14355 setTranslate, 14356 activeSlideIndex, 14357 initial, 14358 byController, 14359 byMousewheel 14360 } = _temp === void 0 ? {} : _temp; 14361 const swiper = this; 14362 if (!swiper.params.loop) return; 14363 swiper.emit('beforeLoopFix'); 14364 const { 14365 slides, 14366 allowSlidePrev, 14367 allowSlideNext, 14368 slidesEl, 14369 params 14370 } = swiper; 14371 const { 14372 centeredSlides, 14373 initialSlide 14374 } = params; 14375 swiper.allowSlidePrev = true; 14376 swiper.allowSlideNext = true; 14377 if (swiper.virtual && params.virtual.enabled) { 14378 if (slideTo) { 14379 if (!params.centeredSlides && swiper.snapIndex === 0) { 14380 swiper.slideTo(swiper.virtual.slides.length, 0, false, true); 14381 } else if (params.centeredSlides && swiper.snapIndex < params.slidesPerView) { 14382 swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true); 14383 } else if (swiper.snapIndex === swiper.snapGrid.length - 1) { 14384 swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true); 14385 } 14386 } 14387 swiper.allowSlidePrev = allowSlidePrev; 14388 swiper.allowSlideNext = allowSlideNext; 14389 swiper.emit('loopFix'); 14390 return; 14391 } 14392 let slidesPerView = params.slidesPerView; 14393 if (slidesPerView === 'auto') { 14394 slidesPerView = swiper.slidesPerViewDynamic(); 14395 } else { 14396 slidesPerView = Math.ceil(parseFloat(params.slidesPerView, 10)); 14397 if (centeredSlides && slidesPerView % 2 === 0) { 14398 slidesPerView = slidesPerView + 1; 14399 } 14400 } 14401 const slidesPerGroup = params.slidesPerGroupAuto ? slidesPerView : params.slidesPerGroup; 14402 let loopedSlides = centeredSlides ? Math.max(slidesPerGroup, Math.ceil(slidesPerView / 2)) : slidesPerGroup; 14403 if (loopedSlides % slidesPerGroup !== 0) { 14404 loopedSlides += slidesPerGroup - loopedSlides % slidesPerGroup; 14405 } 14406 loopedSlides += params.loopAdditionalSlides; 14407 swiper.loopedSlides = loopedSlides; 14408 const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1; 14409 if (slides.length < slidesPerView + loopedSlides || swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) { 14410 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'); 14411 } else if (gridEnabled && params.grid.fill === 'row') { 14412 showWarning('Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`'); 14413 } 14414 const prependSlidesIndexes = []; 14415 const appendSlidesIndexes = []; 14416 const cols = gridEnabled ? Math.ceil(slides.length / params.grid.rows) : slides.length; 14417 const isInitialOverflow = initial && cols - initialSlide < slidesPerView && !centeredSlides; 14418 let activeIndex = isInitialOverflow ? initialSlide : swiper.activeIndex; 14419 if (typeof activeSlideIndex === 'undefined') { 14420 activeSlideIndex = swiper.getSlideIndex(slides.find(el => el.classList.contains(params.slideActiveClass))); 14421 } else { 14422 activeIndex = activeSlideIndex; 14423 } 14424 const isNext = direction === 'next' || !direction; 14425 const isPrev = direction === 'prev' || !direction; 14426 let slidesPrepended = 0; 14427 let slidesAppended = 0; 14428 const activeColIndex = gridEnabled ? slides[activeSlideIndex].column : activeSlideIndex; 14429 const activeColIndexWithShift = activeColIndex + (centeredSlide
vendor: 7,760 bytes, lines 14429-14636
14429s && typeof setTranslate === 'undefined' ? -slidesPerView / 2 + 0.5 : 0); 14430 // prepend last slides before start 14431 if (activeColIndexWithShift < loopedSlides) { 14432 slidesPrepended = Math.max(loopedSlides - activeColIndexWithShift, slidesPerGroup); 14433 for (let i = 0; i < loopedSlides - activeColIndexWithShift; i += 1) { 14434 const index = i - Math.floor(i / cols) * cols; 14435 if (gridEnabled) { 14436 const colIndexToPrepend = cols - index - 1; 14437 for (let i = slides.length - 1; i >= 0; i -= 1) { 14438 if (slides[i].column === colIndexToPrepend) prependSlidesIndexes.push(i); 14439 } 14440 // slides.forEach((slide, slideIndex) => { 14441 // if (slide.column === colIndexToPrepend) prependSlidesIndexes.push(slideIndex); 14442 // }); 14443 } else { 14444 prependSlidesIndexes.push(cols - index - 1); 14445 } 14446 } 14447 } else if (activeColIndexWithShift + slidesPerView > cols - loopedSlides) { 14448 slidesAppended = Math.max(activeColIndexWithShift - (cols - loopedSlides * 2), slidesPerGroup); 14449 if (isInitialOverflow) { 14450 slidesAppended = Math.max(slidesAppended, slidesPerView - cols + initialSlide + 1); 14451 } 14452 for (let i = 0; i < slidesAppended; i += 1) { 14453 const index = i - Math.floor(i / cols) * cols; 14454 if (gridEnabled) { 14455 slides.forEach((slide, slideIndex) => { 14456 if (slide.column === index) appendSlidesIndexes.push(slideIndex); 14457 }); 14458 } else { 14459 appendSlidesIndexes.push(index); 14460 } 14461 } 14462 } 14463 swiper.__preventObserver__ = true; 14464 requestAnimationFrame(() => { 14465 swiper.__preventObserver__ = false; 14466 }); 14467 if (swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) { 14468 if (appendSlidesIndexes.includes(activeSlideIndex)) { 14469 appendSlidesIndexes.splice(appendSlidesIndexes.indexOf(activeSlideIndex), 1); 14470 } 14471 if (prependSlidesIndexes.includes(activeSlideIndex)) { 14472 prependSlidesIndexes.splice(prependSlidesIndexes.indexOf(activeSlideIndex), 1); 14473 } 14474 } 14475 if (isPrev) { 14476 prependSlidesIndexes.forEach(index => { 14477 slides[index].swiperLoopMoveDOM = true; 14478 slidesEl.prepend(slides[index]); 14479 slides[index].swiperLoopMoveDOM = false; 14480 }); 14481 } 14482 if (isNext) { 14483 appendSlidesIndexes.forEach(index => { 14484 slides[index].swiperLoopMoveDOM = true; 14485 slidesEl.append(slides[index]); 14486 slides[index].swiperLoopMoveDOM = false; 14487 }); 14488 } 14489 swiper.recalcSlides(); 14490 if (params.slidesPerView === 'auto') { 14491 swiper.updateSlides(); 14492 } else if (gridEnabled && (prependSlidesIndexes.length > 0 && isPrev || appendSlidesIndexes.length > 0 && isNext)) { 14493 swiper.slides.forEach((slide, slideIndex) => { 14494 swiper.grid.updateSlide(slideIndex, slide, swiper.slides); 14495 }); 14496 } 14497 if (params.watchSlidesProgress) { 14498 swiper.updateSlidesOffset(); 14499 } 14500 if (slideTo) { 14501 if (prependSlidesIndexes.length > 0 && isPrev) { 14502 if (typeof slideRealIndex === 'undefined') { 14503 const currentSlideTranslate = swiper.slidesGrid[activeIndex]; 14504 const newSlideTranslate = swiper.slidesGrid[activeIndex + slidesPrepended]; 14505 const diff = newSlideTranslate - currentSlideTranslate; 14506 if (byMousewheel) { 14507 swiper.setTranslate(swiper.translate - diff); 14508 } else { 14509 swiper.slideTo(activeIndex + Math.ceil(slidesPrepended), 0, false, true); 14510 if (setTranslate) { 14511 swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff; 14512 swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff; 14513 } 14514 } 14515 } else { 14516 if (setTranslate) { 14517 const shift = gridEnabled ? prependSlidesIndexes.length / params.grid.rows : prependSlidesIndexes.length; 14518 swiper.slideTo(swiper.activeIndex + shift, 0, false, true); 14519 swiper.touchEventsData.currentTranslate = swiper.translate; 14520 } 14521 } 14522 } else if (appendSlidesIndexes.length > 0 && isNext) { 14523 if (typeof slideRealIndex === 'undefined') { 14524 const currentSlideTranslate = swiper.slidesGrid[activeIndex]; 14525 const newSlideTranslate = swiper.slidesGrid[activeIndex - slidesAppended]; 14526 const diff = newSlideTranslate - currentSlideTranslate; 14527 if (byMousewheel) { 14528 swiper.setTranslate(swiper.translate - diff); 14529 } else { 14530 swiper.slideTo(activeIndex - slidesAppended, 0, false, true); 14531 if (setTranslate) { 14532 swiper.touchEventsData.startTranslate = swiper.touchEventsData.startTranslate - diff; 14533 swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff; 14534 } 14535 } 14536 } else { 14537 const shift = gridEnabled ? appendSlidesIndexes.length / params.grid.rows : appendSlidesIndexes.length; 14538 swiper.slideTo(swiper.activeIndex - shift, 0, false, true); 14539 } 14540 } 14541 } 14542 swiper.allowSlidePrev = allowSlidePrev; 14543 swiper.allowSlideNext = allowSlideNext; 14544 if (swiper.controller && swiper.controller.control && !byController) { 14545 const loopParams = { 14546 slideRealIndex, 14547 direction, 14548 setTranslate, 14549 activeSlideIndex, 14550 byController: true 14551 }; 14552 if (Array.isArray(swiper.controller.control)) { 14553 swiper.controller.control.forEach(c => { 14554 if (!c.destroyed && c.params.loop) c.loopFix({ 14555 ...loopParams, 14556 slideTo: c.params.slidesPerView === params.slidesPerView ? slideTo : false 14557 }); 14558 }); 14559 } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) { 14560 swiper.controller.control.loopFix({ 14561 ...loopParams, 14562 slideTo: swiper.controller.control.params.slidesPerView === params.slidesPerView ? slideTo : false 14563 }); 14564 } 14565 } 14566 swiper.emit('loopFix'); 14567} 14568 14569function loopDestroy() { 14570 const swiper = this; 14571 const { 14572 params, 14573 slidesEl 14574 } = swiper; 14575 if (!params.loop || !slidesEl || swiper.virtual && swiper.params.virtual.enabled) return; 14576 swiper.recalcSlides(); 14577 const newSlidesOrder = []; 14578 swiper.slides.forEach(slideEl => { 14579 const index = typeof slideEl.swiperSlideIndex === 'undefined' ? slideEl.getAttribute('data-swiper-slide-index') * 1 : slideEl.swiperSlideIndex; 14580 newSlidesOrder[index] = slideEl; 14581 }); 14582 swiper.slides.forEach(slideEl => { 14583 slideEl.removeAttribute('data-swiper-slide-index'); 14584 }); 14585 newSlidesOrder.forEach(slideEl => { 14586 slidesEl.append(slideEl); 14587 }); 14588 swiper.recalcSlides(); 14589 swiper.slideTo(swiper.realIndex, 0); 14590} 14591 14592var loop = { 14593 loopCreate, 14594 loopFix, 14595 loopDestroy 14596}; 14597 14598function setGrabCursor(moving) { 14599 const swiper = this; 14600 if (!swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) return; 14601 const el = swiper.params.touchEventsTarget === 'container' ? swiper.el : swiper.wrapperEl; 14602 if (swiper.isElement) { 14603 swiper.__preventObserver__ = true; 14604 } 14605 el.style.cursor = 'move'; 14606 el.style.cursor = moving ? 'grabbing' : 'grab'; 14607 if (swiper.isElement) { 14608 requestAnimationFrame(() => { 14609 swiper.__preventObserver__ = false; 14610 }); 14611 } 14612} 14613 14614function unsetGrabCursor() { 14615 const swiper = this; 14616 if (swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) { 14617 return; 14618 } 14619 if (swiper.isElement) { 14620 swiper.__preventObserver__ = true; 14621 } 14622 swiper[swiper.params.touchEventsTarget === 'container' ? 'el' : 'wrapperEl'].style.cursor = ''; 14623 if (swiper.isElement) { 14624 requestAnimationFrame(() => { 14625 swiper.__preventObserver__ = false; 14626 }); 14627 } 14628} 14629 14630var grabCursor = { 14631 setGrabCursor, 14632 unsetGrabCursor 14633}; 14634 14635// Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd 14636function closestElement(selector, base
vendor: 3,722 bytes, lines 14636-14748
14636) { 14637 if (base === void 0) { 14638 base = this; 14639 } 14640 function __closestFrom(el) { 14641 if (!el || el === ssr_window_esm_getDocument() || el === ssr_window_esm_getWindow()) return null; 14642 if (el.assignedSlot) el = el.assignedSlot; 14643 const found = el.closest(selector); 14644 if (!found && !el.getRootNode) { 14645 return null; 14646 } 14647 return found || __closestFrom(el.getRootNode().host); 14648 } 14649 return __closestFrom(base); 14650} 14651function preventEdgeSwipe(swiper, event, startX) { 14652 const window = ssr_window_esm_getWindow(); 14653 const { 14654 params 14655 } = swiper; 14656 const edgeSwipeDetection = params.edgeSwipeDetection; 14657 const edgeSwipeThreshold = params.edgeSwipeThreshold; 14658 if (edgeSwipeDetection && (startX <= edgeSwipeThreshold || startX >= window.innerWidth - edgeSwipeThreshold)) { 14659 if (edgeSwipeDetection === 'prevent') { 14660 event.preventDefault(); 14661 return true; 14662 } 14663 return false; 14664 } 14665 return true; 14666} 14667function onTouchStart(event) { 14668 const swiper = this; 14669 const document = ssr_window_esm_getDocument(); 14670 let e = event; 14671 if (e.originalEvent) e = e.originalEvent; 14672 const data = swiper.touchEventsData; 14673 if (e.type === 'pointerdown') { 14674 if (data.pointerId !== null && data.pointerId !== e.pointerId) { 14675 return; 14676 } 14677 data.pointerId = e.pointerId; 14678 } else if (e.type === 'touchstart' && e.targetTouches.length === 1) { 14679 data.touchId = e.targetTouches[0].identifier; 14680 } 14681 if (e.type === 'touchstart') { 14682 // don't proceed touch event 14683 preventEdgeSwipe(swiper, e, e.targetTouches[0].pageX); 14684 return; 14685 } 14686 const { 14687 params, 14688 touches, 14689 enabled 14690 } = swiper; 14691 if (!enabled) return; 14692 if (!params.simulateTouch && e.pointerType === 'mouse') return; 14693 if (swiper.animating && params.preventInteractionOnTransition) { 14694 return; 14695 } 14696 if (!swiper.animating && params.cssMode && params.loop) { 14697 swiper.loopFix(); 14698 } 14699 let targetEl = e.target; 14700 if (params.touchEventsTarget === 'wrapper') { 14701 if (!elementIsChildOf(targetEl, swiper.wrapperEl)) return; 14702 } 14703 if ('which' in e && e.which === 3) return; 14704 if ('button' in e && e.button > 0) return; 14705 if (data.isTouched && data.isMoved) return; 14706 14707 // change target el for shadow root component 14708 const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== ''; 14709 // eslint-disable-next-line 14710 const eventPath = e.composedPath ? e.composedPath() : e.path; 14711 if (swipingClassHasValue && e.target && e.target.shadowRoot && eventPath) { 14712 targetEl = eventPath[0]; 14713 } 14714 const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`; 14715 const isTargetShadow = !!(e.target && e.target.shadowRoot); 14716 14717 // use closestElement for shadow root element to get the actual closest for nested shadow root element 14718 if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))) { 14719 swiper.allowClick = true; 14720 return; 14721 } 14722 if (params.swipeHandler) { 14723 if (!targetEl.closest(params.swipeHandler)) return; 14724 } 14725 touches.currentX = e.pageX; 14726 touches.currentY = e.pageY; 14727 const startX = touches.currentX; 14728 const startY = touches.currentY; 14729 14730 // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore 14731 14732 if (!preventEdgeSwipe(swiper, e, startX)) { 14733 return; 14734 } 14735 Object.assign(data, { 14736 isTouched: true, 14737 isMoved: false, 14738 allowTouchCallbacks: true, 14739 isScrolling: undefined, 14740 startMoving: undefined 14741 }); 14742 touches.startX = startX; 14743 touches.startY = startY; 14744 data.touchStartTime = utils_now(); 14745 swiper.allowClick = true; 14746 swiper.updateSize(); 14747 swiper.swipeDirection = undefined; 14748 if (params.threshold > 0) data.allowThresholdMove = false;
vendor: 2,328 bytes, lines 14749-14819
14749 let preventDefault = true; 14750 if (targetEl.matches(data.focusableElements)) { 14751 preventDefault = false; 14752 if (targetEl.nodeName === 'SELECT') { 14753 data.isTouched = false; 14754 } 14755 } 14756 if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== targetEl && (e.pointerType === 'mouse' || e.pointerType !== 'mouse' && !targetEl.matches(data.focusableElements))) { 14757 document.activeElement.blur(); 14758 } 14759 const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault; 14760 if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) { 14761 e.preventDefault(); 14762 } 14763 if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) { 14764 swiper.freeMode.onTouchStart(); 14765 } 14766 swiper.emit('touchStart', e); 14767} 14768 14769function onTouchMove(event) { 14770 const document = ssr_window_esm_getDocument(); 14771 const swiper = this; 14772 const data = swiper.touchEventsData; 14773 const { 14774 params, 14775 touches, 14776 rtlTranslate: rtl, 14777 enabled 14778 } = swiper; 14779 if (!enabled) return; 14780 if (!params.simulateTouch && event.pointerType === 'mouse') return; 14781 let e = event; 14782 if (e.originalEvent) e = e.originalEvent; 14783 if (e.type === 'pointermove') { 14784 if (data.touchId !== null) return; // return from pointer if we use touch 14785 const id = e.pointerId; 14786 if (id !== data.pointerId) return; 14787 } 14788 let targetTouch; 14789 if (e.type === 'touchmove') { 14790 targetTouch = [...e.changedTouches].find(t => t.identifier === data.touchId); 14791 if (!targetTouch || targetTouch.identifier !== data.touchId) return; 14792 } else { 14793 targetTouch = e; 14794 } 14795 if (!data.isTouched) { 14796 if (data.startMoving && data.isScrolling) { 14797 swiper.emit('touchMoveOpposite', e); 14798 } 14799 return; 14800 } 14801 const pageX = targetTouch.pageX; 14802 const pageY = targetTouch.pageY; 14803 if (e.preventedByNestedSwiper) { 14804 touches.startX = pageX; 14805 touches.startY = pageY; 14806 return; 14807 } 14808 if (!swiper.allowTouchMove) { 14809 if (!e.target.matches(data.focusableElements)) { 14810 swiper.allowClick = false; 14811 } 14812 if (data.isTouched) { 14813 Object.assign(touches, { 14814 startX: pageX, 14815 startY: pageY, 14816 currentX: pageX, 14817 currentY: pageY 14818 }); 14819 data.touchStartTime = utils_now
vendor: 10,043 bytes, lines 14819-15082
14819(); 14820 } 14821 return; 14822 } 14823 if (params.touchReleaseOnEdges && !params.loop) { 14824 if (swiper.isVertical()) { 14825 // Vertical 14826 if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) { 14827 data.isTouched = false; 14828 data.isMoved = false; 14829 return; 14830 } 14831 } else if (rtl && (pageX > touches.startX && -swiper.translate <= swiper.maxTranslate() || pageX < touches.startX && -swiper.translate >= swiper.minTranslate())) { 14832 return; 14833 } else if (!rtl && (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX && swiper.translate >= swiper.minTranslate())) { 14834 return; 14835 } 14836 } 14837 if (document.activeElement && document.activeElement.matches(data.focusableElements) && document.activeElement !== e.target && e.pointerType !== 'mouse') { 14838 document.activeElement.blur(); 14839 } 14840 if (document.activeElement) { 14841 if (e.target === document.activeElement && e.target.matches(data.focusableElements)) { 14842 data.isMoved = true; 14843 swiper.allowClick = false; 14844 return; 14845 } 14846 } 14847 if (data.allowTouchCallbacks) { 14848 swiper.emit('touchMove', e); 14849 } 14850 touches.previousX = touches.currentX; 14851 touches.previousY = touches.currentY; 14852 touches.currentX = pageX; 14853 touches.currentY = pageY; 14854 const diffX = touches.currentX - touches.startX; 14855 const diffY = touches.currentY - touches.startY; 14856 if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return; 14857 if (typeof data.isScrolling === 'undefined') { 14858 let touchAngle; 14859 if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX === touches.startX) { 14860 data.isScrolling = false; 14861 } else { 14862 // eslint-disable-next-line 14863 if (diffX * diffX + diffY * diffY >= 25) { 14864 touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI; 14865 data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params.touchAngle; 14866 } 14867 } 14868 } 14869 if (data.isScrolling) { 14870 swiper.emit('touchMoveOpposite', e); 14871 } 14872 if (typeof data.startMoving === 'undefined') { 14873 if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) { 14874 data.startMoving = true; 14875 } 14876 } 14877 if (data.isScrolling || e.type === 'touchmove' && data.preventTouchMoveFromPointerMove) { 14878 data.isTouched = false; 14879 return; 14880 } 14881 if (!data.startMoving) { 14882 return; 14883 } 14884 swiper.allowClick = false; 14885 if (!params.cssMode && e.cancelable) { 14886 e.preventDefault(); 14887 } 14888 if (params.touchMoveStopPropagation && !params.nested) { 14889 e.stopPropagation(); 14890 } 14891 let diff = swiper.isHorizontal() ? diffX : diffY; 14892 let touchesDiff = swiper.isHorizontal() ? touches.currentX - touches.previousX : touches.currentY - touches.previousY; 14893 if (params.oneWayMovement) { 14894 diff = Math.abs(diff) * (rtl ? 1 : -1); 14895 touchesDiff = Math.abs(touchesDiff) * (rtl ? 1 : -1); 14896 } 14897 touches.diff = diff; 14898 diff *= params.touchRatio; 14899 if (rtl) { 14900 diff = -diff; 14901 touchesDiff = -touchesDiff; 14902 } 14903 const prevTouchesDirection = swiper.touchesDirection; 14904 swiper.swipeDirection = diff > 0 ? 'prev' : 'next'; 14905 swiper.touchesDirection = touchesDiff > 0 ? 'prev' : 'next'; 14906 const isLoop = swiper.params.loop && !params.cssMode; 14907 const allowLoopFix = swiper.touchesDirection === 'next' && swiper.allowSlideNext || swiper.touchesDirection === 'prev' && swiper.allowSlidePrev; 14908 if (!data.isMoved) { 14909 if (isLoop && allowLoopFix) { 14910 swiper.loopFix({ 14911 direction: swiper.swipeDirection 14912 }); 14913 } 14914 data.startTranslate = swiper.getTranslate(); 14915 swiper.setTransition(0); 14916 if (swiper.animating) { 14917 const evt = new window.CustomEvent('transitionend', { 14918 bubbles: true, 14919 cancelable: true, 14920 detail: { 14921 bySwiperTouchMove: true 14922 } 14923 }); 14924 swiper.wrapperEl.dispatchEvent(evt); 14925 } 14926 data.allowMomentumBounce = false; 14927 // Grab Cursor 14928 if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) { 14929 swiper.setGrabCursor(true); 14930 } 14931 swiper.emit('sliderFirstMove', e); 14932 } 14933 let loopFixed; 14934 new Date().getTime(); 14935 if (params._loopSwapReset !== false && data.isMoved && data.allowThresholdMove && prevTouchesDirection !== swiper.touchesDirection && isLoop && allowLoopFix && Math.abs(diff) >= 1) { 14936 Object.assign(touches, { 14937 startX: pageX, 14938 startY: pageY, 14939 currentX: pageX, 14940 currentY: pageY, 14941 startTranslate: data.currentTranslate 14942 }); 14943 data.loopSwapReset = true; 14944 data.startTranslate = data.currentTranslate; 14945 return; 14946 } 14947 swiper.emit('sliderMove', e); 14948 data.isMoved = true; 14949 data.currentTranslate = diff + data.startTranslate; 14950 let disableParentSwiper = true; 14951 let resistanceRatio = params.resistanceRatio; 14952 if (params.touchReleaseOnEdges) { 14953 resistanceRatio = 0; 14954 } 14955 if (diff > 0) { 14956 if (isLoop && allowLoopFix && !loopFixed && 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())) { 14957 swiper.loopFix({ 14958 direction: 'prev', 14959 setTranslate: true, 14960 activeSlideIndex: 0 14961 }); 14962 } 14963 if (data.currentTranslate > swiper.minTranslate()) { 14964 disableParentSwiper = false; 14965 if (params.resistance) { 14966 data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio; 14967 } 14968 } 14969 } else if (diff < 0) { 14970 if (isLoop && allowLoopFix && !loopFixed && 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())) { 14971 swiper.loopFix({ 14972 direction: 'next', 14973 setTranslate: true, 14974 activeSlideIndex: swiper.slides.length - (params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10))) 14975 }); 14976 } 14977 if (data.currentTranslate < swiper.maxTranslate()) { 14978 disableParentSwiper = false; 14979 if (params.resistance) { 14980 data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio; 14981 } 14982 } 14983 } 14984 if (disableParentSwiper) { 14985 e.preventedByNestedSwiper = true; 14986 } 14987 14988 // Directions locks 14989 if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) { 14990 data.currentTranslate = data.startTranslate; 14991 } 14992 if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) { 14993 data.currentTranslate = data.startTranslate; 14994 } 14995 if (!swiper.allowSlidePrev && !swiper.allowSlideNext) { 14996 data.currentTranslate = data.startTranslate; 14997 } 14998 14999 // Threshold 15000 if (params.threshold > 0) { 15001 if (Math.abs(diff) > params.threshold || data.allowThresholdMove) { 15002 if (!data.allowThresholdMove) { 15003 data.allowThresholdMove = true; 15004 touches.startX = touches.currentX; 15005 touches.startY = touches.currentY; 15006 data.currentTranslate = data.startTranslate; 15007 touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY; 15008 return; 15009 } 15010 } else { 15011 data.currentTranslate = data.startTranslate; 15012 return; 15013 } 15014 } 15015 if (!params.followFinger || params.cssMode) return; 15016 15017 // Update active index in free mode 15018 if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) { 15019 swiper.updateActiveIndex(); 15020 swiper.updateSlidesClasses(); 15021 } 15022 if (params.freeMode && params.freeMode.enabled && swiper.freeMode) { 15023 swiper.freeMode.onTouchMove(); 15024 } 15025 // Update progress 15026 swiper.updateProgress(data.currentTranslate); 15027 // Update translate 15028 swiper.setTranslate(data.currentTranslate); 15029} 15030 15031function onTouchEnd(event) { 15032 const swiper = this; 15033 const data = swiper.touchEventsData; 15034 let e = event; 15035 if (e.originalEvent) e = e.originalEvent; 15036 let targetTouch; 15037 const isTouchEvent = e.type === 'touchend' || e.type === 'touchcancel'; 15038 if (!isTouchEvent) { 15039 if (data.touchId !== null) return; // return from pointer if we use touch 15040 if (e.pointerId !== data.pointerId) return; 15041 targetTouch = e; 15042 } else { 15043 targetTouch = [...e.changedTouches].find(t => t.identifier === data.touchId); 15044 if (!targetTouch || targetTouch.identifier !== data.touchId) return; 15045 } 15046 if (['pointercancel', 'pointerout', 'pointerleave', 'contextmenu'].includes(e.type)) { 15047 const proceed = ['pointercancel', 'contextmenu'].includes(e.type) && (swiper.browser.isSafari || swiper.browser.isWebView); 15048 if (!proceed) { 15049 return; 15050 } 15051 } 15052 data.pointerId = null; 15053 data.touchId = null; 15054 const { 15055 params, 15056 touches, 15057 rtlTranslate: rtl, 15058 slidesGrid, 15059 enabled 15060 } = swiper; 15061 if (!enabled) return; 15062 if (!params.simulateTouch && e.pointerType === 'mouse') return; 15063 if (data.allowTouchCallbacks) { 15064 swiper.emit('touchEnd', e); 15065 } 15066 data.allowTouchCallbacks = false; 15067 if (!data.isTouched) { 15068 if (data.isMoved && params.grabCursor) { 15069 swiper.setGrabCursor(false); 15070 } 15071 data.isMoved = false; 15072 data.startMoving = false; 15073 return; 15074 } 15075 15076 // Return Grab Cursor 15077 if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) { 15078 swiper.setGrabCursor(false); 15079 } 15080 15081 // Time diff 15082 const touchEndTime =
vendor: 4,126 bytes, lines 15082-15198
15082utils_now(); 15083 const timeDiff = touchEndTime - data.touchStartTime; 15084 15085 // Tap, doubleTap, Click 15086 if (swiper.allowClick) { 15087 const pathTree = e.path || e.composedPath && e.composedPath(); 15088 swiper.updateClickedSlide(pathTree && pathTree[0] || e.target, pathTree); 15089 swiper.emit('tap click', e); 15090 if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) { 15091 swiper.emit('doubleTap doubleClick', e); 15092 } 15093 } 15094 data.lastClickTime = utils_now(); 15095 utils_nextTick(() => { 15096 if (!swiper.destroyed) swiper.allowClick = true; 15097 }); 15098 if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 && !data.loopSwapReset || data.currentTranslate === data.startTranslate && !data.loopSwapReset) { 15099 data.isTouched = false; 15100 data.isMoved = false; 15101 data.startMoving = false; 15102 return; 15103 } 15104 data.isTouched = false; 15105 data.isMoved = false; 15106 data.startMoving = false; 15107 let currentPos; 15108 if (params.followFinger) { 15109 currentPos = rtl ? swiper.translate : -swiper.translate; 15110 } else { 15111 currentPos = -data.currentTranslate; 15112 } 15113 if (params.cssMode) { 15114 return; 15115 } 15116 if (params.freeMode && params.freeMode.enabled) { 15117 swiper.freeMode.onTouchEnd({ 15118 currentPos 15119 }); 15120 return; 15121 } 15122 15123 // Find current slide 15124 const swipeToLast = currentPos >= -swiper.maxTranslate() && !swiper.params.loop; 15125 let stopIndex = 0; 15126 let groupSize = swiper.slidesSizesGrid[0]; 15127 for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) { 15128 const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup; 15129 if (typeof slidesGrid[i + increment] !== 'undefined') { 15130 if (swipeToLast || currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) { 15131 stopIndex = i; 15132 groupSize = slidesGrid[i + increment] - slidesGrid[i]; 15133 } 15134 } else if (swipeToLast || currentPos >= slidesGrid[i]) { 15135 stopIndex = i; 15136 groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2]; 15137 } 15138 } 15139 let rewindFirstIndex = null; 15140 let rewindLastIndex = null; 15141 if (params.rewind) { 15142 if (swiper.isBeginning) { 15143 rewindLastIndex = params.virtual && params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1; 15144 } else if (swiper.isEnd) { 15145 rewindFirstIndex = 0; 15146 } 15147 } 15148 // Find current slide size 15149 const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize; 15150 const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup; 15151 if (timeDiff > params.longSwipesMs) { 15152 // Long touches 15153 if (!params.longSwipes) { 15154 swiper.slideTo(swiper.activeIndex); 15155 return; 15156 } 15157 if (swiper.swipeDirection === 'next') { 15158 if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);else swiper.slideTo(stopIndex); 15159 } 15160 if (swiper.swipeDirection === 'prev') { 15161 if (ratio > 1 - params.longSwipesRatio) { 15162 swiper.slideTo(stopIndex + increment); 15163 } else if (rewindLastIndex !== null && ratio < 0 && Math.abs(ratio) > params.longSwipesRatio) { 15164 swiper.slideTo(rewindLastIndex); 15165 } else { 15166 swiper.slideTo(stopIndex); 15167 } 15168 } 15169 } else { 15170 // Short swipes 15171 if (!params.shortSwipes) { 15172 swiper.slideTo(swiper.activeIndex); 15173 return; 15174 } 15175 const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper.navigation.prevEl); 15176 if (!isNavButtonTarget) { 15177 if (swiper.swipeDirection === 'next') { 15178 swiper.slideTo(rewindFirstIndex !== null ? rewindFirstIndex : stopIndex + increment); 15179 } 15180 if (swiper.swipeDirection === 'prev') { 15181 swiper.slideTo(rewindLastIndex !== null ? rewindLastIndex : stopIndex); 15182 } 15183 } else if (e.target === swiper.navigation.nextEl) { 15184 swiper.slideTo(stopIndex + increment); 15185 } else { 15186 swiper.slideTo(stopIndex); 15187 } 15188 } 15189} 15190 15191function onResize() { 15192 const swiper = this; 15193 const { 15194 params, 15195 el 15196 } = swiper; 15197 if (el && el.offsetWidth === 0) return; 15198
vendor: 6,463 bytes, lines 15199-15421
15199 // Breakpoints 15200 if (params.breakpoints) { 15201 swiper.setBreakpoint(); 15202 } 15203 15204 // Save locks 15205 const { 15206 allowSlideNext, 15207 allowSlidePrev, 15208 snapGrid 15209 } = swiper; 15210 const isVirtual = swiper.virtual && swiper.params.virtual.enabled; 15211 15212 // Disable locks on resize 15213 swiper.allowSlideNext = true; 15214 swiper.allowSlidePrev = true; 15215 swiper.updateSize(); 15216 swiper.updateSlides(); 15217 swiper.updateSlidesClasses(); 15218 const isVirtualLoop = isVirtual && params.loop; 15219 if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides && !isVirtualLoop) { 15220 swiper.slideTo(swiper.slides.length - 1, 0, false, true); 15221 } else { 15222 if (swiper.params.loop && !isVirtual) { 15223 swiper.slideToLoop(swiper.realIndex, 0, false, true); 15224 } else { 15225 swiper.slideTo(swiper.activeIndex, 0, false, true); 15226 } 15227 } 15228 if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) { 15229 clearTimeout(swiper.autoplay.resizeTimeout); 15230 swiper.autoplay.resizeTimeout = setTimeout(() => { 15231 if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) { 15232 swiper.autoplay.resume(); 15233 } 15234 }, 500); 15235 } 15236 // Return locks after resize 15237 swiper.allowSlidePrev = allowSlidePrev; 15238 swiper.allowSlideNext = allowSlideNext; 15239 if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) { 15240 swiper.checkOverflow(); 15241 } 15242} 15243 15244function onClick(e) { 15245 const swiper = this; 15246 if (!swiper.enabled) return; 15247 if (!swiper.allowClick) { 15248 if (swiper.params.preventClicks) e.preventDefault(); 15249 if (swiper.params.preventClicksPropagation && swiper.animating) { 15250 e.stopPropagation(); 15251 e.stopImmediatePropagation(); 15252 } 15253 } 15254} 15255 15256function onScroll() { 15257 const swiper = this; 15258 const { 15259 wrapperEl, 15260 rtlTranslate, 15261 enabled 15262 } = swiper; 15263 if (!enabled) return; 15264 swiper.previousTranslate = swiper.translate; 15265 if (swiper.isHorizontal()) { 15266 swiper.translate = -wrapperEl.scrollLeft; 15267 } else { 15268 swiper.translate = -wrapperEl.scrollTop; 15269 } 15270 // eslint-disable-next-line 15271 if (swiper.translate === 0) swiper.translate = 0; 15272 swiper.updateActiveIndex(); 15273 swiper.updateSlidesClasses(); 15274 let newProgress; 15275 const translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); 15276 if (translatesDiff === 0) { 15277 newProgress = 0; 15278 } else { 15279 newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff; 15280 } 15281 if (newProgress !== swiper.progress) { 15282 swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate); 15283 } 15284 swiper.emit('setTranslate', swiper.translate, false); 15285} 15286 15287function onLoad(e) { 15288 const swiper = this; 15289 processLazyPreloader(swiper, e.target); 15290 if (swiper.params.cssMode || swiper.params.slidesPerView !== 'auto' && !swiper.params.autoHeight) { 15291 return; 15292 } 15293 swiper.update(); 15294} 15295 15296function onDocumentTouchStart() { 15297 const swiper = this; 15298 if (swiper.documentTouchHandlerProceeded) return; 15299 swiper.documentTouchHandlerProceeded = true; 15300 if (swiper.params.touchReleaseOnEdges) { 15301 swiper.el.style.touchAction = 'auto'; 15302 } 15303} 15304 15305const events = (swiper, method) => { 15306 const document = ssr_window_esm_getDocument(); 15307 const { 15308 params, 15309 el, 15310 wrapperEl, 15311 device 15312 } = swiper; 15313 const capture = !!params.nested; 15314 const domMethod = method === 'on' ? 'addEventListener' : 'removeEventListener'; 15315 const swiperMethod = method; 15316 if (!el || typeof el === 'string') return; 15317 15318 // Touch Events 15319 document[domMethod]('touchstart', swiper.onDocumentTouchStart, { 15320 passive: false, 15321 capture 15322 }); 15323 el[domMethod]('touchstart', swiper.onTouchStart, { 15324 passive: false 15325 }); 15326 el[domMethod]('pointerdown', swiper.onTouchStart, { 15327 passive: false 15328 }); 15329 document[domMethod]('touchmove', swiper.onTouchMove, { 15330 passive: false, 15331 capture 15332 }); 15333 document[domMethod]('pointermove', swiper.onTouchMove, { 15334 passive: false, 15335 capture 15336 }); 15337 document[domMethod]('touchend', swiper.onTouchEnd, { 15338 passive: true 15339 }); 15340 document[domMethod]('pointerup', swiper.onTouchEnd, { 15341 passive: true 15342 }); 15343 document[domMethod]('pointercancel', swiper.onTouchEnd, { 15344 passive: true 15345 }); 15346 document[domMethod]('touchcancel', swiper.onTouchEnd, { 15347 passive: true 15348 }); 15349 document[domMethod]('pointerout', swiper.onTouchEnd, { 15350 passive: true 15351 }); 15352 document[domMethod]('pointerleave', swiper.onTouchEnd, { 15353 passive: true 15354 }); 15355 document[domMethod]('contextmenu', swiper.onTouchEnd, { 15356 passive: true 15357 }); 15358 15359 // Prevent Links Clicks 15360 if (params.preventClicks || params.preventClicksPropagation) { 15361 el[domMethod]('click', swiper.onClick, true); 15362 } 15363 if (params.cssMode) { 15364 wrapperEl[domMethod]('scroll', swiper.onScroll); 15365 } 15366 15367 // Resize handler 15368 if (params.updateOnWindowResize) { 15369 swiper[swiperMethod](device.ios || device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate', onResize, true); 15370 } else { 15371 swiper[swiperMethod]('observerUpdate', onResize, true); 15372 } 15373 15374 // Images loader 15375 el[domMethod]('load', swiper.onLoad, { 15376 capture: true 15377 }); 15378}; 15379function attachEvents() { 15380 const swiper = this; 15381 const { 15382 params 15383 } = swiper; 15384 swiper.onTouchStart = onTouchStart.bind(swiper); 15385 swiper.onTouchMove = onTouchMove.bind(swiper); 15386 swiper.onTouchEnd = onTouchEnd.bind(swiper); 15387 swiper.onDocumentTouchStart = onDocumentTouchStart.bind(swiper); 15388 if (params.cssMode) { 15389 swiper.onScroll = onScroll.bind(swiper); 15390 } 15391 swiper.onClick = onClick.bind(swiper); 15392 swiper.onLoad = onLoad.bind(swiper); 15393 events(swiper, 'on'); 15394} 15395function detachEvents() { 15396 const swiper = this; 15397 events(swiper, 'off'); 15398} 15399var events$1 = { 15400 attachEvents, 15401 detachEvents 15402}; 15403 15404const isGridEnabled = (swiper, params) => { 15405 return swiper.grid && params.grid && params.grid.rows > 1; 15406}; 15407function setBreakpoint() { 15408 const swiper = this; 15409 const { 15410 realIndex, 15411 initialized, 15412 params, 15413 el 15414 } = swiper; 15415 const breakpoints = params.breakpoints; 15416 if (!breakpoints || breakpoints && Object.keys(breakpoints).length === 0) return; 15417 const document = ssr_window_esm_getDocument(); 15418 15419 // Get breakpoint for window/container width and update parameters 15420 const breakpointsBase = params.breakpointsBase === 'window' || !params.breakpointsBase ? params.breakpointsBase : 'container'; 15421 const breakpointContainer = ['window', 'container'].includes(params.breakpointsBase) || !params.breakpointsBase ? swiper.el : document.querySelector(params.breakpointsBase);
vendor: 4,153 bytes, lines 15422-15535
15422 const breakpoint = swiper.getBreakpoint(breakpoints, breakpointsBase, breakpointContainer); 15423 if (!breakpoint || swiper.currentBreakpoint === breakpoint) return; 15424 const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined; 15425 const breakpointParams = breakpointOnlyParams || swiper.originalParams; 15426 const wasMultiRow = isGridEnabled(swiper, params); 15427 const isMultiRow = isGridEnabled(swiper, breakpointParams); 15428 const wasGrabCursor = swiper.params.grabCursor; 15429 const isGrabCursor = breakpointParams.grabCursor; 15430 const wasEnabled = params.enabled; 15431 if (wasMultiRow && !isMultiRow) { 15432 el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`); 15433 swiper.emitContainerClasses(); 15434 } else if (!wasMultiRow && isMultiRow) { 15435 el.classList.add(`${params.containerModifierClass}grid`); 15436 if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') { 15437 el.classList.add(`${params.containerModifierClass}grid-column`); 15438 } 15439 swiper.emitContainerClasses(); 15440 } 15441 if (wasGrabCursor && !isGrabCursor) { 15442 swiper.unsetGrabCursor(); 15443 } else if (!wasGrabCursor && isGrabCursor) { 15444 swiper.setGrabCursor(); 15445 } 15446 15447 // Toggle navigation, pagination, scrollbar 15448 ['navigation', 'pagination', 'scrollbar'].forEach(prop => { 15449 if (typeof breakpointParams[prop] === 'undefined') return; 15450 const wasModuleEnabled = params[prop] && params[prop].enabled; 15451 const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled; 15452 if (wasModuleEnabled && !isModuleEnabled) { 15453 swiper[prop].disable(); 15454 } 15455 if (!wasModuleEnabled && isModuleEnabled) { 15456 swiper[prop].enable(); 15457 } 15458 }); 15459 const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction; 15460 const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged); 15461 const wasLoop = params.loop; 15462 if (directionChanged && initialized) { 15463 swiper.changeDirection(); 15464 } 15465 utils_extend(swiper.params, breakpointParams); 15466 const isEnabled = swiper.params.enabled; 15467 const hasLoop = swiper.params.loop; 15468 Object.assign(swiper, { 15469 allowTouchMove: swiper.params.allowTouchMove, 15470 allowSlideNext: swiper.params.allowSlideNext, 15471 allowSlidePrev: swiper.params.allowSlidePrev 15472 }); 15473 if (wasEnabled && !isEnabled) { 15474 swiper.disable(); 15475 } else if (!wasEnabled && isEnabled) { 15476 swiper.enable(); 15477 } 15478 swiper.currentBreakpoint = breakpoint; 15479 swiper.emit('_beforeBreakpoint', breakpointParams); 15480 if (initialized) { 15481 if (needsReLoop) { 15482 swiper.loopDestroy(); 15483 swiper.loopCreate(realIndex); 15484 swiper.updateSlides(); 15485 } else if (!wasLoop && hasLoop) { 15486 swiper.loopCreate(realIndex); 15487 swiper.updateSlides(); 15488 } else if (wasLoop && !hasLoop) { 15489 swiper.loopDestroy(); 15490 } 15491 } 15492 swiper.emit('breakpoint', breakpointParams); 15493} 15494 15495function getBreakpoint(breakpoints, base, containerEl) { 15496 if (base === void 0) { 15497 base = 'window'; 15498 } 15499 if (!breakpoints || base === 'container' && !containerEl) return undefined; 15500 let breakpoint = false; 15501 const window = ssr_window_esm_getWindow(); 15502 const currentHeight = base === 'window' ? window.innerHeight : containerEl.clientHeight; 15503 const points = Object.keys(breakpoints).map(point => { 15504 if (typeof point === 'string' && point.indexOf('@') === 0) { 15505 const minRatio = parseFloat(point.substr(1)); 15506 const value = currentHeight * minRatio; 15507 return { 15508 value, 15509 point 15510 }; 15511 } 15512 return { 15513 value: point, 15514 point 15515 }; 15516 }); 15517 points.sort((a, b) => parseInt(a.value, 10) - parseInt(b.value, 10)); 15518 for (let i = 0; i < points.length; i += 1) { 15519 const { 15520 point, 15521 value 15522 } = points[i]; 15523 if (base === 'window') { 15524 if (window.matchMedia(`(min-width: ${value}px)`).matches) { 15525 breakpoint = point; 15526 } 15527 } else if (value <= containerEl.clientWidth) { 15528 breakpoint = point; 15529 } 15530 } 15531 return breakpoint || 'max'; 15532} 15533 15534var breakpoints = { 15535 setBreakpoint,
vendor: 14,757 bytes, lines 15536-16064
15536 getBreakpoint 15537}; 15538 15539function prepareClasses(entries, prefix) { 15540 const resultClasses = []; 15541 entries.forEach(item => { 15542 if (typeof item === 'object') { 15543 Object.keys(item).forEach(classNames => { 15544 if (item[classNames]) { 15545 resultClasses.push(prefix + classNames); 15546 } 15547 }); 15548 } else if (typeof item === 'string') { 15549 resultClasses.push(prefix + item); 15550 } 15551 }); 15552 return resultClasses; 15553} 15554function addClasses() { 15555 const swiper = this; 15556 const { 15557 classNames, 15558 params, 15559 rtl, 15560 el, 15561 device 15562 } = swiper; 15563 // prettier-ignore 15564 const suffixes = prepareClasses(['initialized', params.direction, { 15565 'free-mode': swiper.params.freeMode && params.freeMode.enabled 15566 }, { 15567 'autoheight': params.autoHeight 15568 }, { 15569 'rtl': rtl 15570 }, { 15571 'grid': params.grid && params.grid.rows > 1 15572 }, { 15573 'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column' 15574 }, { 15575 'android': device.android 15576 }, { 15577 'ios': device.ios 15578 }, { 15579 'css-mode': params.cssMode 15580 }, { 15581 'centered': params.cssMode && params.centeredSlides 15582 }, { 15583 'watch-progress': params.watchSlidesProgress 15584 }], params.containerModifierClass); 15585 classNames.push(...suffixes); 15586 el.classList.add(...classNames); 15587 swiper.emitContainerClasses(); 15588} 15589 15590function removeClasses() { 15591 const swiper = this; 15592 const { 15593 el, 15594 classNames 15595 } = swiper; 15596 if (!el || typeof el === 'string') return; 15597 el.classList.remove(...classNames); 15598 swiper.emitContainerClasses(); 15599} 15600 15601var classes = { 15602 addClasses, 15603 removeClasses 15604}; 15605 15606function checkOverflow() { 15607 const swiper = this; 15608 const { 15609 isLocked: wasLocked, 15610 params 15611 } = swiper; 15612 const { 15613 slidesOffsetBefore 15614 } = params; 15615 if (slidesOffsetBefore) { 15616 const lastSlideIndex = swiper.slides.length - 1; 15617 const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] + slidesOffsetBefore * 2; 15618 swiper.isLocked = swiper.size > lastSlideRightEdge; 15619 } else { 15620 swiper.isLocked = swiper.snapGrid.length === 1; 15621 } 15622 if (params.allowSlideNext === true) { 15623 swiper.allowSlideNext = !swiper.isLocked; 15624 } 15625 if (params.allowSlidePrev === true) { 15626 swiper.allowSlidePrev = !swiper.isLocked; 15627 } 15628 if (wasLocked && wasLocked !== swiper.isLocked) { 15629 swiper.isEnd = false; 15630 } 15631 if (wasLocked !== swiper.isLocked) { 15632 swiper.emit(swiper.isLocked ? 'lock' : 'unlock'); 15633 } 15634} 15635var checkOverflow$1 = { 15636 checkOverflow 15637}; 15638 15639var defaults = { 15640 init: true, 15641 direction: 'horizontal', 15642 oneWayMovement: false, 15643 swiperElementNodeName: 'SWIPER-CONTAINER', 15644 touchEventsTarget: 'wrapper', 15645 initialSlide: 0, 15646 speed: 300, 15647 cssMode: false, 15648 updateOnWindowResize: true, 15649 resizeObserver: true, 15650 nested: false, 15651 createElements: false, 15652 eventsPrefix: 'swiper', 15653 enabled: true, 15654 focusableElements: 'input, select, option, textarea, button, video, label', 15655 // Overrides 15656 width: null, 15657 height: null, 15658 // 15659 preventInteractionOnTransition: false, 15660 // ssr 15661 userAgent: null, 15662 url: null, 15663 // To support iOS's swipe-to-go-back gesture (when being used in-app). 15664 edgeSwipeDetection: false, 15665 edgeSwipeThreshold: 20, 15666 // Autoheight 15667 autoHeight: false, 15668 // Set wrapper width 15669 setWrapperSize: false, 15670 // Virtual Translate 15671 virtualTranslate: false, 15672 // Effects 15673 effect: 'slide', 15674 // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip' 15675 15676 // Breakpoints 15677 breakpoints: undefined, 15678 breakpointsBase: 'window', 15679 // Slides grid 15680 spaceBetween: 0, 15681 slidesPerView: 1, 15682 slidesPerGroup: 1, 15683 slidesPerGroupSkip: 0, 15684 slidesPerGroupAuto: false, 15685 centeredSlides: false, 15686 centeredSlidesBounds: false, 15687 slidesOffsetBefore: 0, 15688 // in px 15689 slidesOffsetAfter: 0, 15690 // in px 15691 normalizeSlideIndex: true, 15692 centerInsufficientSlides: false, 15693 // Disable swiper and hide navigation when container not overflow 15694 watchOverflow: true, 15695 // Round length 15696 roundLengths: false, 15697 // Touches 15698 touchRatio: 1, 15699 touchAngle: 45, 15700 simulateTouch: true, 15701 shortSwipes: true, 15702 longSwipes: true, 15703 longSwipesRatio: 0.5, 15704 longSwipesMs: 300, 15705 followFinger: true, 15706 allowTouchMove: true, 15707 threshold: 5, 15708 touchMoveStopPropagation: false, 15709 touchStartPreventDefault: true, 15710 touchStartForcePreventDefault: false, 15711 touchReleaseOnEdges: false, 15712 // Unique Navigation Elements 15713 uniqueNavElements: true, 15714 // Resistance 15715 resistance: true, 15716 resistanceRatio: 0.85, 15717 // Progress 15718 watchSlidesProgress: false, 15719 // Cursor 15720 grabCursor: false, 15721 // Clicks 15722 preventClicks: true, 15723 preventClicksPropagation: true, 15724 slideToClickedSlide: false, 15725 // loop 15726 loop: false, 15727 loopAddBlankSlides: true, 15728 loopAdditionalSlides: 0, 15729 loopPreventsSliding: true, 15730 // rewind 15731 rewind: false, 15732 // Swiping/no swiping 15733 allowSlidePrev: true, 15734 allowSlideNext: true, 15735 swipeHandler: null, 15736 // '.swipe-handler', 15737 noSwiping: true, 15738 noSwipingClass: 'swiper-no-swiping', 15739 noSwipingSelector: null, 15740 // Passive Listeners 15741 passiveListeners: true, 15742 maxBackfaceHiddenSlides: 10, 15743 // NS 15744 containerModifierClass: 'swiper-', 15745 // NEW 15746 slideClass: 'swiper-slide', 15747 slideBlankClass: 'swiper-slide-blank', 15748 slideActiveClass: 'swiper-slide-active', 15749 slideVisibleClass: 'swiper-slide-visible', 15750 slideFullyVisibleClass: 'swiper-slide-fully-visible', 15751 slideNextClass: 'swiper-slide-next', 15752 slidePrevClass: 'swiper-slide-prev', 15753 wrapperClass: 'swiper-wrapper', 15754 lazyPreloaderClass: 'swiper-lazy-preloader', 15755 lazyPreloadPrevNext: 0, 15756 // Callbacks 15757 runCallbacksOnInit: true, 15758 // Internals 15759 _emitClasses: false 15760}; 15761 15762function moduleExtendParams(params, allModulesParams) { 15763 return function extendParams(obj) { 15764 if (obj === void 0) { 15765 obj = {}; 15766 } 15767 const moduleParamName = Object.keys(obj)[0]; 15768 const moduleParams = obj[moduleParamName]; 15769 if (typeof moduleParams !== 'object' || moduleParams === null) { 15770 utils_extend(allModulesParams, obj); 15771 return; 15772 } 15773 if (params[moduleParamName] === true) { 15774 params[moduleParamName] = { 15775 enabled: true 15776 }; 15777 } 15778 if (moduleParamName === 'navigation' && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].prevEl && !params[moduleParamName].nextEl) { 15779 params[moduleParamName].auto = true; 15780 } 15781 if (['pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].el) { 15782 params[moduleParamName].auto = true; 15783 } 15784 if (!(moduleParamName in params && 'enabled' in moduleParams)) { 15785 utils_extend(allModulesParams, obj); 15786 return; 15787 } 15788 if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) { 15789 params[moduleParamName].enabled = true; 15790 } 15791 if (!params[moduleParamName]) params[moduleParamName] = { 15792 enabled: false 15793 }; 15794 utils_extend(allModulesParams, obj); 15795 }; 15796} 15797 15798/* eslint no-param-reassign: "off" */ 15799const prototypes = { 15800 eventsEmitter, 15801 update, 15802 translate, 15803 transition, 15804 slide, 15805 loop, 15806 grabCursor, 15807 events: events$1, 15808 breakpoints, 15809 checkOverflow: checkOverflow$1, 15810 classes 15811}; 15812const extendedDefaults = {}; 15813class Swiper { 15814 constructor() { 15815 let el; 15816 let params; 15817 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 15818 args[_key] = arguments[_key]; 15819 } 15820 if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) === 'Object') { 15821 params = args[0]; 15822 } else { 15823 [el, params] = args; 15824 } 15825 if (!params) params = {}; 15826 params = utils_extend({}, params); 15827 if (el && !params.el) params.el = el; 15828 const document = ssr_window_esm_getDocument(); 15829 if (params.el && typeof params.el === 'string' && document.querySelectorAll(params.el).length > 1) { 15830 const swipers = []; 15831 document.querySelectorAll(params.el).forEach(containerEl => { 15832 const newParams = utils_extend({}, params, { 15833 el: containerEl 15834 }); 15835 swipers.push(new Swiper(newParams)); 15836 }); 15837 // eslint-disable-next-line no-constructor-return 15838 return swipers; 15839 } 15840 15841 // Swiper Instance 15842 const swiper = this; 15843 swiper.__swiper__ = true; 15844 swiper.support = getSupport(); 15845 swiper.device = getDevice({ 15846 userAgent: params.userAgent 15847 }); 15848 swiper.browser = getBrowser(); 15849 swiper.eventsListeners = {}; 15850 swiper.eventsAnyListeners = []; 15851 swiper.modules = [...swiper.__modules__]; 15852 if (params.modules && Array.isArray(params.modules)) { 15853 swiper.modules.push(...params.modules); 15854 } 15855 const allModulesParams = {}; 15856 swiper.modules.forEach(mod => { 15857 mod({ 15858 params, 15859 swiper, 15860 extendParams: moduleExtendParams(params, allModulesParams), 15861 on: swiper.on.bind(swiper), 15862 once: swiper.once.bind(swiper), 15863 off: swiper.off.bind(swiper), 15864 emit: swiper.emit.bind(swiper) 15865 }); 15866 }); 15867 15868 // Extend defaults with modules params 15869 const swiperParams = utils_extend({}, defaults, allModulesParams); 15870 15871 // Extend defaults with passed params 15872 swiper.params = utils_extend({}, swiperParams, extendedDefaults, params); 15873 swiper.originalParams = utils_extend({}, swiper.params); 15874 swiper.passedParams = utils_extend({}, params); 15875 15876 // add event listeners 15877 if (swiper.params && swiper.params.on) { 15878 Object.keys(swiper.params.on).forEach(eventName => { 15879 swiper.on(eventName, swiper.params.on[eventName]); 15880 }); 15881 } 15882 if (swiper.params && swiper.params.onAny) { 15883 swiper.onAny(swiper.params.onAny); 15884 } 15885 15886 // Extend Swiper 15887 Object.assign(swiper, { 15888 enabled: swiper.params.enabled, 15889 el, 15890 // Classes 15891 classNames: [], 15892 // Slides 15893 slides: [], 15894 slidesGrid: [], 15895 snapGrid: [], 15896 slidesSizesGrid: [], 15897 // isDirection 15898 isHorizontal() { 15899 return swiper.params.direction === 'horizontal'; 15900 }, 15901 isVertical() { 15902 return swiper.params.direction === 'vertical'; 15903 }, 15904 // Indexes 15905 activeIndex: 0, 15906 realIndex: 0, 15907 // 15908 isBeginning: true, 15909 isEnd: false, 15910 // Props 15911 translate: 0, 15912 previousTranslate: 0, 15913 progress: 0, 15914 velocity: 0, 15915 animating: false, 15916 cssOverflowAdjustment() { 15917 // Returns 0 unless `translate` is > 2**23 15918 // Should be subtracted from css values to prevent overflow 15919 return Math.trunc(this.translate / 2 ** 23) * 2 ** 23; 15920 }, 15921 // Locks 15922 allowSlideNext: swiper.params.allowSlideNext, 15923 allowSlidePrev: swiper.params.allowSlidePrev, 15924 // Touch Events 15925 touchEventsData: { 15926 isTouched: undefined, 15927 isMoved: undefined, 15928 allowTouchCallbacks: undefined, 15929 touchStartTime: undefined, 15930 isScrolling: undefined, 15931 currentTranslate: undefined, 15932 startTranslate: undefined, 15933 allowThresholdMove: undefined, 15934 // Form elements to match 15935 focusableElements: swiper.params.focusableElements, 15936 // Last click time 15937 lastClickTime: 0, 15938 clickTimeout: undefined, 15939 // Velocities 15940 velocities: [], 15941 allowMomentumBounce: undefined, 15942 startMoving: undefined, 15943 pointerId: null, 15944 touchId: null 15945 }, 15946 // Clicks 15947 allowClick: true, 15948 // Touches 15949 allowTouchMove: swiper.params.allowTouchMove, 15950 touches: { 15951 startX: 0, 15952 startY: 0, 15953 currentX: 0, 15954 currentY: 0, 15955 diff: 0 15956 }, 15957 // Images 15958 imagesToLoad: [], 15959 imagesLoaded: 0 15960 }); 15961 swiper.emit('_swiper'); 15962 15963 // Init 15964 if (swiper.params.init) { 15965 swiper.init(); 15966 } 15967 15968 // Return app instance 15969 // eslint-disable-next-line no-constructor-return 15970 return swiper; 15971 } 15972 getDirectionLabel(property) { 15973 if (this.isHorizontal()) { 15974 return property; 15975 } 15976 // prettier-ignore 15977 return { 15978 'width': 'height', 15979 'margin-top': 'margin-left', 15980 'margin-bottom ': 'margin-right', 15981 'margin-left': 'margin-top', 15982 'margin-right': 'margin-bottom', 15983 'padding-left': 'padding-top', 15984 'padding-right': 'padding-bottom', 15985 'marginRight': 'marginBottom' 15986 }[property]; 15987 } 15988 getSlideIndex(slideEl) { 15989 const { 15990 slidesEl, 15991 params 15992 } = this; 15993 const slides = utils_elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`); 15994 const firstSlideIndex = utils_elementIndex(slides[0]); 15995 return utils_elementIndex(slideEl) - firstSlideIndex; 15996 } 15997 getSlideIndexByData(index) { 15998 return this.getSlideIndex(this.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === index)); 15999 } 16000 getSlideIndexWhenGrid(index) { 16001 if (this.grid && this.params.grid && this.params.grid.rows > 1) { 16002 if (this.params.grid.fill === 'column') { 16003 index = Math.floor(index / this.params.grid.rows); 16004 } else if (this.params.grid.fill === 'row') { 16005 index = index % Math.ceil(this.slides.length / this.params.grid.rows); 16006 } 16007 } 16008 return index; 16009 } 16010 recalcSlides() { 16011 const swiper = this; 16012 const { 16013 slidesEl, 16014 params 16015 } = swiper; 16016 swiper.slides = utils_elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`); 16017 } 16018 enable() { 16019 const swiper = this; 16020 if (swiper.enabled) return; 16021 swiper.enabled = true; 16022 if (swiper.params.grabCursor) { 16023 swiper.setGrabCursor(); 16024 } 16025 swiper.emit('enable'); 16026 } 16027 disable() { 16028 const swiper = this; 16029 if (!swiper.enabled) return; 16030 swiper.enabled = false; 16031 if (swiper.params.grabCursor) { 16032 swiper.unsetGrabCursor(); 16033 } 16034 swiper.emit('disable'); 16035 } 16036 setProgress(progress, speed) { 16037 const swiper = this; 16038 progress = Math.min(Math.max(progress, 0), 1); 16039 const min = swiper.minTranslate(); 16040 const max = swiper.maxTranslate(); 16041 const current = (max - min) * progress + min; 16042 swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed); 16043 swiper.updateActiveIndex(); 16044 swiper.updateSlidesClasses(); 16045 } 16046 emitContainerClasses() { 16047 const swiper = this; 16048 if (!swiper.params._emitClasses || !swiper.el) return; 16049 const cls = swiper.el.className.split(' ').filter(className => { 16050 return className.indexOf('swiper') === 0 || className.indexOf(swiper.params.containerModifierClass) === 0; 16051 }); 16052 swiper.emit('_containerClasses', cls.join(' ')); 16053 } 16054 getSlideClasses(slideEl) { 16055 const swiper = this; 16056 if (swiper.destroyed) return ''; 16057 return slideEl.className.split(' ').filter(className => { 16058 return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params.slideClass) === 0; 16059 }).join(' '); 16060 } 16061 emitSlidesClasses() { 16062 const swiper = this; 16063 if (!swiper.params._emitClasses || !swiper.el) return; 16064 const updates = [];
vendor: 4,378 bytes, lines 16065-16196
16065 swiper.slides.forEach(slideEl => { 16066 const classNames = swiper.getSlideClasses(slideEl); 16067 updates.push({ 16068 slideEl, 16069 classNames 16070 }); 16071 swiper.emit('_slideClass', slideEl, classNames); 16072 }); 16073 swiper.emit('_slideClasses', updates); 16074 } 16075 slidesPerViewDynamic(view, exact) { 16076 if (view === void 0) { 16077 view = 'current'; 16078 } 16079 if (exact === void 0) { 16080 exact = false; 16081 } 16082 const swiper = this; 16083 const { 16084 params, 16085 slides, 16086 slidesGrid, 16087 slidesSizesGrid, 16088 size: swiperSize, 16089 activeIndex 16090 } = swiper; 16091 let spv = 1; 16092 if (typeof params.slidesPerView === 'number') return params.slidesPerView; 16093 if (params.centeredSlides) { 16094 let slideSize = slides[activeIndex] ? Math.ceil(slides[activeIndex].swiperSlideSize) : 0; 16095 let breakLoop; 16096 for (let i = activeIndex + 1; i < slides.length; i += 1) { 16097 if (slides[i] && !breakLoop) { 16098 slideSize += Math.ceil(slides[i].swiperSlideSize); 16099 spv += 1; 16100 if (slideSize > swiperSize) breakLoop = true; 16101 } 16102 } 16103 for (let i = activeIndex - 1; i >= 0; i -= 1) { 16104 if (slides[i] && !breakLoop) { 16105 slideSize += slides[i].swiperSlideSize; 16106 spv += 1; 16107 if (slideSize > swiperSize) breakLoop = true; 16108 } 16109 } 16110 } else { 16111 // eslint-disable-next-line 16112 if (view === 'current') { 16113 for (let i = activeIndex + 1; i < slides.length; i += 1) { 16114 const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize; 16115 if (slideInView) { 16116 spv += 1; 16117 } 16118 } 16119 } else { 16120 // previous 16121 for (let i = activeIndex - 1; i >= 0; i -= 1) { 16122 const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize; 16123 if (slideInView) { 16124 spv += 1; 16125 } 16126 } 16127 } 16128 } 16129 return spv; 16130 } 16131 update() { 16132 const swiper = this; 16133 if (!swiper || swiper.destroyed) return; 16134 const { 16135 snapGrid, 16136 params 16137 } = swiper; 16138 // Breakpoints 16139 if (params.breakpoints) { 16140 swiper.setBreakpoint(); 16141 } 16142 [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach(imageEl => { 16143 if (imageEl.complete) { 16144 processLazyPreloader(swiper, imageEl); 16145 } 16146 }); 16147 swiper.updateSize(); 16148 swiper.updateSlides(); 16149 swiper.updateProgress(); 16150 swiper.updateSlidesClasses(); 16151 function setTranslate() { 16152 const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate; 16153 const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate()); 16154 swiper.setTranslate(newTranslate); 16155 swiper.updateActiveIndex(); 16156 swiper.updateSlidesClasses(); 16157 } 16158 let translated; 16159 if (params.freeMode && params.freeMode.enabled && !params.cssMode) { 16160 setTranslate(); 16161 if (params.autoHeight) { 16162 swiper.updateAutoHeight(); 16163 } 16164 } else { 16165 if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) { 16166 const slides = swiper.virtual && params.virtual.enabled ? swiper.virtual.slides : swiper.slides; 16167 translated = swiper.slideTo(slides.length - 1, 0, false, true); 16168 } else { 16169 translated = swiper.slideTo(swiper.activeIndex, 0, false, true); 16170 } 16171 if (!translated) { 16172 setTranslate(); 16173 } 16174 } 16175 if (params.watchOverflow && snapGrid !== swiper.snapGrid) { 16176 swiper.checkOverflow(); 16177 } 16178 swiper.emit('update'); 16179 } 16180 changeDirection(newDirection, needUpdate) { 16181 if (needUpdate === void 0) { 16182 needUpdate = true; 16183 } 16184 const swiper = this; 16185 const currentDirection = swiper.params.direction; 16186 if (!newDirection) { 16187 // eslint-disable-next-line 16188 newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal'; 16189 } 16190 if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') { 16191 return swiper; 16192 } 16193 swiper.el.classList.remove(`${swiper.params.containerModifierClass}${currentDirection}`); 16194 swiper.el.classList.add(`${swiper.params.containerModifierClass}${newDirection}`); 16195 swiper.emitContainerClasses(); 16196 swiper.params.direction = newDirection;
vendor: 1,995 bytes, lines 16197-16254
16197 swiper.slides.forEach(slideEl => { 16198 if (newDirection === 'vertical') { 16199 slideEl.style.width = ''; 16200 } else { 16201 slideEl.style.height = ''; 16202 } 16203 }); 16204 swiper.emit('changeDirection'); 16205 if (needUpdate) swiper.update(); 16206 return swiper; 16207 } 16208 changeLanguageDirection(direction) { 16209 const swiper = this; 16210 if (swiper.rtl && direction === 'rtl' || !swiper.rtl && direction === 'ltr') return; 16211 swiper.rtl = direction === 'rtl'; 16212 swiper.rtlTranslate = swiper.params.direction === 'horizontal' && swiper.rtl; 16213 if (swiper.rtl) { 16214 swiper.el.classList.add(`${swiper.params.containerModifierClass}rtl`); 16215 swiper.el.dir = 'rtl'; 16216 } else { 16217 swiper.el.classList.remove(`${swiper.params.containerModifierClass}rtl`); 16218 swiper.el.dir = 'ltr'; 16219 } 16220 swiper.update(); 16221 } 16222 mount(element) { 16223 const swiper = this; 16224 if (swiper.mounted) return true; 16225 16226 // Find el 16227 let el = element || swiper.params.el; 16228 if (typeof el === 'string') { 16229 el = document.querySelector(el); 16230 } 16231 if (!el) { 16232 return false; 16233 } 16234 el.swiper = swiper; 16235 if (el.parentNode && el.parentNode.host && el.parentNode.host.nodeName === swiper.params.swiperElementNodeName.toUpperCase()) { 16236 swiper.isElement = true; 16237 } 16238 const getWrapperSelector = () => { 16239 return `.${(swiper.params.wrapperClass || '').trim().split(' ').join('.')}`; 16240 }; 16241 const getWrapper = () => { 16242 if (el && el.shadowRoot && el.shadowRoot.querySelector) { 16243 const res = el.shadowRoot.querySelector(getWrapperSelector()); 16244 // Children needs to return slot items 16245 return res; 16246 } 16247 return utils_elementChildren(el, getWrapperSelector())[0]; 16248 }; 16249 // Find Wrapper 16250 let wrapperEl = getWrapper(); 16251 if (!wrapperEl && swiper.params.createElements) { 16252 wrapperEl = utils_createElement('div', swiper.params.wrapperClass); 16253 el.append(wrapperEl); 16254 utils_elementChildren(el, `.${swiper.params.slideClass}
16254`).forEach(slideEl => { 16255 wrapperEl.append(slideEl); 16256 }); 16257 } 16258 Object.assign(swiper, { 16259 el, 16260 wrapperEl, 16261 slidesEl: swiper.isElement && !el.parentNode.host.slideSlots ? el.parentNode.host : wrapperEl, 16262 hostEl: swiper.isElement ? el.parentNode.host : el, 16263 mounted: true, 16264 // RTL 16265 rtl: el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl', 16266 rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl'), 16267 wrongRTL: elementStyle(wrapperEl, 'display') === '-webkit-box' 16268 }); 16269 return true; 16270 } 16271 init(el) { 16272 const swiper = this; 16273 if (swiper.initialized) return swiper; 16274 const mounted = swiper.mount(el); 16275 if (mounted === false) return swiper; 16276 swiper.emit('beforeInit'); 16277 16278 // Set breakpoint 16279 if (swiper.params.breakpoints) { 16280 swiper.setBreakpoint(); 16281 } 16282 16283 // Add Classes 16284 swiper.addClasses(); 16285 16286 // Update size 16287 swiper.updateSize(); 16288 16289 // Update slides 16290 swiper.updateSlides(); 16291 if (swiper.params.watchOverflow) { 16292 swiper.checkOverflow(); 16293 } 16294 16295 // Set Grab Cursor 16296 if (swiper.params.grabCursor && swiper.enabled) { 16297 swiper.setGrabCursor(); 16298 } 16299 16300 // Slide To Initial Slide 16301 if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) { 16302 swiper.slideTo(swiper.params.initialSlide + swiper.virtual.slidesBefore, 0, swiper.params.runCallbacksOnInit, false, true); 16303 } else { 16304 swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true); 16305 } 16306 16307 // Create loop 16308 if (swiper.params.loop) { 16309 swiper.loopCreate(undefined, true); 16310 } 16311 16312 // Attach events 16313 swiper.attachEvents(); 16314 const lazyElements = [...swiper.el.querySelectorAll('[loading="lazy"]')]; 16315 if (swiper.isElement) { 16316 lazyElements.push(...swiper.hostEl.querySelectorAll('[loading="lazy"]')); 16317 } 16318 lazyElements.forEach(imageEl => { 16319 if (imageEl.complete) { 16320 processLazyPreloader(swiper, imageEl); 16321 } else { 16322 imageEl.addEventListener('load', e => { 16323 processLazyPreloader(swiper, e.target); 16324 }); 16325 } 16326 }); 16327 preload(swiper); 16328 16329 // Init Flag 16330 swiper.initialized = true; 16331 preload(swiper); 16332 16333 // Emit 16334 swiper.emit('init'); 16335 swiper.emit('afterInit'); 16336 return swiper; 16337 } 16338 destroy(deleteInstance, cleanStyles) { 16339 if (deleteInstance === void 0) { 16340 deleteInstance = true; 16341 } 16342 if (cleanStyles === void 0) { 16343 cleanStyles = true; 16344 } 16345 const swiper = this; 16346 const { 16347 params, 16348 el, 16349 wrapperEl, 16350 slides 16351 } = swiper; 16352 if (typeof swiper.params === 'undefined' || swiper.destroyed) { 16353 return null; 16354 } 16355 swiper.emit('beforeDestroy'); 16356 16357 // Init Flag 16358 swiper.initialized = false; 16359 16360 // Detach events 16361 swiper.detachEvents(); 16362 16363 // Destroy loop 16364 if (params.loop) { 16365 swiper.loopDestroy(); 16366 } 16367 16368 // Cleanup styles 16369 if (cleanStyles) { 16370 swiper.removeClasses(); 16371 if (el && typeof el !== 'string') { 16372 el.removeAttribute('style'); 16373 } 16374 if (wrapperEl) { 16375 wrapperEl.removeAttribute('style'); 16376 } 16377 if (slides && slides.length) {
vendor: 4,573 bytes, lines 16378-16545
16378 slides.forEach(slideEl => { 16379 slideEl.classList.remove(params.slideVisibleClass, params.slideFullyVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass); 16380 slideEl.removeAttribute('style'); 16381 slideEl.removeAttribute('data-swiper-slide-index'); 16382 }); 16383 } 16384 } 16385 swiper.emit('destroy'); 16386 16387 // Detach emitter events 16388 Object.keys(swiper.eventsListeners).forEach(eventName => { 16389 swiper.off(eventName); 16390 }); 16391 if (deleteInstance !== false) { 16392 if (swiper.el && typeof swiper.el !== 'string') { 16393 swiper.el.swiper = null; 16394 } 16395 deleteProps(swiper); 16396 } 16397 swiper.destroyed = true; 16398 return null; 16399 } 16400 static extendDefaults(newDefaults) { 16401 utils_extend(extendedDefaults, newDefaults); 16402 } 16403 static get extendedDefaults() { 16404 return extendedDefaults; 16405 } 16406 static get defaults() { 16407 return defaults; 16408 } 16409 static installModule(mod) { 16410 if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = []; 16411 const modules = Swiper.prototype.__modules__; 16412 if (typeof mod === 'function' && modules.indexOf(mod) < 0) { 16413 modules.push(mod); 16414 } 16415 } 16416 static use(module) { 16417 if (Array.isArray(module)) { 16418 module.forEach(m => Swiper.installModule(m)); 16419 return Swiper; 16420 } 16421 Swiper.installModule(module); 16422 return Swiper; 16423 } 16424} 16425Object.keys(prototypes).forEach(prototypeGroup => { 16426 Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => { 16427 Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod]; 16428 }); 16429}); 16430Swiper.use([Resize, Observer]); 16431 16432 16433 16434;// ./node_modules/swiper/swiper.mjs 16435/** 16436 * Swiper 11.2.10 16437 * Most modern mobile touch slider and framework with hardware accelerated transitions 16438 * https://swiperjs.com 16439 * 16440 * Copyright 2014-2025 Vladimir Kharlampidi 16441 * 16442 * Released under the MIT License 16443 * 16444 * Released on: June 28, 2025 16445 */ 16446 16447 16448 16449;// ./node_modules/swiper/modules/virtual.mjs 16450 16451 16452 16453function Virtual(_ref) { 16454 let { 16455 swiper, 16456 extendParams, 16457 on, 16458 emit 16459 } = _ref; 16460 extendParams({ 16461 virtual: { 16462 enabled: false, 16463 slides: [], 16464 cache: true, 16465 renderSlide: null, 16466 renderExternal: null, 16467 renderExternalUpdate: true, 16468 addSlidesBefore: 0, 16469 addSlidesAfter: 0 16470 } 16471 }); 16472 let cssModeTimeout; 16473 const document = getDocument(); 16474 swiper.virtual = { 16475 cache: {}, 16476 from: undefined, 16477 to: undefined, 16478 slides: [], 16479 offset: 0, 16480 slidesGrid: [] 16481 }; 16482 const tempDOM = document.createElement('div'); 16483 function renderSlide(slide, index) { 16484 const params = swiper.params.virtual; 16485 if (params.cache && swiper.virtual.cache[index]) { 16486 return swiper.virtual.cache[index]; 16487 } 16488 // eslint-disable-next-line 16489 let slideEl; 16490 if (params.renderSlide) { 16491 slideEl = params.renderSlide.call(swiper, slide, index); 16492 if (typeof slideEl === 'string') { 16493 setInnerHTML(tempDOM, slideEl); 16494 slideEl = tempDOM.children[0]; 16495 } 16496 } else if (swiper.isElement) { 16497 slideEl = createElement('swiper-slide'); 16498 } else { 16499 slideEl = createElement('div', swiper.params.slideClass); 16500 } 16501 slideEl.setAttribute('data-swiper-slide-index', index); 16502 if (!params.renderSlide) { 16503 setInnerHTML(slideEl, slide); 16504 } 16505 if (params.cache) { 16506 swiper.virtual.cache[index] = slideEl; 16507 } 16508 return slideEl; 16509 } 16510 function update(force, beforeInit, forceActiveIndex) { 16511 const { 16512 slidesPerView, 16513 slidesPerGroup, 16514 centeredSlides, 16515 loop: isLoop, 16516 initialSlide 16517 } = swiper.params; 16518 if (beforeInit && !isLoop && initialSlide > 0) { 16519 return; 16520 } 16521 const { 16522 addSlidesBefore, 16523 addSlidesAfter 16524 } = swiper.params.virtual; 16525 const { 16526 from: previousFrom, 16527 to: previousTo, 16528 slides, 16529 slidesGrid: previousSlidesGrid, 16530 offset: previousOffset 16531 } = swiper.virtual; 16532 if (!swiper.params.cssMode) { 16533 swiper.updateActiveIndex(); 16534 } 16535 const activeIndex = typeof forceActiveIndex === 'undefined' ? swiper.activeIndex || 0 : forceActiveIndex; 16536 let offsetProp; 16537 if (swiper.rtlTranslate) offsetProp = 'right';else offsetProp = swiper.isHorizontal() ? 'left' : 'top'; 16538 let slidesAfter; 16539 let slidesBefore; 16540 if (centeredSlides) { 16541 slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter; 16542 slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore; 16543 } else { 16544 slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter; 16545 slidesBefore = (isLoop ? slidesPerView
vendor: 3,781 bytes, lines 16545-16658
16545 : slidesPerGroup) + addSlidesBefore; 16546 } 16547 let from = activeIndex - slidesBefore; 16548 let to = activeIndex + slidesAfter; 16549 if (!isLoop) { 16550 from = Math.max(from, 0); 16551 to = Math.min(to, slides.length - 1); 16552 } 16553 let offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0); 16554 if (isLoop && activeIndex >= slidesBefore) { 16555 from -= slidesBefore; 16556 if (!centeredSlides) offset += swiper.slidesGrid[0]; 16557 } else if (isLoop && activeIndex < slidesBefore) { 16558 from = -slidesBefore; 16559 if (centeredSlides) offset += swiper.slidesGrid[0]; 16560 } 16561 Object.assign(swiper.virtual, { 16562 from, 16563 to, 16564 offset, 16565 slidesGrid: swiper.slidesGrid, 16566 slidesBefore, 16567 slidesAfter 16568 }); 16569 function onRendered() { 16570 swiper.updateSlides(); 16571 swiper.updateProgress(); 16572 swiper.updateSlidesClasses(); 16573 emit('virtualUpdate'); 16574 } 16575 if (previousFrom === from && previousTo === to && !force) { 16576 if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) { 16577 swiper.slides.forEach(slideEl => { 16578 slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`; 16579 }); 16580 } 16581 swiper.updateProgress(); 16582 emit('virtualUpdate'); 16583 return; 16584 } 16585 if (swiper.params.virtual.renderExternal) { 16586 swiper.params.virtual.renderExternal.call(swiper, { 16587 offset, 16588 from, 16589 to, 16590 slides: function getSlides() { 16591 const slidesToRender = []; 16592 for (let i = from; i <= to; i += 1) { 16593 slidesToRender.push(slides[i]); 16594 } 16595 return slidesToRender; 16596 }() 16597 }); 16598 if (swiper.params.virtual.renderExternalUpdate) { 16599 onRendered(); 16600 } else { 16601 emit('virtualUpdate'); 16602 } 16603 return; 16604 } 16605 const prependIndexes = []; 16606 const appendIndexes = []; 16607 const getSlideIndex = index => { 16608 let slideIndex = index; 16609 if (index < 0) { 16610 slideIndex = slides.length + index; 16611 } else if (slideIndex >= slides.length) { 16612 // eslint-disable-next-line 16613 slideIndex = slideIndex - slides.length; 16614 } 16615 return slideIndex; 16616 }; 16617 if (force) { 16618 swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`)).forEach(slideEl => { 16619 slideEl.remove(); 16620 }); 16621 } else { 16622 for (let i = previousFrom; i <= previousTo; i += 1) { 16623 if (i < from || i > to) { 16624 const slideIndex = getSlideIndex(i); 16625 swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}[data-swiper-slide-index="${slideIndex}"], swiper-slide[data-swiper-slide-index="${slideIndex}"]`)).forEach(slideEl => { 16626 slideEl.remove(); 16627 }); 16628 } 16629 } 16630 } 16631 const loopFrom = isLoop ? -slides.length : 0; 16632 const loopTo = isLoop ? slides.length * 2 : slides.length; 16633 for (let i = loopFrom; i < loopTo; i += 1) { 16634 if (i >= from && i <= to) { 16635 const slideIndex = getSlideIndex(i); 16636 if (typeof previousTo === 'undefined' || force) { 16637 appendIndexes.push(slideIndex); 16638 } else { 16639 if (i > previousTo) appendIndexes.push(slideIndex); 16640 if (i < previousFrom) prependIndexes.push(slideIndex); 16641 } 16642 } 16643 } 16644 appendIndexes.forEach(index => { 16645 swiper.slidesEl.append(renderSlide(slides[index], index)); 16646 }); 16647 if (isLoop) { 16648 for (let i = prependIndexes.length - 1; i >= 0; i -= 1) { 16649 const index = prependIndexes[i]; 16650 swiper.slidesEl.prepend(renderSlide(slides[index], index)); 16651 } 16652 } else { 16653 prependIndexes.sort((a, b) => b - a); 16654 prependIndexes.forEach(index => { 16655 swiper.slidesEl.prepend(renderSlide(slides[index], index)); 16656 }); 16657 } 16658
16658elementChildren(swiper.slidesEl, '.swiper-slide, swiper-slide').forEach(sli
vendor: 38,634 bytes, lines 16658-17745
16658deEl => { 16659 slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`; 16660 }); 16661 onRendered(); 16662 } 16663 function appendSlide(slides) { 16664 if (typeof slides === 'object' && 'length' in slides) { 16665 for (let i = 0; i < slides.length; i += 1) { 16666 if (slides[i]) swiper.virtual.slides.push(slides[i]); 16667 } 16668 } else { 16669 swiper.virtual.slides.push(slides); 16670 } 16671 update(true); 16672 } 16673 function prependSlide(slides) { 16674 const activeIndex = swiper.activeIndex; 16675 let newActiveIndex = activeIndex + 1; 16676 let numberOfNewSlides = 1; 16677 if (Array.isArray(slides)) { 16678 for (let i = 0; i < slides.length; i += 1) { 16679 if (slides[i]) swiper.virtual.slides.unshift(slides[i]); 16680 } 16681 newActiveIndex = activeIndex + slides.length; 16682 numberOfNewSlides = slides.length; 16683 } else { 16684 swiper.virtual.slides.unshift(slides); 16685 } 16686 if (swiper.params.virtual.cache) { 16687 const cache = swiper.virtual.cache; 16688 const newCache = {}; 16689 Object.keys(cache).forEach(cachedIndex => { 16690 const cachedEl = cache[cachedIndex]; 16691 const cachedElIndex = cachedEl.getAttribute('data-swiper-slide-index'); 16692 if (cachedElIndex) { 16693 cachedEl.setAttribute('data-swiper-slide-index', parseInt(cachedElIndex, 10) + numberOfNewSlides); 16694 } 16695 newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cachedEl; 16696 }); 16697 swiper.virtual.cache = newCache; 16698 } 16699 update(true); 16700 swiper.slideTo(newActiveIndex, 0); 16701 } 16702 function removeSlide(slidesIndexes) { 16703 if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return; 16704 let activeIndex = swiper.activeIndex; 16705 if (Array.isArray(slidesIndexes)) { 16706 for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) { 16707 if (swiper.params.virtual.cache) { 16708 delete swiper.virtual.cache[slidesIndexes[i]]; 16709 // shift cache indexes 16710 Object.keys(swiper.virtual.cache).forEach(key => { 16711 if (key > slidesIndexes) { 16712 swiper.virtual.cache[key - 1] = swiper.virtual.cache[key]; 16713 swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1); 16714 delete swiper.virtual.cache[key]; 16715 } 16716 }); 16717 } 16718 swiper.virtual.slides.splice(slidesIndexes[i], 1); 16719 if (slidesIndexes[i] < activeIndex) activeIndex -= 1; 16720 activeIndex = Math.max(activeIndex, 0); 16721 } 16722 } else { 16723 if (swiper.params.virtual.cache) { 16724 delete swiper.virtual.cache[slidesIndexes]; 16725 // shift cache indexes 16726 Object.keys(swiper.virtual.cache).forEach(key => { 16727 if (key > slidesIndexes) { 16728 swiper.virtual.cache[key - 1] = swiper.virtual.cache[key]; 16729 swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1); 16730 delete swiper.virtual.cache[key]; 16731 } 16732 }); 16733 } 16734 swiper.virtual.slides.splice(slidesIndexes, 1); 16735 if (slidesIndexes < activeIndex) activeIndex -= 1; 16736 activeIndex = Math.max(activeIndex, 0); 16737 } 16738 update(true); 16739 swiper.slideTo(activeIndex, 0); 16740 } 16741 function removeAllSlides() { 16742 swiper.virtual.slides = []; 16743 if (swiper.params.virtual.cache) { 16744 swiper.virtual.cache = {}; 16745 } 16746 update(true); 16747 swiper.slideTo(0, 0); 16748 } 16749 on('beforeInit', () => { 16750 if (!swiper.params.virtual.enabled) return; 16751 let domSlidesAssigned; 16752 if (typeof swiper.passedParams.virtual.slides === 'undefined') { 16753 const slides = [...swiper.slidesEl.children].filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`)); 16754 if (slides && slides.length) { 16755 swiper.virtual.slides = [...slides]; 16756 domSlidesAssigned = true; 16757 slides.forEach((slideEl, slideIndex) => { 16758 slideEl.setAttribute('data-swiper-slide-index', slideIndex); 16759 swiper.virtual.cache[slideIndex] = slideEl; 16760 slideEl.remove(); 16761 }); 16762 } 16763 } 16764 if (!domSlidesAssigned) { 16765 swiper.virtual.slides = swiper.params.virtual.slides; 16766 } 16767 swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`); 16768 swiper.params.watchSlidesProgress = true; 16769 swiper.originalParams.watchSlidesProgress = true; 16770 update(false, true); 16771 }); 16772 on('setTranslate', () => { 16773 if (!swiper.params.virtual.enabled) return; 16774 if (swiper.params.cssMode && !swiper._immediateVirtual) { 16775 clearTimeout(cssModeTimeout); 16776 cssModeTimeout = setTimeout(() => { 16777 update(); 16778 }, 100); 16779 } else { 16780 update(); 16781 } 16782 }); 16783 on('init update resize', () => { 16784 if (!swiper.params.virtual.enabled) return; 16785 if (swiper.params.cssMode) { 16786 setCSSProperty(swiper.wrapperEl, '--swiper-virtual-size', `${swiper.virtualSize}px`); 16787 } 16788 }); 16789 Object.assign(swiper.virtual, { 16790 appendSlide, 16791 prependSlide, 16792 removeSlide, 16793 removeAllSlides, 16794 update 16795 }); 16796} 16797 16798 16799 16800;// ./node_modules/swiper/modules/keyboard.mjs 16801 16802 16803 16804/* eslint-disable consistent-return */ 16805function Keyboard(_ref) { 16806 let { 16807 swiper, 16808 extendParams, 16809 on, 16810 emit 16811 } = _ref; 16812 const document = getDocument(); 16813 const window = getWindow(); 16814 swiper.keyboard = { 16815 enabled: false 16816 }; 16817 extendParams({ 16818 keyboard: { 16819 enabled: false, 16820 onlyInViewport: true, 16821 pageUpDown: true 16822 } 16823 }); 16824 function handle(event) { 16825 if (!swiper.enabled) return; 16826 const { 16827 rtlTranslate: rtl 16828 } = swiper; 16829 let e = event; 16830 if (e.originalEvent) e = e.originalEvent; // jquery fix 16831 const kc = e.keyCode || e.charCode; 16832 const pageUpDown = swiper.params.keyboard.pageUpDown; 16833 const isPageUp = pageUpDown && kc === 33; 16834 const isPageDown = pageUpDown && kc === 34; 16835 const isArrowLeft = kc === 37; 16836 const isArrowRight = kc === 39; 16837 const isArrowUp = kc === 38; 16838 const isArrowDown = kc === 40; 16839 // Directions locks 16840 if (!swiper.allowSlideNext && (swiper.isHorizontal() && isArrowRight || swiper.isVertical() && isArrowDown || isPageDown)) { 16841 return false; 16842 } 16843 if (!swiper.allowSlidePrev && (swiper.isHorizontal() && isArrowLeft || swiper.isVertical() && isArrowUp || isPageUp)) { 16844 return false; 16845 } 16846 if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { 16847 return undefined; 16848 } 16849 if (document.activeElement && (document.activeElement.isContentEditable || document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea'))) { 16850 return undefined; 16851 } 16852 if (swiper.params.keyboard.onlyInViewport && (isPageUp || isPageDown || isArrowLeft || isArrowRight || isArrowUp || isArrowDown)) { 16853 let inView = false; 16854 // Check that swiper should be inside of visible area of window 16855 if (elementParents(swiper.el, `.${swiper.params.slideClass}, swiper-slide`).length > 0 && elementParents(swiper.el, `.${swiper.params.slideActiveClass}`).length === 0) { 16856 return undefined; 16857 } 16858 const el = swiper.el; 16859 const swiperWidth = el.clientWidth; 16860 const swiperHeight = el.clientHeight; 16861 const windowWidth = window.innerWidth; 16862 const windowHeight = window.innerHeight; 16863 const swiperOffset = elementOffset(el); 16864 if (rtl) swiperOffset.left -= el.scrollLeft; 16865 const swiperCoord = [[swiperOffset.left, swiperOffset.top], [swiperOffset.left + swiperWidth, swiperOffset.top], [swiperOffset.left, swiperOffset.top + swiperHeight], [swiperOffset.left + swiperWidth, swiperOffset.top + swiperHeight]]; 16866 for (let i = 0; i < swiperCoord.length; i += 1) { 16867 const point = swiperCoord[i]; 16868 if (point[0] >= 0 && point[0] <= windowWidth && point[1] >= 0 && point[1] <= windowHeight) { 16869 if (point[0] === 0 && point[1] === 0) continue; // eslint-disable-line 16870 inView = true; 16871 } 16872 } 16873 if (!inView) return undefined; 16874 } 16875 if (swiper.isHorizontal()) { 16876 if (isPageUp || isPageDown || isArrowLeft || isArrowRight) { 16877 if (e.preventDefault) e.preventDefault();else e.returnValue = false; 16878 } 16879 if ((isPageDown || isArrowRight) && !rtl || (isPageUp || isArrowLeft) && rtl) swiper.slideNext(); 16880 if ((isPageUp || isArrowLeft) && !rtl || (isPageDown || isArrowRight) && rtl) swiper.slidePrev(); 16881 } else { 16882 if (isPageUp || isPageDown || isArrowUp || isArrowDown) { 16883 if (e.preventDefault) e.preventDefault();else e.returnValue = false; 16884 } 16885 if (isPageDown || isArrowDown) swiper.slideNext(); 16886 if (isPageUp || isArrowUp) swiper.slidePrev(); 16887 } 16888 emit('keyPress', kc); 16889 return undefined; 16890 } 16891 function enable() { 16892 if (swiper.keyboard.enabled) return; 16893 document.addEventListener('keydown', handle); 16894 swiper.keyboard.enabled = true; 16895 } 16896 function disable() { 16897 if (!swiper.keyboard.enabled) return; 16898 document.removeEventListener('keydown', handle); 16899 swiper.keyboard.enabled = false; 16900 } 16901 on('init', () => { 16902 if (swiper.params.keyboard.enabled) { 16903 enable(); 16904 } 16905 }); 16906 on('destroy', () => { 16907 if (swiper.keyboard.enabled) { 16908 disable(); 16909 } 16910 }); 16911 Object.assign(swiper.keyboard, { 16912 enable, 16913 disable 16914 }); 16915} 16916 16917 16918 16919;// ./node_modules/swiper/modules/mousewheel.mjs 16920 16921 16922 16923/* eslint-disable consistent-return */ 16924function Mousewheel(_ref) { 16925 let { 16926 swiper, 16927 extendParams, 16928 on, 16929 emit 16930 } = _ref; 16931 const window = getWindow(); 16932 extendParams({ 16933 mousewheel: { 16934 enabled: false, 16935 releaseOnEdges: false, 16936 invert: false, 16937 forceToAxis: false, 16938 sensitivity: 1, 16939 eventsTarget: 'container', 16940 thresholdDelta: null, 16941 thresholdTime: null, 16942 noMousewheelClass: 'swiper-no-mousewheel' 16943 } 16944 }); 16945 swiper.mousewheel = { 16946 enabled: false 16947 }; 16948 let timeout; 16949 let lastScrollTime = now(); 16950 let lastEventBeforeSnap; 16951 const recentWheelEvents = []; 16952 function normalize(e) { 16953 // Reasonable defaults 16954 const PIXEL_STEP = 10; 16955 const LINE_HEIGHT = 40; 16956 const PAGE_HEIGHT = 800; 16957 let sX = 0; 16958 let sY = 0; // spinX, spinY 16959 let pX = 0; 16960 let pY = 0; // pixelX, pixelY 16961 16962 // Legacy 16963 if ('detail' in e) { 16964 sY = e.detail; 16965 } 16966 if ('wheelDelta' in e) { 16967 sY = -e.wheelDelta / 120; 16968 } 16969 if ('wheelDeltaY' in e) { 16970 sY = -e.wheelDeltaY / 120; 16971 } 16972 if ('wheelDeltaX' in e) { 16973 sX = -e.wheelDeltaX / 120; 16974 } 16975 16976 // side scrolling on FF with DOMMouseScroll 16977 if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) { 16978 sX = sY; 16979 sY = 0; 16980 } 16981 pX = sX * PIXEL_STEP; 16982 pY = sY * PIXEL_STEP; 16983 if ('deltaY' in e) { 16984 pY = e.deltaY; 16985 } 16986 if ('deltaX' in e) { 16987 pX = e.deltaX; 16988 } 16989 if (e.shiftKey && !pX) { 16990 // if user scrolls with shift he wants horizontal scroll 16991 pX = pY; 16992 pY = 0; 16993 } 16994 if ((pX || pY) && e.deltaMode) { 16995 if (e.deltaMode === 1) { 16996 // delta in LINE units 16997 pX *= LINE_HEIGHT; 16998 pY *= LINE_HEIGHT; 16999 } else { 17000 // delta in PAGE units 17001 pX *= PAGE_HEIGHT; 17002 pY *= PAGE_HEIGHT; 17003 } 17004 } 17005 17006 // Fall-back if spin cannot be determined 17007 if (pX && !sX) { 17008 sX = pX < 1 ? -1 : 1; 17009 } 17010 if (pY && !sY) { 17011 sY = pY < 1 ? -1 : 1; 17012 } 17013 return { 17014 spinX: sX, 17015 spinY: sY, 17016 pixelX: pX, 17017 pixelY: pY 17018 }; 17019 } 17020 function handleMouseEnter() { 17021 if (!swiper.enabled) return; 17022 swiper.mouseEntered = true; 17023 } 17024 function handleMouseLeave() { 17025 if (!swiper.enabled) return; 17026 swiper.mouseEntered = false; 17027 } 17028 function animateSlider(newEvent) { 17029 if (swiper.params.mousewheel.thresholdDelta && newEvent.delta < swiper.params.mousewheel.thresholdDelta) { 17030 // Prevent if delta of wheel scroll delta is below configured threshold 17031 return false; 17032 } 17033 if (swiper.params.mousewheel.thresholdTime && now() - lastScrollTime < swiper.params.mousewheel.thresholdTime) { 17034 // Prevent if time between scrolls is below configured threshold 17035 return false; 17036 } 17037 17038 // If the movement is NOT big enough and 17039 // if the last time the user scrolled was too close to the current one (avoid continuously triggering the slider): 17040 // Don't go any further (avoid insignificant scroll movement). 17041 if (newEvent.delta >= 6 && now() - lastScrollTime < 60) { 17042 // Return false as a default 17043 return true; 17044 } 17045 // If user is scrolling towards the end: 17046 // If the slider hasn't hit the latest slide or 17047 // if the slider is a loop and 17048 // if the slider isn't moving right now: 17049 // Go to next slide and 17050 // emit a scroll event. 17051 // Else (the user is scrolling towards the beginning) and 17052 // if the slider hasn't hit the first slide or 17053 // if the slider is a loop and 17054 // if the slider isn't moving right now: 17055 // Go to prev slide and 17056 // emit a scroll event. 17057 if (newEvent.direction < 0) { 17058 if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) { 17059 swiper.slideNext(); 17060 emit('scroll', newEvent.raw); 17061 } 17062 } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) { 17063 swiper.slidePrev(); 17064 emit('scroll', newEvent.raw); 17065 } 17066 // If you got here is because an animation has been triggered so store the current time 17067 lastScrollTime = new window.Date().getTime(); 17068 // Return false as a default 17069 return false; 17070 } 17071 function releaseScroll(newEvent) { 17072 const params = swiper.params.mousewheel; 17073 if (newEvent.direction < 0) { 17074 if (swiper.isEnd && !swiper.params.loop && params.releaseOnEdges) { 17075 // Return true to animate scroll on edges 17076 return true; 17077 } 17078 } else if (swiper.isBeginning && !swiper.params.loop && params.releaseOnEdges) { 17079 // Return true to animate scroll on edges 17080 return true; 17081 } 17082 return false; 17083 } 17084 function handle(event) { 17085 let e = event; 17086 let disableParentSwiper = true; 17087 if (!swiper.enabled) return; 17088 17089 // Ignore event if the target or its parents have the swiper-no-mousewheel class 17090 if (event.target.closest(`.${swiper.params.mousewheel.noMousewheelClass}`)) return; 17091 const params = swiper.params.mousewheel; 17092 if (swiper.params.cssMode) { 17093 e.preventDefault(); 17094 } 17095 let targetEl = swiper.el; 17096 if (swiper.params.mousewheel.eventsTarget !== 'container') { 17097 targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget); 17098 } 17099 const targetElContainsTarget = targetEl && targetEl.contains(e.target); 17100 if (!swiper.mouseEntered && !targetElContainsTarget && !params.releaseOnEdges) return true; 17101 if (e.originalEvent) e = e.originalEvent; // jquery fix 17102 let delta = 0; 17103 const rtlFactor = swiper.rtlTranslate ? -1 : 1; 17104 const data = normalize(e); 17105 if (params.forceToAxis) { 17106 if (swiper.isHorizontal()) { 17107 if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = -data.pixelX * rtlFactor;else return true; 17108 } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = -data.pixelY;else return true; 17109 } else { 17110 delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY; 17111 } 17112 if (delta === 0) return true; 17113 if (params.invert) delta = -delta; 17114 17115 // Get the scroll positions 17116 let positions = swiper.getTranslate() + delta * params.sensitivity; 17117 if (positions >= swiper.minTranslate()) positions = swiper.minTranslate(); 17118 if (positions <= swiper.maxTranslate()) positions = swiper.maxTranslate(); 17119 17120 // When loop is true: 17121 // the disableParentSwiper will be true. 17122 // When loop is false: 17123 // if the scroll positions is not on edge, 17124 // then the disableParentSwiper will be true. 17125 // if the scroll on edge positions, 17126 // then the disableParentSwiper will be false. 17127 disableParentSwiper = swiper.params.loop ? true : !(positions === swiper.minTranslate() || positions === swiper.maxTranslate()); 17128 if (disableParentSwiper && swiper.params.nested) e.stopPropagation(); 17129 if (!swiper.params.freeMode || !swiper.params.freeMode.enabled) { 17130 // Register the new event in a variable which stores the relevant data 17131 const newEvent = { 17132 time: now(), 17133 delta: Math.abs(delta), 17134 direction: Math.sign(delta), 17135 raw: event 17136 }; 17137 17138 // Keep the most recent events 17139 if (recentWheelEvents.length >= 2) { 17140 recentWheelEvents.shift(); // only store the last N events 17141 } 17142 17143 const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined; 17144 recentWheelEvents.push(newEvent); 17145 17146 // If there is at least one previous recorded event: 17147 // If direction has changed or 17148 // if the scroll is quicker than the previous one: 17149 // Animate the slider. 17150 // Else (this is the first time the wheel is moved): 17151 // Animate the slider. 17152 if (prevEvent) { 17153 if (newEvent.direction !== prevEvent.direction || newEvent.delta > prevEvent.delta || newEvent.time > prevEvent.time + 150) { 17154 animateSlider(newEvent); 17155 } 17156 } else { 17157 animateSlider(newEvent); 17158 } 17159 17160 // If it's time to release the scroll: 17161 // Return now so you don't hit the preventDefault. 17162 if (releaseScroll(newEvent)) { 17163 return true; 17164 } 17165 } else { 17166 // Freemode or scrollContainer: 17167 17168 // If we recently snapped after a momentum scroll, then ignore wheel events 17169 // to give time for the deceleration to finish. Stop ignoring after 500 msecs 17170 // or if it's a new scroll (larger delta or inverse sign as last event before 17171 // an end-of-momentum snap). 17172 const newEvent = { 17173 time: now(), 17174 delta: Math.abs(delta), 17175 direction: Math.sign(delta) 17176 }; 17177 const ignoreWheelEvents = lastEventBeforeSnap && newEvent.time < lastEventBeforeSnap.time + 500 && newEvent.delta <= lastEventBeforeSnap.delta && newEvent.direction === lastEventBeforeSnap.direction; 17178 if (!ignoreWheelEvents) { 17179 lastEventBeforeSnap = undefined; 17180 let position = swiper.getTranslate() + delta * params.sensitivity; 17181 const wasBeginning = swiper.isBeginning; 17182 const wasEnd = swiper.isEnd; 17183 if (position >= swiper.minTranslate()) position = swiper.minTranslate(); 17184 if (position <= swiper.maxTranslate()) position = swiper.maxTranslate(); 17185 swiper.setTransition(0); 17186 swiper.setTranslate(position); 17187 swiper.updateProgress(); 17188 swiper.updateActiveIndex(); 17189 swiper.updateSlidesClasses(); 17190 if (!wasBeginning && swiper.isBeginning || !wasEnd && swiper.isEnd) { 17191 swiper.updateSlidesClasses(); 17192 } 17193 if (swiper.params.loop) { 17194 swiper.loopFix({ 17195 direction: newEvent.direction < 0 ? 'next' : 'prev', 17196 byMousewheel: true 17197 }); 17198 } 17199 if (swiper.params.freeMode.sticky) { 17200 // When wheel scrolling starts with sticky (aka snap) enabled, then detect 17201 // the end of a momentum scroll by storing recent (N=15?) wheel events. 17202 // 1. do all N events have decreasing or same (absolute value) delta? 17203 // 2. did all N events arrive in the last M (M=500?) msecs? 17204 // 3. does the earliest event have an (absolute value) delta that's 17205 // at least P (P=1?) larger than the most recent event's delta? 17206 // 4. does the latest event have a delta that's smaller than Q (Q=6?) pixels? 17207 // If 1-4 are "yes" then we're near the end of a momentum scroll deceleration. 17208 // Snap immediately and ignore remaining wheel events in this scroll. 17209 // See comment above for "remaining wheel events in this scroll" determination. 17210 // If 1-4 aren't satisfied, then wait to snap until 500ms after the last event. 17211 clearTimeout(timeout); 17212 timeout = undefined; 17213 if (recentWheelEvents.length >= 15) { 17214 recentWheelEvents.shift(); // only store the last N events 17215 } 17216 17217 const prevEvent = recentWheelEvents.length ? recentWheelEvents[recentWheelEvents.length - 1] : undefined; 17218 const firstEvent = recentWheelEvents[0]; 17219 recentWheelEvents.push(newEvent); 17220 if (prevEvent && (newEvent.delta > prevEvent.delta || newEvent.direction !== prevEvent.direction)) { 17221 // Increasing or reverse-sign delta means the user started scrolling again. Clear the wheel event log. 17222 recentWheelEvents.splice(0); 17223 } else if (recentWheelEvents.length >= 15 && newEvent.time - firstEvent.time < 500 && firstEvent.delta - newEvent.delta >= 1 && newEvent.delta <= 6) { 17224 // We're at the end of the deceleration of a momentum scroll, so there's no need 17225 // to wait for more events. Snap ASAP on the next tick. 17226 // Also, because there's some remaining momentum we'll bias the snap in the 17227 // direction of the ongoing scroll because it's better UX for the scroll to snap 17228 // in the same direction as the scroll instead of reversing to snap. Therefore, 17229 // if it's already scrolled more than 20% in the current direction, keep going. 17230 const snapToThreshold = delta > 0 ? 0.8 : 0.2; 17231 lastEventBeforeSnap = newEvent; 17232 recentWheelEvents.splice(0); 17233 timeout = nextTick(() => { 17234 if (swiper.destroyed || !swiper.params) return; 17235 swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold); 17236 }, 0); // no delay; move on next tick 17237 } 17238 17239 if (!timeout) { 17240 // if we get here, then we haven't detected the end of a momentum scroll, so 17241 // we'll consider a scroll "complete" when there haven't been any wheel events 17242 // for 500ms. 17243 timeout = nextTick(() => { 17244 if (swiper.destroyed || !swiper.params) return; 17245 const snapToThreshold = 0.5; 17246 lastEventBeforeSnap = newEvent; 17247 recentWheelEvents.splice(0); 17248 swiper.slideToClosest(swiper.params.speed, true, undefined, snapToThreshold); 17249 }, 500); 17250 } 17251 } 17252 17253 // Emit event 17254 if (!ignoreWheelEvents) emit('scroll', e); 17255 17256 // Stop autoplay 17257 if (swiper.params.autoplay && swiper.params.autoplay.disableOnInteraction) swiper.autoplay.stop(); 17258 // Return page scroll on edge positions 17259 if (params.releaseOnEdges && (position === swiper.minTranslate() || position === swiper.maxTranslate())) { 17260 return true; 17261 } 17262 } 17263 } 17264 if (e.preventDefault) e.preventDefault();else e.returnValue = false; 17265 return false; 17266 } 17267 function events(method) { 17268 let targetEl = swiper.el; 17269 if (swiper.params.mousewheel.eventsTarget !== 'container') { 17270 targetEl = document.querySelector(swiper.params.mousewheel.eventsTarget); 17271 } 17272 targetEl[method]('mouseenter', handleMouseEnter); 17273 targetEl[method]('mouseleave', handleMouseLeave); 17274 targetEl[method]('wheel', handle); 17275 } 17276 function enable() { 17277 if (swiper.params.cssMode) { 17278 swiper.wrapperEl.removeEventListener('wheel', handle); 17279 return true; 17280 } 17281 if (swiper.mousewheel.enabled) return false; 17282 events('addEventListener'); 17283 swiper.mousewheel.enabled = true; 17284 return true; 17285 } 17286 function disable() { 17287 if (swiper.params.cssMode) { 17288 swiper.wrapperEl.addEventListener(event, handle); 17289 return true; 17290 } 17291 if (!swiper.mousewheel.enabled) return false; 17292 events('removeEventListener'); 17293 swiper.mousewheel.enabled = false; 17294 return true; 17295 } 17296 on('init', () => { 17297 if (!swiper.params.mousewheel.enabled && swiper.params.cssMode) { 17298 disable(); 17299 } 17300 if (swiper.params.mousewheel.enabled) enable(); 17301 }); 17302 on('destroy', () => { 17303 if (swiper.params.cssMode) { 17304 enable(); 17305 } 17306 if (swiper.mousewheel.enabled) disable(); 17307 }); 17308 Object.assign(swiper.mousewheel, { 17309 enable, 17310 disable 17311 }); 17312} 17313 17314 17315 17316;// ./node_modules/swiper/shared/create-element-if-not-defined.mjs 17317 17318 17319function create_element_if_not_defined_createElementIfNotDefined(swiper, originalParams, params, checkProps) { 17320 if (swiper.params.createElements) { 17321 Object.keys(checkProps).forEach(key => { 17322 if (!params[key] && params.auto === true) { 17323 let element = utils_elementChildren(swiper.el, `.${checkProps[key]}`)[0]; 17324 if (!element) { 17325 element = utils_createElement('div', checkProps[key]); 17326 element.className = checkProps[key]; 17327 swiper.el.append(element); 17328 } 17329 params[key] = element; 17330 originalParams[key] = element; 17331 } 17332 }); 17333 } 17334 return params; 17335} 17336 17337 17338 17339;// ./node_modules/swiper/modules/navigation.mjs 17340 17341 17342 17343function Navigation(_ref) { 17344 let { 17345 swiper, 17346 extendParams, 17347 on, 17348 emit 17349 } = _ref; 17350 extendParams({ 17351 navigation: { 17352 nextEl: null, 17353 prevEl: null, 17354 hideOnClick: false, 17355 disabledClass: 'swiper-button-disabled', 17356 hiddenClass: 'swiper-button-hidden', 17357 lockClass: 'swiper-button-lock', 17358 navigationDisabledClass: 'swiper-navigation-disabled' 17359 } 17360 }); 17361 swiper.navigation = { 17362 nextEl: null, 17363 prevEl: null 17364 }; 17365 function getEl(el) { 17366 let res; 17367 if (el && typeof el === 'string' && swiper.isElement) { 17368 res = swiper.el.querySelector(el) || swiper.hostEl.querySelector(el); 17369 if (res) return res; 17370 } 17371 if (el) { 17372 if (typeof el === 'string') res = [...document.querySelectorAll(el)]; 17373 if (swiper.params.uniqueNavElements && typeof el === 'string' && res && res.length > 1 && swiper.el.querySelectorAll(el).length === 1) { 17374 res = swiper.el.querySelector(el); 17375 } else if (res && res.length === 1) { 17376 res = res[0]; 17377 } 17378 } 17379 if (el && !res) return el; 17380 // if (Array.isArray(res) && res.length === 1) res = res[0]; 17381 return res; 17382 } 17383 function toggleEl(el, disabled) { 17384 const params = swiper.params.navigation; 17385 el = utils_makeElementsArray(el); 17386 el.forEach(subEl => { 17387 if (subEl) { 17388 subEl.classList[disabled ? 'add' : 'remove'](...params.disabledClass.split(' ')); 17389 if (subEl.tagName === 'BUTTON') subEl.disabled = disabled; 17390 if (swiper.params.watchOverflow && swiper.enabled) { 17391 subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass); 17392 } 17393 } 17394 }); 17395 } 17396 function update() { 17397 // Update Navigation Buttons 17398 const { 17399 nextEl, 17400 prevEl 17401 } = swiper.navigation; 17402 if (swiper.params.loop) { 17403 toggleEl(prevEl, false); 17404 toggleEl(nextEl, false); 17405 return; 17406 } 17407 toggleEl(prevEl, swiper.isBeginning && !swiper.params.rewind); 17408 toggleEl(nextEl, swiper.isEnd && !swiper.params.rewind); 17409 } 17410 function onPrevClick(e) { 17411 e.preventDefault(); 17412 if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return; 17413 swiper.slidePrev(); 17414 emit('navigationPrev'); 17415 } 17416 function onNextClick(e) { 17417 e.preventDefault(); 17418 if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return; 17419 swiper.slideNext(); 17420 emit('navigationNext'); 17421 } 17422 function init() { 17423 const params = swiper.params.navigation; 17424 swiper.params.navigation = create_element_if_not_defined_createElementIfNotDefined(swiper, swiper.originalParams.navigation, swiper.params.navigation, { 17425 nextEl: 'swiper-button-next', 17426 prevEl: 'swiper-button-prev' 17427 }); 17428 if (!(params.nextEl || params.prevEl)) return; 17429 let nextEl = getEl(params.nextEl); 17430 let prevEl = getEl(params.prevEl); 17431 Object.assign(swiper.navigation, { 17432 nextEl, 17433 prevEl 17434 }); 17435 nextEl = utils_makeElementsArray(nextEl); 17436 prevEl = utils_makeElementsArray(prevEl); 17437 const initButton = (el, dir) => { 17438 if (el) { 17439 el.addEventListener('click', dir === 'next' ? onNextClick : onPrevClick); 17440 } 17441 if (!swiper.enabled && el) { 17442 el.classList.add(...params.lockClass.split(' ')); 17443 } 17444 }; 17445 nextEl.forEach(el => initButton(el, 'next')); 17446 prevEl.forEach(el => initButton(el, 'prev')); 17447 } 17448 function destroy() { 17449 let { 17450 nextEl, 17451 prevEl 17452 } = swiper.navigation; 17453 nextEl = utils_makeElementsArray(nextEl); 17454 prevEl = utils_makeElementsArray(prevEl); 17455 const destroyButton = (el, dir) => { 17456 el.removeEventListener('click', dir === 'next' ? onNextClick : onPrevClick); 17457 el.classList.remove(...swiper.params.navigation.disabledClass.split(' ')); 17458 }; 17459 nextEl.forEach(el => destroyButton(el, 'next')); 17460 prevEl.forEach(el => destroyButton(el, 'prev')); 17461 } 17462 on('init', () => { 17463 if (swiper.params.navigation.enabled === false) { 17464 // eslint-disable-next-line 17465 disable(); 17466 } else { 17467 init(); 17468 update(); 17469 } 17470 }); 17471 on('toEdge fromEdge lock unlock', () => { 17472 update(); 17473 }); 17474 on('destroy', () => { 17475 destroy(); 17476 }); 17477 on('enable disable', () => { 17478 let { 17479 nextEl, 17480 prevEl 17481 } = swiper.navigation; 17482 nextEl = utils_makeElementsArray(nextEl); 17483 prevEl = utils_makeElementsArray(prevEl); 17484 if (swiper.enabled) { 17485 update(); 17486 return; 17487 } 17488 [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.add(swiper.params.navigation.lockClass)); 17489 }); 17490 on('click', (_s, e) => { 17491 let { 17492 nextEl, 17493 prevEl 17494 } = swiper.navigation; 17495 nextEl = utils_makeElementsArray(nextEl); 17496 prevEl = utils_makeElementsArray(prevEl); 17497 const targetEl = e.target; 17498 let targetIsButton = prevEl.includes(targetEl) || nextEl.includes(targetEl); 17499 if (swiper.isElement && !targetIsButton) { 17500 const path = e.path || e.composedPath && e.composedPath(); 17501 if (path) { 17502 targetIsButton = path.find(pathEl => nextEl.includes(pathEl) || prevEl.includes(pathEl)); 17503 } 17504 } 17505 if (swiper.params.navigation.hideOnClick && !targetIsButton) { 17506 if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return; 17507 let isHidden; 17508 if (nextEl.length) { 17509 isHidden = nextEl[0].classList.contains(swiper.params.navigation.hiddenClass); 17510 } else if (prevEl.length) { 17511 isHidden = prevEl[0].classList.contains(swiper.params.navigation.hiddenClass); 17512 } 17513 if (isHidden === true) { 17514 emit('navigationShow'); 17515 } else { 17516 emit('navigationHide'); 17517 } 17518 [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.toggle(swiper.params.navigation.hiddenClass)); 17519 } 17520 }); 17521 const enable = () => { 17522 swiper.el.classList.remove(...swiper.params.navigation.navigationDisabledClass.split(' ')); 17523 init(); 17524 update(); 17525 }; 17526 const disable = () => { 17527 swiper.el.classList.add(...swiper.params.navigation.navigationDisabledClass.split(' ')); 17528 destroy(); 17529 }; 17530 Object.assign(swiper.navigation, { 17531 enable, 17532 disable, 17533 update, 17534 init, 17535 destroy 17536 }); 17537} 17538 17539 17540 17541;// ./node_modules/swiper/shared/classes-to-selector.mjs 17542function classes_to_selector_classesToSelector(classes) { 17543 if (classes === void 0) { 17544 classes = ''; 17545 } 17546 return `.${classes.trim().replace(/([\.:!+\/()[\]])/g, '\\$1') // eslint-disable-line 17547 .replace(/ /g, '.')}`; 17548} 17549 17550 17551 17552;// ./node_modules/swiper/modules/pagination.mjs 17553 17554 17555 17556 17557function Pagination(_ref) { 17558 let { 17559 swiper, 17560 extendParams, 17561 on, 17562 emit 17563 } = _ref; 17564 const pfx = 'swiper-pagination'; 17565 extendParams({ 17566 pagination: { 17567 el: null, 17568 bulletElement: 'span', 17569 clickable: false, 17570 hideOnClick: false, 17571 renderBullet: null, 17572 renderProgressbar: null, 17573 renderFraction: null, 17574 renderCustom: null, 17575 progressbarOpposite: false, 17576 type: 'bullets', 17577 // 'bullets' or 'progressbar' or 'fraction' or 'custom' 17578 dynamicBullets: false, 17579 dynamicMainBullets: 1, 17580 formatFractionCurrent: number => number, 17581 formatFractionTotal: number => number, 17582 bulletClass: `${pfx}-bullet`, 17583 bulletActiveClass: `${pfx}-bullet-active`, 17584 modifierClass: `${pfx}-`, 17585 currentClass: `${pfx}-current`, 17586 totalClass: `${pfx}-total`, 17587 hiddenClass: `${pfx}-hidden`, 17588 progressbarFillClass: `${pfx}-progressbar-fill`, 17589 progressbarOppositeClass: `${pfx}-progressbar-opposite`, 17590 clickableClass: `${pfx}-clickable`, 17591 lockClass: `${pfx}-lock`, 17592 horizontalClass: `${pfx}-horizontal`, 17593 verticalClass: `${pfx}-vertical`, 17594 paginationDisabledClass: `${pfx}-disabled` 17595 } 17596 }); 17597 swiper.pagination = { 17598 el: null, 17599 bullets: [] 17600 }; 17601 let bulletSize; 17602 let dynamicBulletIndex = 0; 17603 function isPaginationDisabled() { 17604 return !swiper.params.pagination.el || !swiper.pagination.el || Array.isArray(swiper.pagination.el) && swiper.pagination.el.length === 0; 17605 } 17606 function setSideBullets(bulletEl, position) { 17607 const { 17608 bulletActiveClass 17609 } = swiper.params.pagination; 17610 if (!bulletEl) return; 17611 bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`]; 17612 if (bulletEl) { 17613 bulletEl.classList.add(`${bulletActiveClass}-${position}`); 17614 bulletEl = bulletEl[`${position === 'prev' ? 'previous' : 'next'}ElementSibling`]; 17615 if (bulletEl) { 17616 bulletEl.classList.add(`${bulletActiveClass}-${position}-${position}`); 17617 } 17618 } 17619 } 17620 function getMoveDirection(prevIndex, nextIndex, length) { 17621 prevIndex = prevIndex % length; 17622 nextIndex = nextIndex % length; 17623 if (nextIndex === prevIndex + 1) { 17624 return 'next'; 17625 } else if (nextIndex === prevIndex - 1) { 17626 return 'previous'; 17627 } 17628 return; 17629 } 17630 function onBulletClick(e) { 17631 const bulletEl = e.target.closest(classes_to_selector_classesToSelector(swiper.params.pagination.bulletClass)); 17632 if (!bulletEl) { 17633 return; 17634 } 17635 e.preventDefault(); 17636 const index = utils_elementIndex(bulletEl) * swiper.params.slidesPerGroup; 17637 if (swiper.params.loop) { 17638 if (swiper.realIndex === index) return; 17639 const moveDirection = getMoveDirection(swiper.realIndex, index, swiper.slides.length); 17640 if (moveDirection === 'next') { 17641 swiper.slideNext(); 17642 } else if (moveDirection === 'previous') { 17643 swiper.slidePrev(); 17644 } else { 17645 swiper.slideToLoop(index); 17646 } 17647 } else { 17648 swiper.slideTo(index); 17649 } 17650 } 17651 function update() { 17652 // Render || Update Pagination bullets/items 17653 const rtl = swiper.rtl; 17654 const params = swiper.params.pagination; 17655 if (isPaginationDisabled()) return; 17656 let el = swiper.pagination.el; 17657 el = utils_makeElementsArray(el); 17658 // Current/Total 17659 let current; 17660 let previousIndex; 17661 const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length; 17662 const total = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length; 17663 if (swiper.params.loop) { 17664 previousIndex = swiper.previousRealIndex || 0; 17665 current = swiper.params.slidesPerGroup > 1 ? Math.floor(swiper.realIndex / swiper.params.slidesPerGroup) : swiper.realIndex; 17666 } else if (typeof swiper.snapIndex !== 'undefined') { 17667 current = swiper.snapIndex; 17668 previousIndex = swiper.previousSnapIndex; 17669 } else { 17670 previousIndex = swiper.previousIndex || 0; 17671 current = swiper.activeIndex || 0; 17672 } 17673 // Types 17674 if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) { 17675 const bullets = swiper.pagination.bullets; 17676 let firstIndex; 17677 let lastIndex; 17678 let midIndex; 17679 if (params.dynamicBullets) { 17680 bulletSize = elementOuterSize(bullets[0], swiper.isHorizontal() ? 'width' : 'height', true); 17681 el.forEach(subEl => { 17682 subEl.style[swiper.isHorizontal() ? 'width' : 'height'] = `${bulletSize * (params.dynamicMainBullets + 4)}px`; 17683 }); 17684 if (params.dynamicMainBullets > 1 && previousIndex !== undefined) { 17685 dynamicBulletIndex += current - (previousIndex || 0); 17686 if (dynamicBulletIndex > params.dynamicMainBullets - 1) { 17687 dynamicBulletIndex = params.dynamicMainBullets - 1; 17688 } else if (dynamicBulletIndex < 0) { 17689 dynamicBulletIndex = 0; 17690 } 17691 } 17692 firstIndex = Math.max(current - dynamicBulletIndex, 0); 17693 lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1); 17694 midIndex = (lastIndex + firstIndex) / 2; 17695 } 17696 bullets.forEach(bulletEl => { 17697 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(); 17698 bulletEl.classList.remove(...classesToRemove); 17699 }); 17700 if (el.length > 1) { 17701 bullets.forEach(bullet => { 17702 const bulletIndex = utils_elementIndex(bullet); 17703 if (bulletIndex === current) { 17704 bullet.classList.add(...params.bulletActiveClass.split(' ')); 17705 } else if (swiper.isElement) { 17706 bullet.setAttribute('part', 'bullet'); 17707 } 17708 if (params.dynamicBullets) { 17709 if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) { 17710 bullet.classList.add(...`${params.bulletActiveClass}-main`.split(' ')); 17711 } 17712 if (bulletIndex === firstIndex) { 17713 setSideBullets(bullet, 'prev'); 17714 } 17715 if (bulletIndex === lastIndex) { 17716 setSideBullets(bullet, 'next'); 17717 } 17718 } 17719 }); 17720 } else { 17721 const bullet = bullets[current]; 17722 if (bullet) { 17723 bullet.classList.add(...params.bulletActiveClass.split(' ')); 17724 } 17725 if (swiper.isElement) { 17726 bullets.forEach((bulletEl, bulletIndex) => { 17727 bulletEl.setAttribute('part', bulletIndex === current ? 'bullet-active' : 'bullet'); 17728 }); 17729 } 17730 if (params.dynamicBullets) { 17731 const firstDisplayedBullet = bullets[firstIndex]; 17732 const lastDisplayedBullet = bullets[lastIndex]; 17733 for (let i = firstIndex; i <= lastIndex; i += 1) { 17734 if (bullets[i]) { 17735 bullets[i].classList.add(...`${params.bulletActiveClass}-main`.split(' ')); 17736 } 17737 } 17738 setSideBullets(firstDisplayedBullet, 'prev'); 17739 setSideBullets(lastDisplayedBullet, 'next'); 17740 } 17741 } 17742 if (params.dynamicBullets) { 17743 const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4); 17744 const bulletsOffset = (bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize; 17745 const offsetProp = rtl ? 'right' : 'left';
vendor: 4,211 bytes, lines 17746-17840
17746 bullets.forEach(bullet => { 17747 bullet.style[swiper.isHorizontal() ? offsetProp : 'top'] = `${bulletsOffset}px`; 17748 }); 17749 } 17750 } 17751 el.forEach((subEl, subElIndex) => { 17752 if (params.type === 'fraction') { 17753 subEl.querySelectorAll(classes_to_selector_classesToSelector(params.currentClass)).forEach(fractionEl => { 17754 fractionEl.textContent = params.formatFractionCurrent(current + 1); 17755 }); 17756 subEl.querySelectorAll(classes_to_selector_classesToSelector(params.totalClass)).forEach(totalEl => { 17757 totalEl.textContent = params.formatFractionTotal(total); 17758 }); 17759 } 17760 if (params.type === 'progressbar') { 17761 let progressbarDirection; 17762 if (params.progressbarOpposite) { 17763 progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal'; 17764 } else { 17765 progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical'; 17766 } 17767 const scale = (current + 1) / total; 17768 let scaleX = 1; 17769 let scaleY = 1; 17770 if (progressbarDirection === 'horizontal') { 17771 scaleX = scale; 17772 } else { 17773 scaleY = scale; 17774 } 17775 subEl.querySelectorAll(classes_to_selector_classesToSelector(params.progressbarFillClass)).forEach(progressEl => { 17776 progressEl.style.transform = `translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`; 17777 progressEl.style.transitionDuration = `${swiper.params.speed}ms`; 17778 }); 17779 } 17780 if (params.type === 'custom' && params.renderCustom) { 17781 utils_setInnerHTML(subEl, params.renderCustom(swiper, current + 1, total)); 17782 if (subElIndex === 0) emit('paginationRender', subEl); 17783 } else { 17784 if (subElIndex === 0) emit('paginationRender', subEl); 17785 emit('paginationUpdate', subEl); 17786 } 17787 if (swiper.params.watchOverflow && swiper.enabled) { 17788 subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass); 17789 } 17790 }); 17791 } 17792 function render() { 17793 // Render Container 17794 const params = swiper.params.pagination; 17795 if (isPaginationDisabled()) return; 17796 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; 17797 let el = swiper.pagination.el; 17798 el = utils_makeElementsArray(el); 17799 let paginationHTML = ''; 17800 if (params.type === 'bullets') { 17801 let numberOfBullets = swiper.params.loop ? Math.ceil(slidesLength / swiper.params.slidesPerGroup) : swiper.snapGrid.length; 17802 if (swiper.params.freeMode && swiper.params.freeMode.enabled && numberOfBullets > slidesLength) { 17803 numberOfBullets = slidesLength; 17804 } 17805 for (let i = 0; i < numberOfBullets; i += 1) { 17806 if (params.renderBullet) { 17807 paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass); 17808 } else { 17809 // prettier-ignore 17810 paginationHTML += `<${params.bulletElement} ${swiper.isElement ? 'part="bullet"' : ''} class="${params.bulletClass}"></${params.bulletElement}>`; 17811 } 17812 } 17813 } 17814 if (params.type === 'fraction') { 17815 if (params.renderFraction) { 17816 paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass); 17817 } else { 17818 paginationHTML = `<span class="${params.currentClass}"></span>` + ' / ' + `<span class="${params.totalClass}"></span>`; 17819 } 17820 } 17821 if (params.type === 'progressbar') { 17822 if (params.renderProgressbar) { 17823 paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass); 17824 } else { 17825 paginationHTML = `<span class="${params.progressbarFillClass}"></span>`; 17826 } 17827 } 17828 swiper.pagination.bullets = []; 17829 el.forEach(subEl => { 17830 if (params.type !== 'custom') { 17831 utils_setInnerHTML(subEl, paginationHTML || ''); 17832 } 17833 if (params.type === 'bullets') { 17834 swiper.pagination.bullets.push(...subEl.querySelectorAll(classes_to_selector_classesToSelector(params.bulletClass))); 17835 } 17836 }); 17837 if (params.type !== 'custom') { 17838 emit('paginationRender', el[0]); 17839 } 17840 }
vendor: 5,913 bytes, lines 17841-18028
17841 function init() { 17842 swiper.params.pagination = create_element_if_not_defined_createElementIfNotDefined(swiper, swiper.originalParams.pagination, swiper.params.pagination, { 17843 el: 'swiper-pagination' 17844 }); 17845 const params = swiper.params.pagination; 17846 if (!params.el) return; 17847 let el; 17848 if (typeof params.el === 'string' && swiper.isElement) { 17849 el = swiper.el.querySelector(params.el); 17850 } 17851 if (!el && typeof params.el === 'string') { 17852 el = [...document.querySelectorAll(params.el)]; 17853 } 17854 if (!el) { 17855 el = params.el; 17856 } 17857 if (!el || el.length === 0) return; 17858 if (swiper.params.uniqueNavElements && typeof params.el === 'string' && Array.isArray(el) && el.length > 1) { 17859 el = [...swiper.el.querySelectorAll(params.el)]; 17860 // check if it belongs to another nested Swiper 17861 if (el.length > 1) { 17862 el = el.find(subEl => { 17863 if (utils_elementParents(subEl, '.swiper')[0] !== swiper.el) return false; 17864 return true; 17865 }); 17866 } 17867 } 17868 if (Array.isArray(el) && el.length === 1) el = el[0]; 17869 Object.assign(swiper.pagination, { 17870 el 17871 }); 17872 el = utils_makeElementsArray(el); 17873 el.forEach(subEl => { 17874 if (params.type === 'bullets' && params.clickable) { 17875 subEl.classList.add(...(params.clickableClass || '').split(' ')); 17876 } 17877 subEl.classList.add(params.modifierClass + params.type); 17878 subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass); 17879 if (params.type === 'bullets' && params.dynamicBullets) { 17880 subEl.classList.add(`${params.modifierClass}${params.type}-dynamic`); 17881 dynamicBulletIndex = 0; 17882 if (params.dynamicMainBullets < 1) { 17883 params.dynamicMainBullets = 1; 17884 } 17885 } 17886 if (params.type === 'progressbar' && params.progressbarOpposite) { 17887 subEl.classList.add(params.progressbarOppositeClass); 17888 } 17889 if (params.clickable) { 17890 subEl.addEventListener('click', onBulletClick); 17891 } 17892 if (!swiper.enabled) { 17893 subEl.classList.add(params.lockClass); 17894 } 17895 }); 17896 } 17897 function destroy() { 17898 const params = swiper.params.pagination; 17899 if (isPaginationDisabled()) return; 17900 let el = swiper.pagination.el; 17901 if (el) { 17902 el = utils_makeElementsArray(el); 17903 el.forEach(subEl => { 17904 subEl.classList.remove(params.hiddenClass); 17905 subEl.classList.remove(params.modifierClass + params.type); 17906 subEl.classList.remove(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass); 17907 if (params.clickable) { 17908 subEl.classList.remove(...(params.clickableClass || '').split(' ')); 17909 subEl.removeEventListener('click', onBulletClick); 17910 } 17911 }); 17912 } 17913 if (swiper.pagination.bullets) swiper.pagination.bullets.forEach(subEl => subEl.classList.remove(...params.bulletActiveClass.split(' '))); 17914 } 17915 on('changeDirection', () => { 17916 if (!swiper.pagination || !swiper.pagination.el) return; 17917 const params = swiper.params.pagination; 17918 let { 17919 el 17920 } = swiper.pagination; 17921 el = utils_makeElementsArray(el); 17922 el.forEach(subEl => { 17923 subEl.classList.remove(params.horizontalClass, params.verticalClass); 17924 subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass); 17925 }); 17926 }); 17927 on('init', () => { 17928 if (swiper.params.pagination.enabled === false) { 17929 // eslint-disable-next-line 17930 disable(); 17931 } else { 17932 init(); 17933 render(); 17934 update(); 17935 } 17936 }); 17937 on('activeIndexChange', () => { 17938 if (typeof swiper.snapIndex === 'undefined') { 17939 update(); 17940 } 17941 }); 17942 on('snapIndexChange', () => { 17943 update(); 17944 }); 17945 on('snapGridLengthChange', () => { 17946 render(); 17947 update(); 17948 }); 17949 on('destroy', () => { 17950 destroy(); 17951 }); 17952 on('enable disable', () => { 17953 let { 17954 el 17955 } = swiper.pagination; 17956 if (el) { 17957 el = utils_makeElementsArray(el); 17958 el.forEach(subEl => subEl.classList[swiper.enabled ? 'remove' : 'add'](swiper.params.pagination.lockClass)); 17959 } 17960 }); 17961 on('lock unlock', () => { 17962 update(); 17963 }); 17964 on('click', (_s, e) => { 17965 const targetEl = e.target; 17966 const el = utils_makeElementsArray(swiper.pagination.el); 17967 if (swiper.params.pagination.el && swiper.params.pagination.hideOnClick && el && el.length > 0 && !targetEl.classList.contains(swiper.params.pagination.bulletClass)) { 17968 if (swiper.navigation && (swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl || swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl)) return; 17969 const isHidden = el[0].classList.contains(swiper.params.pagination.hiddenClass); 17970 if (isHidden === true) { 17971 emit('paginationShow'); 17972 } else { 17973 emit('paginationHide'); 17974 } 17975 el.forEach(subEl => subEl.classList.toggle(swiper.params.pagination.hiddenClass)); 17976 } 17977 }); 17978 const enable = () => { 17979 swiper.el.classList.remove(swiper.params.pagination.paginationDisabledClass); 17980 let { 17981 el 17982 } = swiper.pagination; 17983 if (el) { 17984 el = utils_makeElementsArray(el); 17985 el.forEach(subEl => subEl.classList.remove(swiper.params.pagination.paginationDisabledClass)); 17986 } 17987 init(); 17988 render(); 17989 update(); 17990 }; 17991 const disable = () => { 17992 swiper.el.classList.add(swiper.params.pagination.paginationDisabledClass); 17993 let { 17994 el 17995 } = swiper.pagination; 17996 if (el) { 17997 el = utils_makeElementsArray(el); 17998 el.forEach(subEl => subEl.classList.add(swiper.params.pagination.paginationDisabledClass)); 17999 } 18000 destroy(); 18001 }; 18002 Object.assign(swiper.pagination, { 18003 enable, 18004 disable, 18005 render, 18006 update, 18007 init, 18008 destroy 18009 }); 18010} 18011 18012 18013 18014;// ./node_modules/swiper/modules/scrollbar.mjs 18015 18016 18017 18018 18019 18020function Scrollbar(_ref) { 18021 let { 18022 swiper, 18023 extendParams, 18024 on, 18025 emit 18026 } = _ref; 18027 const document = getDocument(); 18028 let isTouched = false;
vendor: 4,705 bytes, lines 18029-18181
18029 let timeout = null; 18030 let dragTimeout = null; 18031 let dragStartPos; 18032 let dragSize; 18033 let trackSize; 18034 let divider; 18035 extendParams({ 18036 scrollbar: { 18037 el: null, 18038 dragSize: 'auto', 18039 hide: false, 18040 draggable: false, 18041 snapOnRelease: true, 18042 lockClass: 'swiper-scrollbar-lock', 18043 dragClass: 'swiper-scrollbar-drag', 18044 scrollbarDisabledClass: 'swiper-scrollbar-disabled', 18045 horizontalClass: `swiper-scrollbar-horizontal`, 18046 verticalClass: `swiper-scrollbar-vertical` 18047 } 18048 }); 18049 swiper.scrollbar = { 18050 el: null, 18051 dragEl: null 18052 }; 18053 function setTranslate() { 18054 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; 18055 const { 18056 scrollbar, 18057 rtlTranslate: rtl 18058 } = swiper; 18059 const { 18060 dragEl, 18061 el 18062 } = scrollbar; 18063 const params = swiper.params.scrollbar; 18064 const progress = swiper.params.loop ? swiper.progressLoop : swiper.progress; 18065 let newSize = dragSize; 18066 let newPos = (trackSize - dragSize) * progress; 18067 if (rtl) { 18068 newPos = -newPos; 18069 if (newPos > 0) { 18070 newSize = dragSize - newPos; 18071 newPos = 0; 18072 } else if (-newPos + dragSize > trackSize) { 18073 newSize = trackSize + newPos; 18074 } 18075 } else if (newPos < 0) { 18076 newSize = dragSize + newPos; 18077 newPos = 0; 18078 } else if (newPos + dragSize > trackSize) { 18079 newSize = trackSize - newPos; 18080 } 18081 if (swiper.isHorizontal()) { 18082 dragEl.style.transform = `translate3d(${newPos}px, 0, 0)`; 18083 dragEl.style.width = `${newSize}px`; 18084 } else { 18085 dragEl.style.transform = `translate3d(0px, ${newPos}px, 0)`; 18086 dragEl.style.height = `${newSize}px`; 18087 } 18088 if (params.hide) { 18089 clearTimeout(timeout); 18090 el.style.opacity = 1; 18091 timeout = setTimeout(() => { 18092 el.style.opacity = 0; 18093 el.style.transitionDuration = '400ms'; 18094 }, 1000); 18095 } 18096 } 18097 function setTransition(duration) { 18098 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; 18099 swiper.scrollbar.dragEl.style.transitionDuration = `${duration}ms`; 18100 } 18101 function updateSize() { 18102 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; 18103 const { 18104 scrollbar 18105 } = swiper; 18106 const { 18107 dragEl, 18108 el 18109 } = scrollbar; 18110 dragEl.style.width = ''; 18111 dragEl.style.height = ''; 18112 trackSize = swiper.isHorizontal() ? el.offsetWidth : el.offsetHeight; 18113 divider = swiper.size / (swiper.virtualSize + swiper.params.slidesOffsetBefore - (swiper.params.centeredSlides ? swiper.snapGrid[0] : 0)); 18114 if (swiper.params.scrollbar.dragSize === 'auto') { 18115 dragSize = trackSize * divider; 18116 } else { 18117 dragSize = parseInt(swiper.params.scrollbar.dragSize, 10); 18118 } 18119 if (swiper.isHorizontal()) { 18120 dragEl.style.width = `${dragSize}px`; 18121 } else { 18122 dragEl.style.height = `${dragSize}px`; 18123 } 18124 if (divider >= 1) { 18125 el.style.display = 'none'; 18126 } else { 18127 el.style.display = ''; 18128 } 18129 if (swiper.params.scrollbar.hide) { 18130 el.style.opacity = 0; 18131 } 18132 if (swiper.params.watchOverflow && swiper.enabled) { 18133 scrollbar.el.classList[swiper.isLocked ? 'add' : 'remove'](swiper.params.scrollbar.lockClass); 18134 } 18135 } 18136 function getPointerPosition(e) { 18137 return swiper.isHorizontal() ? e.clientX : e.clientY; 18138 } 18139 function setDragPosition(e) { 18140 const { 18141 scrollbar, 18142 rtlTranslate: rtl 18143 } = swiper; 18144 const { 18145 el 18146 } = scrollbar; 18147 let positionRatio; 18148 positionRatio = (getPointerPosition(e) - elementOffset(el)[swiper.isHorizontal() ? 'left' : 'top'] - (dragStartPos !== null ? dragStartPos : dragSize / 2)) / (trackSize - dragSize); 18149 positionRatio = Math.max(Math.min(positionRatio, 1), 0); 18150 if (rtl) { 18151 positionRatio = 1 - positionRatio; 18152 } 18153 const position = swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio; 18154 swiper.updateProgress(position); 18155 swiper.setTranslate(position); 18156 swiper.updateActiveIndex(); 18157 swiper.updateSlidesClasses(); 18158 } 18159 function onDragStart(e) { 18160 const params = swiper.params.scrollbar; 18161 const { 18162 scrollbar, 18163 wrapperEl 18164 } = swiper; 18165 const { 18166 el, 18167 dragEl 18168 } = scrollbar; 18169 isTouched = true; 18170 dragStartPos = e.target === dragEl ? getPointerPosition(e) - e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] : null; 18171 e.preventDefault(); 18172 e.stopPropagation(); 18173 wrapperEl.style.transitionDuration = '100ms'; 18174 dragEl.style.transitionDuration = '100ms'; 18175 setDragPosition(e); 18176 clearTimeout(dragTimeout); 18177 el.style.transitionDuration = '0ms'; 18178 if (params.hide) { 18179 el.style.opacity = 1; 18180 } 18181 if (swiper.params.cssMode) {
vendor: 117,893 bytes, lines 18182-21750
18182 swiper.wrapperEl.style['scroll-snap-type'] = 'none'; 18183 } 18184 emit('scrollbarDragStart', e); 18185 } 18186 function onDragMove(e) { 18187 const { 18188 scrollbar, 18189 wrapperEl 18190 } = swiper; 18191 const { 18192 el, 18193 dragEl 18194 } = scrollbar; 18195 if (!isTouched) return; 18196 if (e.preventDefault && e.cancelable) e.preventDefault();else e.returnValue = false; 18197 setDragPosition(e); 18198 wrapperEl.style.transitionDuration = '0ms'; 18199 el.style.transitionDuration = '0ms'; 18200 dragEl.style.transitionDuration = '0ms'; 18201 emit('scrollbarDragMove', e); 18202 } 18203 function onDragEnd(e) { 18204 const params = swiper.params.scrollbar; 18205 const { 18206 scrollbar, 18207 wrapperEl 18208 } = swiper; 18209 const { 18210 el 18211 } = scrollbar; 18212 if (!isTouched) return; 18213 isTouched = false; 18214 if (swiper.params.cssMode) { 18215 swiper.wrapperEl.style['scroll-snap-type'] = ''; 18216 wrapperEl.style.transitionDuration = ''; 18217 } 18218 if (params.hide) { 18219 clearTimeout(dragTimeout); 18220 dragTimeout = nextTick(() => { 18221 el.style.opacity = 0; 18222 el.style.transitionDuration = '400ms'; 18223 }, 1000); 18224 } 18225 emit('scrollbarDragEnd', e); 18226 if (params.snapOnRelease) { 18227 swiper.slideToClosest(); 18228 } 18229 } 18230 function events(method) { 18231 const { 18232 scrollbar, 18233 params 18234 } = swiper; 18235 const el = scrollbar.el; 18236 if (!el) return; 18237 const target = el; 18238 const activeListener = params.passiveListeners ? { 18239 passive: false, 18240 capture: false 18241 } : false; 18242 const passiveListener = params.passiveListeners ? { 18243 passive: true, 18244 capture: false 18245 } : false; 18246 if (!target) return; 18247 const eventMethod = method === 'on' ? 'addEventListener' : 'removeEventListener'; 18248 target[eventMethod]('pointerdown', onDragStart, activeListener); 18249 document[eventMethod]('pointermove', onDragMove, activeListener); 18250 document[eventMethod]('pointerup', onDragEnd, passiveListener); 18251 } 18252 function enableDraggable() { 18253 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; 18254 events('on'); 18255 } 18256 function disableDraggable() { 18257 if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; 18258 events('off'); 18259 } 18260 function init() { 18261 const { 18262 scrollbar, 18263 el: swiperEl 18264 } = swiper; 18265 swiper.params.scrollbar = createElementIfNotDefined(swiper, swiper.originalParams.scrollbar, swiper.params.scrollbar, { 18266 el: 'swiper-scrollbar' 18267 }); 18268 const params = swiper.params.scrollbar; 18269 if (!params.el) return; 18270 let el; 18271 if (typeof params.el === 'string' && swiper.isElement) { 18272 el = swiper.el.querySelector(params.el); 18273 } 18274 if (!el && typeof params.el === 'string') { 18275 el = document.querySelectorAll(params.el); 18276 if (!el.length) return; 18277 } else if (!el) { 18278 el = params.el; 18279 } 18280 if (swiper.params.uniqueNavElements && typeof params.el === 'string' && el.length > 1 && swiperEl.querySelectorAll(params.el).length === 1) { 18281 el = swiperEl.querySelector(params.el); 18282 } 18283 if (el.length > 0) el = el[0]; 18284 el.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass); 18285 let dragEl; 18286 if (el) { 18287 dragEl = el.querySelector(classesToSelector(swiper.params.scrollbar.dragClass)); 18288 if (!dragEl) { 18289 dragEl = createElement('div', swiper.params.scrollbar.dragClass); 18290 el.append(dragEl); 18291 } 18292 } 18293 Object.assign(scrollbar, { 18294 el, 18295 dragEl 18296 }); 18297 if (params.draggable) { 18298 enableDraggable(); 18299 } 18300 if (el) { 18301 el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass)); 18302 } 18303 } 18304 function destroy() { 18305 const params = swiper.params.scrollbar; 18306 const el = swiper.scrollbar.el; 18307 if (el) { 18308 el.classList.remove(...classesToTokens(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass)); 18309 } 18310 disableDraggable(); 18311 } 18312 on('changeDirection', () => { 18313 if (!swiper.scrollbar || !swiper.scrollbar.el) return; 18314 const params = swiper.params.scrollbar; 18315 let { 18316 el 18317 } = swiper.scrollbar; 18318 el = makeElementsArray(el); 18319 el.forEach(subEl => { 18320 subEl.classList.remove(params.horizontalClass, params.verticalClass); 18321 subEl.classList.add(swiper.isHorizontal() ? params.horizontalClass : params.verticalClass); 18322 }); 18323 }); 18324 on('init', () => { 18325 if (swiper.params.scrollbar.enabled === false) { 18326 // eslint-disable-next-line 18327 disable(); 18328 } else { 18329 init(); 18330 updateSize(); 18331 setTranslate(); 18332 } 18333 }); 18334 on('update resize observerUpdate lock unlock changeDirection', () => { 18335 updateSize(); 18336 }); 18337 on('setTranslate', () => { 18338 setTranslate(); 18339 }); 18340 on('setTransition', (_s, duration) => { 18341 setTransition(duration); 18342 }); 18343 on('enable disable', () => { 18344 const { 18345 el 18346 } = swiper.scrollbar; 18347 if (el) { 18348 el.classList[swiper.enabled ? 'remove' : 'add'](...classesToTokens(swiper.params.scrollbar.lockClass)); 18349 } 18350 }); 18351 on('destroy', () => { 18352 destroy(); 18353 }); 18354 const enable = () => { 18355 swiper.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass)); 18356 if (swiper.scrollbar.el) { 18357 swiper.scrollbar.el.classList.remove(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass)); 18358 } 18359 init(); 18360 updateSize(); 18361 setTranslate(); 18362 }; 18363 const disable = () => { 18364 swiper.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass)); 18365 if (swiper.scrollbar.el) { 18366 swiper.scrollbar.el.classList.add(...classesToTokens(swiper.params.scrollbar.scrollbarDisabledClass)); 18367 } 18368 destroy(); 18369 }; 18370 Object.assign(swiper.scrollbar, { 18371 enable, 18372 disable, 18373 updateSize, 18374 setTranslate, 18375 init, 18376 destroy 18377 }); 18378} 18379 18380 18381 18382;// ./node_modules/swiper/modules/parallax.mjs 18383 18384 18385function Parallax(_ref) { 18386 let { 18387 swiper, 18388 extendParams, 18389 on 18390 } = _ref; 18391 extendParams({ 18392 parallax: { 18393 enabled: false 18394 } 18395 }); 18396 const elementsSelector = '[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]'; 18397 const setTransform = (el, progress) => { 18398 const { 18399 rtl 18400 } = swiper; 18401 const rtlFactor = rtl ? -1 : 1; 18402 const p = el.getAttribute('data-swiper-parallax') || '0'; 18403 let x = el.getAttribute('data-swiper-parallax-x'); 18404 let y = el.getAttribute('data-swiper-parallax-y'); 18405 const scale = el.getAttribute('data-swiper-parallax-scale'); 18406 const opacity = el.getAttribute('data-swiper-parallax-opacity'); 18407 const rotate = el.getAttribute('data-swiper-parallax-rotate'); 18408 if (x || y) { 18409 x = x || '0'; 18410 y = y || '0'; 18411 } else if (swiper.isHorizontal()) { 18412 x = p; 18413 y = '0'; 18414 } else { 18415 y = p; 18416 x = '0'; 18417 } 18418 if (x.indexOf('%') >= 0) { 18419 x = `${parseInt(x, 10) * progress * rtlFactor}%`; 18420 } else { 18421 x = `${x * progress * rtlFactor}px`; 18422 } 18423 if (y.indexOf('%') >= 0) { 18424 y = `${parseInt(y, 10) * progress}%`; 18425 } else { 18426 y = `${y * progress}px`; 18427 } 18428 if (typeof opacity !== 'undefined' && opacity !== null) { 18429 const currentOpacity = opacity - (opacity - 1) * (1 - Math.abs(progress)); 18430 el.style.opacity = currentOpacity; 18431 } 18432 let transform = `translate3d(${x}, ${y}, 0px)`; 18433 if (typeof scale !== 'undefined' && scale !== null) { 18434 const currentScale = scale - (scale - 1) * (1 - Math.abs(progress)); 18435 transform += ` scale(${currentScale})`; 18436 } 18437 if (rotate && typeof rotate !== 'undefined' && rotate !== null) { 18438 const currentRotate = rotate * progress * -1; 18439 transform += ` rotate(${currentRotate}deg)`; 18440 } 18441 el.style.transform = transform; 18442 }; 18443 const setTranslate = () => { 18444 const { 18445 el, 18446 slides, 18447 progress, 18448 snapGrid, 18449 isElement 18450 } = swiper; 18451 const elements = elementChildren(el, elementsSelector); 18452 if (swiper.isElement) { 18453 elements.push(...elementChildren(swiper.hostEl, elementsSelector)); 18454 } 18455 elements.forEach(subEl => { 18456 setTransform(subEl, progress); 18457 }); 18458 slides.forEach((slideEl, slideIndex) => { 18459 let slideProgress = slideEl.progress; 18460 if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') { 18461 slideProgress += Math.ceil(slideIndex / 2) - progress * (snapGrid.length - 1); 18462 } 18463 slideProgress = Math.min(Math.max(slideProgress, -1), 1); 18464 slideEl.querySelectorAll(`${elementsSelector}, [data-swiper-parallax-rotate]`).forEach(subEl => { 18465 setTransform(subEl, slideProgress); 18466 }); 18467 }); 18468 }; 18469 const setTransition = function (duration) { 18470 if (duration === void 0) { 18471 duration = swiper.params.speed; 18472 } 18473 const { 18474 el, 18475 hostEl 18476 } = swiper; 18477 const elements = [...el.querySelectorAll(elementsSelector)]; 18478 if (swiper.isElement) { 18479 elements.push(...hostEl.querySelectorAll(elementsSelector)); 18480 } 18481 elements.forEach(parallaxEl => { 18482 let parallaxDuration = parseInt(parallaxEl.getAttribute('data-swiper-parallax-duration'), 10) || duration; 18483 if (duration === 0) parallaxDuration = 0; 18484 parallaxEl.style.transitionDuration = `${parallaxDuration}ms`; 18485 }); 18486 }; 18487 on('beforeInit', () => { 18488 if (!swiper.params.parallax.enabled) return; 18489 swiper.params.watchSlidesProgress = true; 18490 swiper.originalParams.watchSlidesProgress = true; 18491 }); 18492 on('init', () => { 18493 if (!swiper.params.parallax.enabled) return; 18494 setTranslate(); 18495 }); 18496 on('setTranslate', () => { 18497 if (!swiper.params.parallax.enabled) return; 18498 setTranslate(); 18499 }); 18500 on('setTransition', (_swiper, duration) => { 18501 if (!swiper.params.parallax.enabled) return; 18502 setTransition(duration); 18503 }); 18504} 18505 18506 18507 18508;// ./node_modules/swiper/modules/zoom.mjs 18509 18510 18511 18512function Zoom(_ref) { 18513 let { 18514 swiper, 18515 extendParams, 18516 on, 18517 emit 18518 } = _ref; 18519 const window = getWindow(); 18520 extendParams({ 18521 zoom: { 18522 enabled: false, 18523 limitToOriginalSize: false, 18524 maxRatio: 3, 18525 minRatio: 1, 18526 panOnMouseMove: false, 18527 toggle: true, 18528 containerClass: 'swiper-zoom-container', 18529 zoomedSlideClass: 'swiper-slide-zoomed' 18530 } 18531 }); 18532 swiper.zoom = { 18533 enabled: false 18534 }; 18535 let currentScale = 1; 18536 let isScaling = false; 18537 let isPanningWithMouse = false; 18538 let mousePanStart = { 18539 x: 0, 18540 y: 0 18541 }; 18542 const mousePanSensitivity = -3; // Negative to invert pan direction 18543 let fakeGestureTouched; 18544 let fakeGestureMoved; 18545 const evCache = []; 18546 const gesture = { 18547 originX: 0, 18548 originY: 0, 18549 slideEl: undefined, 18550 slideWidth: undefined, 18551 slideHeight: undefined, 18552 imageEl: undefined, 18553 imageWrapEl: undefined, 18554 maxRatio: 3 18555 }; 18556 const image = { 18557 isTouched: undefined, 18558 isMoved: undefined, 18559 currentX: undefined, 18560 currentY: undefined, 18561 minX: undefined, 18562 minY: undefined, 18563 maxX: undefined, 18564 maxY: undefined, 18565 width: undefined, 18566 height: undefined, 18567 startX: undefined, 18568 startY: undefined, 18569 touchesStart: {}, 18570 touchesCurrent: {} 18571 }; 18572 const velocity = { 18573 x: undefined, 18574 y: undefined, 18575 prevPositionX: undefined, 18576 prevPositionY: undefined, 18577 prevTime: undefined 18578 }; 18579 let scale = 1; 18580 Object.defineProperty(swiper.zoom, 'scale', { 18581 get() { 18582 return scale; 18583 }, 18584 set(value) { 18585 if (scale !== value) { 18586 const imageEl = gesture.imageEl; 18587 const slideEl = gesture.slideEl; 18588 emit('zoomChange', value, imageEl, slideEl); 18589 } 18590 scale = value; 18591 } 18592 }); 18593 function getDistanceBetweenTouches() { 18594 if (evCache.length < 2) return 1; 18595 const x1 = evCache[0].pageX; 18596 const y1 = evCache[0].pageY; 18597 const x2 = evCache[1].pageX; 18598 const y2 = evCache[1].pageY; 18599 const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); 18600 return distance; 18601 } 18602 function getMaxRatio() { 18603 const params = swiper.params.zoom; 18604 const maxRatio = gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio; 18605 if (params.limitToOriginalSize && gesture.imageEl && gesture.imageEl.naturalWidth) { 18606 const imageMaxRatio = gesture.imageEl.naturalWidth / gesture.imageEl.offsetWidth; 18607 return Math.min(imageMaxRatio, maxRatio); 18608 } 18609 return maxRatio; 18610 } 18611 function getScaleOrigin() { 18612 if (evCache.length < 2) return { 18613 x: null, 18614 y: null 18615 }; 18616 const box = gesture.imageEl.getBoundingClientRect(); 18617 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]; 18618 } 18619 function getSlideSelector() { 18620 return swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`; 18621 } 18622 function eventWithinSlide(e) { 18623 const slideSelector = getSlideSelector(); 18624 if (e.target.matches(slideSelector)) return true; 18625 if (swiper.slides.filter(slideEl => slideEl.contains(e.target)).length > 0) return true; 18626 return false; 18627 } 18628 function eventWithinZoomContainer(e) { 18629 const selector = `.${swiper.params.zoom.containerClass}`; 18630 if (e.target.matches(selector)) return true; 18631 if ([...swiper.hostEl.querySelectorAll(selector)].filter(containerEl => containerEl.contains(e.target)).length > 0) return true; 18632 return false; 18633 } 18634 18635 // Events 18636 function onGestureStart(e) { 18637 if (e.pointerType === 'mouse') { 18638 evCache.splice(0, evCache.length); 18639 } 18640 if (!eventWithinSlide(e)) return; 18641 const params = swiper.params.zoom; 18642 fakeGestureTouched = false; 18643 fakeGestureMoved = false; 18644 evCache.push(e); 18645 if (evCache.length < 2) { 18646 return; 18647 } 18648 fakeGestureTouched = true; 18649 gesture.scaleStart = getDistanceBetweenTouches(); 18650 if (!gesture.slideEl) { 18651 gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`); 18652 if (!gesture.slideEl) gesture.slideEl = swiper.slides[swiper.activeIndex]; 18653 let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`); 18654 if (imageEl) { 18655 imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0]; 18656 } 18657 gesture.imageEl = imageEl; 18658 if (imageEl) { 18659 gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0]; 18660 } else { 18661 gesture.imageWrapEl = undefined; 18662 } 18663 if (!gesture.imageWrapEl) { 18664 gesture.imageEl = undefined; 18665 return; 18666 } 18667 gesture.maxRatio = getMaxRatio(); 18668 } 18669 if (gesture.imageEl) { 18670 const [originX, originY] = getScaleOrigin(); 18671 gesture.originX = originX; 18672 gesture.originY = originY; 18673 gesture.imageEl.style.transitionDuration = '0ms'; 18674 } 18675 isScaling = true; 18676 } 18677 function onGestureChange(e) { 18678 if (!eventWithinSlide(e)) return; 18679 const params = swiper.params.zoom; 18680 const zoom = swiper.zoom; 18681 const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId); 18682 if (pointerIndex >= 0) evCache[pointerIndex] = e; 18683 if (evCache.length < 2) { 18684 return; 18685 } 18686 fakeGestureMoved = true; 18687 gesture.scaleMove = getDistanceBetweenTouches(); 18688 if (!gesture.imageEl) { 18689 return; 18690 } 18691 zoom.scale = gesture.scaleMove / gesture.scaleStart * currentScale; 18692 if (zoom.scale > gesture.maxRatio) { 18693 zoom.scale = gesture.maxRatio - 1 + (zoom.scale - gesture.maxRatio + 1) ** 0.5; 18694 } 18695 if (zoom.scale < params.minRatio) { 18696 zoom.scale = params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5; 18697 } 18698 gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`; 18699 } 18700 function onGestureEnd(e) { 18701 if (!eventWithinSlide(e)) return; 18702 if (e.pointerType === 'mouse' && e.type === 'pointerout') return; 18703 const params = swiper.params.zoom; 18704 const zoom = swiper.zoom; 18705 const pointerIndex = evCache.findIndex(cachedEv => cachedEv.pointerId === e.pointerId); 18706 if (pointerIndex >= 0) evCache.splice(pointerIndex, 1); 18707 if (!fakeGestureTouched || !fakeGestureMoved) { 18708 return; 18709 } 18710 fakeGestureTouched = false; 18711 fakeGestureMoved = false; 18712 if (!gesture.imageEl) return; 18713 zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio); 18714 gesture.imageEl.style.transitionDuration = `${swiper.params.speed}ms`; 18715 gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`; 18716 currentScale = zoom.scale; 18717 isScaling = false; 18718 if (zoom.scale > 1 && gesture.slideEl) { 18719 gesture.slideEl.classList.add(`${params.zoomedSlideClass}`); 18720 } else if (zoom.scale <= 1 && gesture.slideEl) { 18721 gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`); 18722 } 18723 if (zoom.scale === 1) { 18724 gesture.originX = 0; 18725 gesture.originY = 0; 18726 gesture.slideEl = undefined; 18727 } 18728 } 18729 let allowTouchMoveTimeout; 18730 function allowTouchMove() { 18731 swiper.touchEventsData.preventTouchMoveFromPointerMove = false; 18732 } 18733 function preventTouchMove() { 18734 clearTimeout(allowTouchMoveTimeout); 18735 swiper.touchEventsData.preventTouchMoveFromPointerMove = true; 18736 allowTouchMoveTimeout = setTimeout(() => { 18737 if (swiper.destroyed) return; 18738 allowTouchMove(); 18739 }); 18740 } 18741 function onTouchStart(e) { 18742 const device = swiper.device; 18743 if (!gesture.imageEl) return; 18744 if (image.isTouched) return; 18745 if (device.android && e.cancelable) e.preventDefault(); 18746 image.isTouched = true; 18747 const event = evCache.length > 0 ? evCache[0] : e; 18748 image.touchesStart.x = event.pageX; 18749 image.touchesStart.y = event.pageY; 18750 } 18751 function onTouchMove(e) { 18752 const isMouseEvent = e.pointerType === 'mouse'; 18753 const isMousePan = isMouseEvent && swiper.params.zoom.panOnMouseMove; 18754 if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) { 18755 return; 18756 } 18757 const zoom = swiper.zoom; 18758 if (!gesture.imageEl) { 18759 return; 18760 } 18761 if (!image.isTouched || !gesture.slideEl) { 18762 if (isMousePan) onMouseMove(e); 18763 return; 18764 } 18765 if (isMousePan) { 18766 onMouseMove(e); 18767 return; 18768 } 18769 if (!image.isMoved) { 18770 image.width = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth; 18771 image.height = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight; 18772 image.startX = getTranslate(gesture.imageWrapEl, 'x') || 0; 18773 image.startY = getTranslate(gesture.imageWrapEl, 'y') || 0; 18774 gesture.slideWidth = gesture.slideEl.offsetWidth; 18775 gesture.slideHeight = gesture.slideEl.offsetHeight; 18776 gesture.imageWrapEl.style.transitionDuration = '0ms'; 18777 } 18778 // Define if we need image drag 18779 const scaledWidth = image.width * zoom.scale; 18780 const scaledHeight = image.height * zoom.scale; 18781 image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0); 18782 image.maxX = -image.minX; 18783 image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0); 18784 image.maxY = -image.minY; 18785 image.touchesCurrent.x = evCache.length > 0 ? evCache[0].pageX : e.pageX; 18786 image.touchesCurrent.y = evCache.length > 0 ? evCache[0].pageY : e.pageY; 18787 const touchesDiff = Math.max(Math.abs(image.touchesCurrent.x - image.touchesStart.x), Math.abs(image.touchesCurrent.y - image.touchesStart.y)); 18788 if (touchesDiff > 5) { 18789 swiper.allowClick = false; 18790 } 18791 if (!image.isMoved && !isScaling) { 18792 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)) { 18793 image.isTouched = false; 18794 allowTouchMove(); 18795 return; 18796 } 18797 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)) { 18798 image.isTouched = false; 18799 allowTouchMove(); 18800 return; 18801 } 18802 } 18803 if (e.cancelable) { 18804 e.preventDefault(); 18805 } 18806 e.stopPropagation(); 18807 preventTouchMove(); 18808 image.isMoved = true; 18809 const scaleRatio = (zoom.scale - currentScale) / (gesture.maxRatio - swiper.params.zoom.minRatio); 18810 const { 18811 originX, 18812 originY 18813 } = gesture; 18814 image.currentX = image.touchesCurrent.x - image.touchesStart.x + image.startX + scaleRatio * (image.width - originX * 2); 18815 image.currentY = image.touchesCurrent.y - image.touchesStart.y + image.startY + scaleRatio * (image.height - originY * 2); 18816 if (image.currentX < image.minX) { 18817 image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8; 18818 } 18819 if (image.currentX > image.maxX) { 18820 image.currentX = image.maxX - 1 + (image.currentX - image.maxX + 1) ** 0.8; 18821 } 18822 if (image.currentY < image.minY) { 18823 image.currentY = image.minY + 1 - (image.minY - image.currentY + 1) ** 0.8; 18824 } 18825 if (image.currentY > image.maxY) { 18826 image.currentY = image.maxY - 1 + (image.currentY - image.maxY + 1) ** 0.8; 18827 } 18828 18829 // Velocity 18830 if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x; 18831 if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y; 18832 if (!velocity.prevTime) velocity.prevTime = Date.now(); 18833 velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2; 18834 velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2; 18835 if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0; 18836 if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0; 18837 velocity.prevPositionX = image.touchesCurrent.x; 18838 velocity.prevPositionY = image.touchesCurrent.y; 18839 velocity.prevTime = Date.now(); 18840 gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`; 18841 } 18842 function onTouchEnd() { 18843 const zoom = swiper.zoom; 18844 evCache.length = 0; 18845 if (!gesture.imageEl) return; 18846 if (!image.isTouched || !image.isMoved) { 18847 image.isTouched = false; 18848 image.isMoved = false; 18849 return; 18850 } 18851 image.isTouched = false; 18852 image.isMoved = false; 18853 let momentumDurationX = 300; 18854 let momentumDurationY = 300; 18855 const momentumDistanceX = velocity.x * momentumDurationX; 18856 const newPositionX = image.currentX + momentumDistanceX; 18857 const momentumDistanceY = velocity.y * momentumDurationY; 18858 const newPositionY = image.currentY + momentumDistanceY; 18859 18860 // Fix duration 18861 if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x); 18862 if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y); 18863 const momentumDuration = Math.max(momentumDurationX, momentumDurationY); 18864 image.currentX = newPositionX; 18865 image.currentY = newPositionY; 18866 // Define if we need image drag 18867 const scaledWidth = image.width * zoom.scale; 18868 const scaledHeight = image.height * zoom.scale; 18869 image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0); 18870 image.maxX = -image.minX; 18871 image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0); 18872 image.maxY = -image.minY; 18873 image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX); 18874 image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY); 18875 gesture.imageWrapEl.style.transitionDuration = `${momentumDuration}ms`; 18876 gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`; 18877 } 18878 function onTransitionEnd() { 18879 const zoom = swiper.zoom; 18880 if (gesture.slideEl && swiper.activeIndex !== swiper.slides.indexOf(gesture.slideEl)) { 18881 if (gesture.imageEl) { 18882 gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)'; 18883 } 18884 if (gesture.imageWrapEl) { 18885 gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)'; 18886 } 18887 gesture.slideEl.classList.remove(`${swiper.params.zoom.zoomedSlideClass}`); 18888 zoom.scale = 1; 18889 currentScale = 1; 18890 gesture.slideEl = undefined; 18891 gesture.imageEl = undefined; 18892 gesture.imageWrapEl = undefined; 18893 gesture.originX = 0; 18894 gesture.originY = 0; 18895 } 18896 } 18897 function onMouseMove(e) { 18898 // Only pan if zoomed in and mouse panning is enabled 18899 if (currentScale <= 1 || !gesture.imageWrapEl) return; 18900 if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) return; 18901 const currentTransform = window.getComputedStyle(gesture.imageWrapEl).transform; 18902 const matrix = new window.DOMMatrix(currentTransform); 18903 if (!isPanningWithMouse) { 18904 isPanningWithMouse = true; 18905 mousePanStart.x = e.clientX; 18906 mousePanStart.y = e.clientY; 18907 image.startX = matrix.e; 18908 image.startY = matrix.f; 18909 image.width = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth; 18910 image.height = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight; 18911 gesture.slideWidth = gesture.slideEl.offsetWidth; 18912 gesture.slideHeight = gesture.slideEl.offsetHeight; 18913 return; 18914 } 18915 const deltaX = (e.clientX - mousePanStart.x) * mousePanSensitivity; 18916 const deltaY = (e.clientY - mousePanStart.y) * mousePanSensitivity; 18917 const scaledWidth = image.width * currentScale; 18918 const scaledHeight = image.height * currentScale; 18919 const slideWidth = gesture.slideWidth; 18920 const slideHeight = gesture.slideHeight; 18921 const minX = Math.min(slideWidth / 2 - scaledWidth / 2, 0); 18922 const maxX = -minX; 18923 const minY = Math.min(slideHeight / 2 - scaledHeight / 2, 0); 18924 const maxY = -minY; 18925 const newX = Math.max(Math.min(image.startX + deltaX, maxX), minX); 18926 const newY = Math.max(Math.min(image.startY + deltaY, maxY), minY); 18927 gesture.imageWrapEl.style.transitionDuration = '0ms'; 18928 gesture.imageWrapEl.style.transform = `translate3d(${newX}px, ${newY}px, 0)`; 18929 mousePanStart.x = e.clientX; 18930 mousePanStart.y = e.clientY; 18931 image.startX = newX; 18932 image.startY = newY; 18933 image.currentX = newX; 18934 image.currentY = newY; 18935 } 18936 function zoomIn(e) { 18937 const zoom = swiper.zoom; 18938 const params = swiper.params.zoom; 18939 if (!gesture.slideEl) { 18940 if (e && e.target) { 18941 gesture.slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`); 18942 } 18943 if (!gesture.slideEl) { 18944 if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) { 18945 gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0]; 18946 } else { 18947 gesture.slideEl = swiper.slides[swiper.activeIndex]; 18948 } 18949 } 18950 let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`); 18951 if (imageEl) { 18952 imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0]; 18953 } 18954 gesture.imageEl = imageEl; 18955 if (imageEl) { 18956 gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0]; 18957 } else { 18958 gesture.imageWrapEl = undefined; 18959 } 18960 } 18961 if (!gesture.imageEl || !gesture.imageWrapEl) return; 18962 if (swiper.params.cssMode) { 18963 swiper.wrapperEl.style.overflow = 'hidden'; 18964 swiper.wrapperEl.style.touchAction = 'none'; 18965 } 18966 gesture.slideEl.classList.add(`${params.zoomedSlideClass}`); 18967 let touchX; 18968 let touchY; 18969 let offsetX; 18970 let offsetY; 18971 let diffX; 18972 let diffY; 18973 let translateX; 18974 let translateY; 18975 let imageWidth; 18976 let imageHeight; 18977 let scaledWidth; 18978 let scaledHeight; 18979 let translateMinX; 18980 let translateMinY; 18981 let translateMaxX; 18982 let translateMaxY; 18983 let slideWidth; 18984 let slideHeight; 18985 if (typeof image.touchesStart.x === 'undefined' && e) { 18986 touchX = e.pageX; 18987 touchY = e.pageY; 18988 } else { 18989 touchX = image.touchesStart.x; 18990 touchY = image.touchesStart.y; 18991 } 18992 const prevScale = currentScale; 18993 const forceZoomRatio = typeof e === 'number' ? e : null; 18994 if (currentScale === 1 && forceZoomRatio) { 18995 touchX = undefined; 18996 touchY = undefined; 18997 image.touchesStart.x = undefined; 18998 image.touchesStart.y = undefined; 18999 } 19000 const maxRatio = getMaxRatio(); 19001 zoom.scale = forceZoomRatio || maxRatio; 19002 currentScale = forceZoomRatio || maxRatio; 19003 if (e && !(currentScale === 1 && forceZoomRatio)) { 19004 slideWidth = gesture.slideEl.offsetWidth; 19005 slideHeight = gesture.slideEl.offsetHeight; 19006 offsetX = elementOffset(gesture.slideEl).left + window.scrollX; 19007 offsetY = elementOffset(gesture.slideEl).top + window.scrollY; 19008 diffX = offsetX + slideWidth / 2 - touchX; 19009 diffY = offsetY + slideHeight / 2 - touchY; 19010 imageWidth = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth; 19011 imageHeight = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight; 19012 scaledWidth = imageWidth * zoom.scale; 19013 scaledHeight = imageHeight * zoom.scale; 19014 translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0); 19015 translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0); 19016 translateMaxX = -translateMinX; 19017 translateMaxY = -translateMinY; 19018 if (prevScale > 0 && forceZoomRatio && typeof image.currentX === 'number' && typeof image.currentY === 'number') { 19019 translateX = image.currentX * zoom.scale / prevScale; 19020 translateY = image.currentY * zoom.scale / prevScale; 19021 } else { 19022 translateX = diffX * zoom.scale; 19023 translateY = diffY * zoom.scale; 19024 } 19025 if (translateX < translateMinX) { 19026 translateX = translateMinX; 19027 } 19028 if (translateX > translateMaxX) { 19029 translateX = translateMaxX; 19030 } 19031 if (translateY < translateMinY) { 19032 translateY = translateMinY; 19033 } 19034 if (translateY > translateMaxY) { 19035 translateY = translateMaxY; 19036 } 19037 } else { 19038 translateX = 0; 19039 translateY = 0; 19040 } 19041 if (forceZoomRatio && zoom.scale === 1) { 19042 gesture.originX = 0; 19043 gesture.originY = 0; 19044 } 19045 image.currentX = translateX; 19046 image.currentY = translateY; 19047 gesture.imageWrapEl.style.transitionDuration = '300ms'; 19048 gesture.imageWrapEl.style.transform = `translate3d(${translateX}px, ${translateY}px,0)`; 19049 gesture.imageEl.style.transitionDuration = '300ms'; 19050 gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`; 19051 } 19052 function zoomOut() { 19053 const zoom = swiper.zoom; 19054 const params = swiper.params.zoom; 19055 if (!gesture.slideEl) { 19056 if (swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual) { 19057 gesture.slideEl = elementChildren(swiper.slidesEl, `.${swiper.params.slideActiveClass}`)[0]; 19058 } else { 19059 gesture.slideEl = swiper.slides[swiper.activeIndex]; 19060 } 19061 let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`); 19062 if (imageEl) { 19063 imageEl = imageEl.querySelectorAll('picture, img, svg, canvas, .swiper-zoom-target')[0]; 19064 } 19065 gesture.imageEl = imageEl; 19066 if (imageEl) { 19067 gesture.imageWrapEl = elementParents(gesture.imageEl, `.${params.containerClass}`)[0]; 19068 } else { 19069 gesture.imageWrapEl = undefined; 19070 } 19071 } 19072 if (!gesture.imageEl || !gesture.imageWrapEl) return; 19073 if (swiper.params.cssMode) { 19074 swiper.wrapperEl.style.overflow = ''; 19075 swiper.wrapperEl.style.touchAction = ''; 19076 } 19077 zoom.scale = 1; 19078 currentScale = 1; 19079 image.currentX = undefined; 19080 image.currentY = undefined; 19081 image.touchesStart.x = undefined; 19082 image.touchesStart.y = undefined; 19083 gesture.imageWrapEl.style.transitionDuration = '300ms'; 19084 gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)'; 19085 gesture.imageEl.style.transitionDuration = '300ms'; 19086 gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)'; 19087 gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`); 19088 gesture.slideEl = undefined; 19089 gesture.originX = 0; 19090 gesture.originY = 0; 19091 if (swiper.params.zoom.panOnMouseMove) { 19092 mousePanStart = { 19093 x: 0, 19094 y: 0 19095 }; 19096 if (isPanningWithMouse) { 19097 isPanningWithMouse = false; 19098 image.startX = 0; 19099 image.startY = 0; 19100 } 19101 } 19102 } 19103 19104 // Toggle Zoom 19105 function zoomToggle(e) { 19106 const zoom = swiper.zoom; 19107 if (zoom.scale && zoom.scale !== 1) { 19108 // Zoom Out 19109 zoomOut(); 19110 } else { 19111 // Zoom In 19112 zoomIn(e); 19113 } 19114 } 19115 function getListeners() { 19116 const passiveListener = swiper.params.passiveListeners ? { 19117 passive: true, 19118 capture: false 19119 } : false; 19120 const activeListenerWithCapture = swiper.params.passiveListeners ? { 19121 passive: false, 19122 capture: true 19123 } : true; 19124 return { 19125 passiveListener, 19126 activeListenerWithCapture 19127 }; 19128 } 19129 19130 // Attach/Detach Events 19131 function enable() { 19132 const zoom = swiper.zoom; 19133 if (zoom.enabled) return; 19134 zoom.enabled = true; 19135 const { 19136 passiveListener, 19137 activeListenerWithCapture 19138 } = getListeners(); 19139 19140 // Scale image 19141 swiper.wrapperEl.addEventListener('pointerdown', onGestureStart, passiveListener); 19142 swiper.wrapperEl.addEventListener('pointermove', onGestureChange, activeListenerWithCapture); 19143 ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => { 19144 swiper.wrapperEl.addEventListener(eventName, onGestureEnd, passiveListener); 19145 }); 19146 19147 // Move image 19148 swiper.wrapperEl.addEventListener('pointermove', onTouchMove, activeListenerWithCapture); 19149 } 19150 function disable() { 19151 const zoom = swiper.zoom; 19152 if (!zoom.enabled) return; 19153 zoom.enabled = false; 19154 const { 19155 passiveListener, 19156 activeListenerWithCapture 19157 } = getListeners(); 19158 19159 // Scale image 19160 swiper.wrapperEl.removeEventListener('pointerdown', onGestureStart, passiveListener); 19161 swiper.wrapperEl.removeEventListener('pointermove', onGestureChange, activeListenerWithCapture); 19162 ['pointerup', 'pointercancel', 'pointerout'].forEach(eventName => { 19163 swiper.wrapperEl.removeEventListener(eventName, onGestureEnd, passiveListener); 19164 }); 19165 19166 // Move image 19167 swiper.wrapperEl.removeEventListener('pointermove', onTouchMove, activeListenerWithCapture); 19168 } 19169 on('init', () => { 19170 if (swiper.params.zoom.enabled) { 19171 enable(); 19172 } 19173 }); 19174 on('destroy', () => { 19175 disable(); 19176 }); 19177 on('touchStart', (_s, e) => { 19178 if (!swiper.zoom.enabled) return; 19179 onTouchStart(e); 19180 }); 19181 on('touchEnd', (_s, e) => { 19182 if (!swiper.zoom.enabled) return; 19183 onTouchEnd(); 19184 }); 19185 on('doubleTap', (_s, e) => { 19186 if (!swiper.animating && swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) { 19187 zoomToggle(e); 19188 } 19189 }); 19190 on('transitionEnd', () => { 19191 if (swiper.zoom.enabled && swiper.params.zoom.enabled) { 19192 onTransitionEnd(); 19193 } 19194 }); 19195 on('slideChange', () => { 19196 if (swiper.zoom.enabled && swiper.params.zoom.enabled && swiper.params.cssMode) { 19197 onTransitionEnd(); 19198 } 19199 }); 19200 Object.assign(swiper.zoom, { 19201 enable, 19202 disable, 19203 in: zoomIn, 19204 out: zoomOut, 19205 toggle: zoomToggle 19206 }); 19207} 19208 19209 19210 19211;// ./node_modules/swiper/modules/controller.mjs 19212 19213 19214/* eslint no-bitwise: ["error", { "allow": [">>"] }] */ 19215function Controller(_ref) { 19216 let { 19217 swiper, 19218 extendParams, 19219 on 19220 } = _ref; 19221 extendParams({ 19222 controller: { 19223 control: undefined, 19224 inverse: false, 19225 by: 'slide' // or 'container' 19226 } 19227 }); 19228 19229 swiper.controller = { 19230 control: undefined 19231 }; 19232 function LinearSpline(x, y) { 19233 const binarySearch = function search() { 19234 let maxIndex; 19235 let minIndex; 19236 let guess; 19237 return (array, val) => { 19238 minIndex = -1; 19239 maxIndex = array.length; 19240 while (maxIndex - minIndex > 1) { 19241 guess = maxIndex + minIndex >> 1; 19242 if (array[guess] <= val) { 19243 minIndex = guess; 19244 } else { 19245 maxIndex = guess; 19246 } 19247 } 19248 return maxIndex; 19249 }; 19250 }(); 19251 this.x = x; 19252 this.y = y; 19253 this.lastIndex = x.length - 1; 19254 // Given an x value (x2), return the expected y2 value: 19255 // (x1,y1) is the known point before given value, 19256 // (x3,y3) is the known point after given value. 19257 let i1; 19258 let i3; 19259 this.interpolate = function interpolate(x2) { 19260 if (!x2) return 0; 19261 19262 // Get the indexes of x1 and x3 (the array indexes before and after given x2): 19263 i3 = binarySearch(this.x, x2); 19264 i1 = i3 - 1; 19265 19266 // We have our indexes i1 & i3, so we can calculate already: 19267 // y2 := ((x2âx1) à (y3ây1)) ÷ (x3âx1) + y1 19268 return (x2 - this.x[i1]) * (this.y[i3] - this.y[i1]) / (this.x[i3] - this.x[i1]) + this.y[i1]; 19269 }; 19270 return this; 19271 } 19272 function getInterpolateFunction(c) { 19273 swiper.controller.spline = swiper.params.loop ? new LinearSpline(swiper.slidesGrid, c.slidesGrid) : new LinearSpline(swiper.snapGrid, c.snapGrid); 19274 } 19275 function setTranslate(_t, byController) { 19276 const controlled = swiper.controller.control; 19277 let multiplier; 19278 let controlledTranslate; 19279 const Swiper = swiper.constructor; 19280 function setControlledTranslate(c) { 19281 if (c.destroyed) return; 19282 19283 // this will create an Interpolate function based on the snapGrids 19284 // x is the Grid of the scrolled scroller and y will be the controlled scroller 19285 // it makes sense to create this only once and recall it for the interpolation 19286 // the function does a lot of value caching for performance 19287 const translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate; 19288 if (swiper.params.controller.by === 'slide') { 19289 getInterpolateFunction(c); 19290 // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid 19291 // but it did not work out 19292 controlledTranslate = -swiper.controller.spline.interpolate(-translate); 19293 } 19294 if (!controlledTranslate || swiper.params.controller.by === 'container') { 19295 multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate()); 19296 if (Number.isNaN(multiplier) || !Number.isFinite(multiplier)) { 19297 multiplier = 1; 19298 } 19299 controlledTranslate = (translate - swiper.minTranslate()) * multiplier + c.minTranslate(); 19300 } 19301 if (swiper.params.controller.inverse) { 19302 controlledTranslate = c.maxTranslate() - controlledTranslate; 19303 } 19304 c.updateProgress(controlledTranslate); 19305 c.setTranslate(controlledTranslate, swiper); 19306 c.updateActiveIndex(); 19307 c.updateSlidesClasses(); 19308 } 19309 if (Array.isArray(controlled)) { 19310 for (let i = 0; i < controlled.length; i += 1) { 19311 if (controlled[i] !== byController && controlled[i] instanceof Swiper) { 19312 setControlledTranslate(controlled[i]); 19313 } 19314 } 19315 } else if (controlled instanceof Swiper && byController !== controlled) { 19316 setControlledTranslate(controlled); 19317 } 19318 } 19319 function setTransition(duration, byController) { 19320 const Swiper = swiper.constructor; 19321 const controlled = swiper.controller.control; 19322 let i; 19323 function setControlledTransition(c) { 19324 if (c.destroyed) return; 19325 c.setTransition(duration, swiper); 19326 if (duration !== 0) { 19327 c.transitionStart(); 19328 if (c.params.autoHeight) { 19329 nextTick(() => { 19330 c.updateAutoHeight(); 19331 }); 19332 } 19333 elementTransitionEnd(c.wrapperEl, () => { 19334 if (!controlled) return; 19335 c.transitionEnd(); 19336 }); 19337 } 19338 } 19339 if (Array.isArray(controlled)) { 19340 for (i = 0; i < controlled.length; i += 1) { 19341 if (controlled[i] !== byController && controlled[i] instanceof Swiper) { 19342 setControlledTransition(controlled[i]); 19343 } 19344 } 19345 } else if (controlled instanceof Swiper && byController !== controlled) { 19346 setControlledTransition(controlled); 19347 } 19348 } 19349 function removeSpline() { 19350 if (!swiper.controller.control) return; 19351 if (swiper.controller.spline) { 19352 swiper.controller.spline = undefined; 19353 delete swiper.controller.spline; 19354 } 19355 } 19356 on('beforeInit', () => { 19357 if (typeof window !== 'undefined' && ( 19358 // eslint-disable-line 19359 typeof swiper.params.controller.control === 'string' || swiper.params.controller.control instanceof HTMLElement)) { 19360 const controlElements = typeof swiper.params.controller.control === 'string' ? [...document.querySelectorAll(swiper.params.controller.control)] : [swiper.params.controller.control]; 19361 controlElements.forEach(controlElement => { 19362 if (!swiper.controller.control) swiper.controller.control = []; 19363 if (controlElement && controlElement.swiper) { 19364 swiper.controller.control.push(controlElement.swiper); 19365 } else if (controlElement) { 19366 const eventName = `${swiper.params.eventsPrefix}init`; 19367 const onControllerSwiper = e => { 19368 swiper.controller.control.push(e.detail[0]); 19369 swiper.update(); 19370 controlElement.removeEventListener(eventName, onControllerSwiper); 19371 }; 19372 controlElement.addEventListener(eventName, onControllerSwiper); 19373 } 19374 }); 19375 return; 19376 } 19377 swiper.controller.control = swiper.params.controller.control; 19378 }); 19379 on('update', () => { 19380 removeSpline(); 19381 }); 19382 on('resize', () => { 19383 removeSpline(); 19384 }); 19385 on('observerUpdate', () => { 19386 removeSpline(); 19387 }); 19388 on('setTranslate', (_s, translate, byController) => { 19389 if (!swiper.controller.control || swiper.controller.control.destroyed) return; 19390 swiper.controller.setTranslate(translate, byController); 19391 }); 19392 on('setTransition', (_s, duration, byController) => { 19393 if (!swiper.controller.control || swiper.controller.control.destroyed) return; 19394 swiper.controller.setTransition(duration, byController); 19395 }); 19396 Object.assign(swiper.controller, { 19397 setTranslate, 19398 setTransition 19399 }); 19400} 19401 19402 19403 19404;// ./node_modules/swiper/modules/a11y.mjs 19405 19406 19407 19408 19409function A11y(_ref) { 19410 let { 19411 swiper, 19412 extendParams, 19413 on 19414 } = _ref; 19415 extendParams({ 19416 a11y: { 19417 enabled: true, 19418 notificationClass: 'swiper-notification', 19419 prevSlideMessage: 'Previous slide', 19420 nextSlideMessage: 'Next slide', 19421 firstSlideMessage: 'This is the first slide', 19422 lastSlideMessage: 'This is the last slide', 19423 paginationBulletMessage: 'Go to slide {{index}}', 19424 slideLabelMessage: '{{index}} / {{slidesLength}}', 19425 containerMessage: null, 19426 containerRoleDescriptionMessage: null, 19427 containerRole: null, 19428 itemRoleDescriptionMessage: null, 19429 slideRole: 'group', 19430 id: null, 19431 scrollOnFocus: true 19432 } 19433 }); 19434 swiper.a11y = { 19435 clicked: false 19436 }; 19437 let liveRegion = null; 19438 let preventFocusHandler; 19439 let focusTargetSlideEl; 19440 let visibilityChangedTimestamp = new Date().getTime(); 19441 function notify(message) { 19442 const notification = liveRegion; 19443 if (notification.length === 0) return; 19444 setInnerHTML(notification, message); 19445 } 19446 function getRandomNumber(size) { 19447 if (size === void 0) { 19448 size = 16; 19449 } 19450 const randomChar = () => Math.round(16 * Math.random()).toString(16); 19451 return 'x'.repeat(size).replace(/x/g, randomChar); 19452 } 19453 function makeElFocusable(el) { 19454 el = makeElementsArray(el); 19455 el.forEach(subEl => { 19456 subEl.setAttribute('tabIndex', '0'); 19457 }); 19458 } 19459 function makeElNotFocusable(el) { 19460 el = makeElementsArray(el); 19461 el.forEach(subEl => { 19462 subEl.setAttribute('tabIndex', '-1'); 19463 }); 19464 } 19465 function addElRole(el, role) { 19466 el = makeElementsArray(el); 19467 el.forEach(subEl => { 19468 subEl.setAttribute('role', role); 19469 }); 19470 } 19471 function addElRoleDescription(el, description) { 19472 el = makeElementsArray(el); 19473 el.forEach(subEl => { 19474 subEl.setAttribute('aria-roledescription', description); 19475 }); 19476 } 19477 function addElControls(el, controls) { 19478 el = makeElementsArray(el); 19479 el.forEach(subEl => { 19480 subEl.setAttribute('aria-controls', controls); 19481 }); 19482 } 19483 function addElLabel(el, label) { 19484 el = makeElementsArray(el); 19485 el.forEach(subEl => { 19486 subEl.setAttribute('aria-label', label); 19487 }); 19488 } 19489 function addElId(el, id) { 19490 el = makeElementsArray(el); 19491 el.forEach(subEl => { 19492 subEl.setAttribute('id', id); 19493 }); 19494 } 19495 function addElLive(el, live) { 19496 el = makeElementsArray(el); 19497 el.forEach(subEl => { 19498 subEl.setAttribute('aria-live', live); 19499 }); 19500 } 19501 function disableEl(el) { 19502 el = makeElementsArray(el); 19503 el.forEach(subEl => { 19504 subEl.setAttribute('aria-disabled', true); 19505 }); 19506 } 19507 function enableEl(el) { 19508 el = makeElementsArray(el); 19509 el.forEach(subEl => { 19510 subEl.setAttribute('aria-disabled', false); 19511 }); 19512 } 19513 function onEnterOrSpaceKey(e) { 19514 if (e.keyCode !== 13 && e.keyCode !== 32) return; 19515 const params = swiper.params.a11y; 19516 const targetEl = e.target; 19517 if (swiper.pagination && swiper.pagination.el && (targetEl === swiper.pagination.el || swiper.pagination.el.contains(e.target))) { 19518 if (!e.target.matches(classesToSelector(swiper.params.pagination.bulletClass))) return; 19519 } 19520 if (swiper.navigation && swiper.navigation.prevEl && swiper.navigation.nextEl) { 19521 const prevEls = makeElementsArray(swiper.navigation.prevEl); 19522 const nextEls = makeElementsArray(swiper.navigation.nextEl); 19523 if (nextEls.includes(targetEl)) { 19524 if (!(swiper.isEnd && !swiper.params.loop)) { 19525 swiper.slideNext(); 19526 } 19527 if (swiper.isEnd) { 19528 notify(params.lastSlideMessage); 19529 } else { 19530 notify(params.nextSlideMessage); 19531 } 19532 } 19533 if (prevEls.includes(targetEl)) { 19534 if (!(swiper.isBeginning && !swiper.params.loop)) { 19535 swiper.slidePrev(); 19536 } 19537 if (swiper.isBeginning) { 19538 notify(params.firstSlideMessage); 19539 } else { 19540 notify(params.prevSlideMessage); 19541 } 19542 } 19543 } 19544 if (swiper.pagination && targetEl.matches(classesToSelector(swiper.params.pagination.bulletClass))) { 19545 targetEl.click(); 19546 } 19547 } 19548 function updateNavigation() { 19549 if (swiper.params.loop || swiper.params.rewind || !swiper.navigation) return; 19550 const { 19551 nextEl, 19552 prevEl 19553 } = swiper.navigation; 19554 if (prevEl) { 19555 if (swiper.isBeginning) { 19556 disableEl(prevEl); 19557 makeElNotFocusable(prevEl); 19558 } else { 19559 enableEl(prevEl); 19560 makeElFocusable(prevEl); 19561 } 19562 } 19563 if (nextEl) { 19564 if (swiper.isEnd) { 19565 disableEl(nextEl); 19566 makeElNotFocusable(nextEl); 19567 } else { 19568 enableEl(nextEl); 19569 makeElFocusable(nextEl); 19570 } 19571 } 19572 } 19573 function hasPagination() { 19574 return swiper.pagination && swiper.pagination.bullets && swiper.pagination.bullets.length; 19575 } 19576 function hasClickablePagination() { 19577 return hasPagination() && swiper.params.pagination.clickable; 19578 } 19579 function updatePagination() { 19580 const params = swiper.params.a11y; 19581 if (!hasPagination()) return; 19582 swiper.pagination.bullets.forEach(bulletEl => { 19583 if (swiper.params.pagination.clickable) { 19584 makeElFocusable(bulletEl); 19585 if (!swiper.params.pagination.renderBullet) { 19586 addElRole(bulletEl, 'button'); 19587 addElLabel(bulletEl, params.paginationBulletMessage.replace(/\{\{index\}\}/, elementIndex(bulletEl) + 1)); 19588 } 19589 } 19590 if (bulletEl.matches(classesToSelector(swiper.params.pagination.bulletActiveClass))) { 19591 bulletEl.setAttribute('aria-current', 'true'); 19592 } else { 19593 bulletEl.removeAttribute('aria-current'); 19594 } 19595 }); 19596 } 19597 const initNavEl = (el, wrapperId, message) => { 19598 makeElFocusable(el); 19599 if (el.tagName !== 'BUTTON') { 19600 addElRole(el, 'button'); 19601 el.addEventListener('keydown', onEnterOrSpaceKey); 19602 } 19603 addElLabel(el, message); 19604 addElControls(el, wrapperId); 19605 }; 19606 const handlePointerDown = e => { 19607 if (focusTargetSlideEl && focusTargetSlideEl !== e.target && !focusTargetSlideEl.contains(e.target)) { 19608 preventFocusHandler = true; 19609 } 19610 swiper.a11y.clicked = true; 19611 }; 19612 const handlePointerUp = () => { 19613 preventFocusHandler = false; 19614 requestAnimationFrame(() => { 19615 requestAnimationFrame(() => { 19616 if (!swiper.destroyed) { 19617 swiper.a11y.clicked = false; 19618 } 19619 }); 19620 }); 19621 }; 19622 const onVisibilityChange = e => { 19623 visibilityChangedTimestamp = new Date().getTime(); 19624 }; 19625 const handleFocus = e => { 19626 if (swiper.a11y.clicked || !swiper.params.a11y.scrollOnFocus) return; 19627 if (new Date().getTime() - visibilityChangedTimestamp < 100) return; 19628 const slideEl = e.target.closest(`.${swiper.params.slideClass}, swiper-slide`); 19629 if (!slideEl || !swiper.slides.includes(slideEl)) return; 19630 focusTargetSlideEl = slideEl; 19631 const isActive = swiper.slides.indexOf(slideEl) === swiper.activeIndex; 19632 const isVisible = swiper.params.watchSlidesProgress && swiper.visibleSlides && swiper.visibleSlides.includes(slideEl); 19633 if (isActive || isVisible) return; 19634 if (e.sourceCapabilities && e.sourceCapabilities.firesTouchEvents) return; 19635 if (swiper.isHorizontal()) { 19636 swiper.el.scrollLeft = 0; 19637 } else { 19638 swiper.el.scrollTop = 0; 19639 } 19640 requestAnimationFrame(() => { 19641 if (preventFocusHandler) return; 19642 if (swiper.params.loop) { 19643 swiper.slideToLoop(swiper.getSlideIndexWhenGrid(parseInt(slideEl.getAttribute('data-swiper-slide-index'))), 0); 19644 } else { 19645 swiper.slideTo(swiper.getSlideIndexWhenGrid(swiper.slides.indexOf(slideEl)), 0); 19646 } 19647 preventFocusHandler = false; 19648 }); 19649 }; 19650 const initSlides = () => { 19651 const params = swiper.params.a11y; 19652 if (params.itemRoleDescriptionMessage) { 19653 addElRoleDescription(swiper.slides, params.itemRoleDescriptionMessage); 19654 } 19655 if (params.slideRole) { 19656 addElRole(swiper.slides, params.slideRole); 19657 } 19658 const slidesLength = swiper.slides.length; 19659 if (params.slideLabelMessage) { 19660 swiper.slides.forEach((slideEl, index) => { 19661 const slideIndex = swiper.params.loop ? parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10) : index; 19662 const ariaLabelMessage = params.slideLabelMessage.replace(/\{\{index\}\}/, slideIndex + 1).replace(/\{\{slidesLength\}\}/, slidesLength); 19663 addElLabel(slideEl, ariaLabelMessage); 19664 }); 19665 } 19666 }; 19667 const init = () => { 19668 const params = swiper.params.a11y; 19669 swiper.el.append(liveRegion); 19670 19671 // Container 19672 const containerEl = swiper.el; 19673 if (params.containerRoleDescriptionMessage) { 19674 addElRoleDescription(containerEl, params.containerRoleDescriptionMessage); 19675 } 19676 if (params.containerMessage) { 19677 addElLabel(containerEl, params.containerMessage); 19678 } 19679 if (params.containerRole) { 19680 addElRole(containerEl, params.containerRole); 19681 } 19682 19683 // Wrapper 19684 const wrapperEl = swiper.wrapperEl; 19685 const wrapperId = params.id || wrapperEl.getAttribute('id') || `swiper-wrapper-${getRandomNumber(16)}`; 19686 const live = swiper.params.autoplay && swiper.params.autoplay.enabled ? 'off' : 'polite'; 19687 addElId(wrapperEl, wrapperId); 19688 addElLive(wrapperEl, live); 19689 19690 // Slide 19691 initSlides(); 19692 19693 // Navigation 19694 let { 19695 nextEl, 19696 prevEl 19697 } = swiper.navigation ? swiper.navigation : {}; 19698 nextEl = makeElementsArray(nextEl); 19699 prevEl = makeElementsArray(prevEl); 19700 if (nextEl) { 19701 nextEl.forEach(el => initNavEl(el, wrapperId, params.nextSlideMessage)); 19702 } 19703 if (prevEl) { 19704 prevEl.forEach(el => initNavEl(el, wrapperId, params.prevSlideMessage)); 19705 } 19706 19707 // Pagination 19708 if (hasClickablePagination()) { 19709 const paginationEl = makeElementsArray(swiper.pagination.el); 19710 paginationEl.forEach(el => { 19711 el.addEventListener('keydown', onEnterOrSpaceKey); 19712 }); 19713 } 19714 19715 // Tab focus 19716 const document = getDocument(); 19717 document.addEventListener('visibilitychange', onVisibilityChange); 19718 swiper.el.addEventListener('focus', handleFocus, true); 19719 swiper.el.addEventListener('focus', handleFocus, true); 19720 swiper.el.addEventListener('pointerdown', handlePointerDown, true); 19721 swiper.el.addEventListener('pointerup', handlePointerUp, true); 19722 }; 19723 function destroy() { 19724 if (liveRegion) liveRegion.remove(); 19725 let { 19726 nextEl, 19727 prevEl 19728 } = swiper.navigation ? swiper.navigation : {}; 19729 nextEl = makeElementsArray(nextEl); 19730 prevEl = makeElementsArray(prevEl); 19731 if (nextEl) { 19732 nextEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey)); 19733 } 19734 if (prevEl) { 19735 prevEl.forEach(el => el.removeEventListener('keydown', onEnterOrSpaceKey)); 19736 } 19737 19738 // Pagination 19739 if (hasClickablePagination()) { 19740 const paginationEl = makeElementsArray(swiper.pagination.el); 19741 paginationEl.forEach(el => { 19742 el.removeEventListener('keydown', onEnterOrSpaceKey); 19743 }); 19744 } 19745 const document = getDocument(); 19746 document.removeEventListener('visibilitychange', onVisibilityChange); 19747 // Tab focus 19748 if (swiper.el && typeof swiper.el !== 'string') { 19749 swiper.el.removeEventListener('focus', handleFocus, true); 19750 swiper.el.removeEventListener('pointerdown', handlePointerDown, true); 19751 swiper.el.removeEventListener('pointerup', handlePointerUp, true); 19752 } 19753 } 19754 on('beforeInit', () => { 19755 liveRegion = createElement('span', swiper.params.a11y.notificationClass); 19756 liveRegion.setAttribute('aria-live', 'assertive'); 19757 liveRegion.setAttribute('aria-atomic', 'true'); 19758 }); 19759 on('afterInit', () => { 19760 if (!swiper.params.a11y.enabled) return; 19761 init(); 19762 }); 19763 on('slidesLengthChange snapGridLengthChange slidesGridLengthChange', () => { 19764 if (!swiper.params.a11y.enabled) return; 19765 initSlides(); 19766 }); 19767 on('fromEdge toEdge afterInit lock unlock', () => { 19768 if (!swiper.params.a11y.enabled) return; 19769 updateNavigation(); 19770 }); 19771 on('paginationUpdate', () => { 19772 if (!swiper.params.a11y.enabled) return; 19773 updatePagination(); 19774 }); 19775 on('destroy', () => { 19776 if (!swiper.params.a11y.enabled) return; 19777 destroy(); 19778 }); 19779} 19780 19781 19782 19783;// ./node_modules/swiper/modules/history.mjs 19784 19785 19786function History(_ref) { 19787 let { 19788 swiper, 19789 extendParams, 19790 on 19791 } = _ref; 19792 extendParams({ 19793 history: { 19794 enabled: false, 19795 root: '', 19796 replaceState: false, 19797 key: 'slides', 19798 keepQuery: false 19799 } 19800 }); 19801 let initialized = false; 19802 let paths = {}; 19803 const slugify = text => { 19804 return text.toString().replace(/\s+/g, '-').replace(/[^\w-]+/g, '').replace(/--+/g, '-').replace(/^-+/, '').replace(/-+$/, ''); 19805 }; 19806 const getPathValues = urlOverride => { 19807 const window = getWindow(); 19808 let location; 19809 if (urlOverride) { 19810 location = new URL(urlOverride); 19811 } else { 19812 location = window.location; 19813 } 19814 const pathArray = location.pathname.slice(1).split('/').filter(part => part !== ''); 19815 const total = pathArray.length; 19816 const key = pathArray[total - 2]; 19817 const value = pathArray[total - 1]; 19818 return { 19819 key, 19820 value 19821 }; 19822 }; 19823 const setHistory = (key, index) => { 19824 const window = getWindow(); 19825 if (!initialized || !swiper.params.history.enabled) return; 19826 let location; 19827 if (swiper.params.url) { 19828 location = new URL(swiper.params.url); 19829 } else { 19830 location = window.location; 19831 } 19832 const slide = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${index}"]`) : swiper.slides[index]; 19833 let value = slugify(slide.getAttribute('data-history')); 19834 if (swiper.params.history.root.length > 0) { 19835 let root = swiper.params.history.root; 19836 if (root[root.length - 1] === '/') root = root.slice(0, root.length - 1); 19837 value = `${root}/${key ? `${key}/` : ''}${value}`; 19838 } else if (!location.pathname.includes(key)) { 19839 value = `${key ? `${key}/` : ''}${value}`; 19840 } 19841 if (swiper.params.history.keepQuery) { 19842 value += location.search; 19843 } 19844 const currentState = window.history.state; 19845 if (currentState && currentState.value === value) { 19846 return; 19847 } 19848 if (swiper.params.history.replaceState) { 19849 window.history.replaceState({ 19850 value 19851 }, null, value); 19852 } else { 19853 window.history.pushState({ 19854 value 19855 }, null, value); 19856 } 19857 }; 19858 const scrollToSlide = (speed, value, runCallbacks) => { 19859 if (value) { 19860 for (let i = 0, length = swiper.slides.length; i < length; i += 1) { 19861 const slide = swiper.slides[i]; 19862 const slideHistory = slugify(slide.getAttribute('data-history')); 19863 if (slideHistory === value) { 19864 const index = swiper.getSlideIndex(slide); 19865 swiper.slideTo(index, speed, runCallbacks); 19866 } 19867 } 19868 } else { 19869 swiper.slideTo(0, speed, runCallbacks); 19870 } 19871 }; 19872 const setHistoryPopState = () => { 19873 paths = getPathValues(swiper.params.url); 19874 scrollToSlide(swiper.params.speed, paths.value, false); 19875 }; 19876 const init = () => { 19877 const window = getWindow(); 19878 if (!swiper.params.history) return; 19879 if (!window.history || !window.history.pushState) { 19880 swiper.params.history.enabled = false; 19881 swiper.params.hashNavigation.enabled = true; 19882 return; 19883 } 19884 initialized = true; 19885 paths = getPathValues(swiper.params.url); 19886 if (!paths.key && !paths.value) { 19887 if (!swiper.params.history.replaceState) { 19888 window.addEventListener('popstate', setHistoryPopState); 19889 } 19890 return; 19891 } 19892 scrollToSlide(0, paths.value, swiper.params.runCallbacksOnInit); 19893 if (!swiper.params.history.replaceState) { 19894 window.addEventListener('popstate', setHistoryPopState); 19895 } 19896 }; 19897 const destroy = () => { 19898 const window = getWindow(); 19899 if (!swiper.params.history.replaceState) { 19900 window.removeEventListener('popstate', setHistoryPopState); 19901 } 19902 }; 19903 on('init', () => { 19904 if (swiper.params.history.enabled) { 19905 init(); 19906 } 19907 }); 19908 on('destroy', () => { 19909 if (swiper.params.history.enabled) { 19910 destroy(); 19911 } 19912 }); 19913 on('transitionEnd _freeModeNoMomentumRelease', () => { 19914 if (initialized) { 19915 setHistory(swiper.params.history.key, swiper.activeIndex); 19916 } 19917 }); 19918 on('slideChange', () => { 19919 if (initialized && swiper.params.cssMode) { 19920 setHistory(swiper.params.history.key, swiper.activeIndex); 19921 } 19922 }); 19923} 19924 19925 19926 19927;// ./node_modules/swiper/modules/hash-navigation.mjs 19928 19929 19930 19931function HashNavigation(_ref) { 19932 let { 19933 swiper, 19934 extendParams, 19935 emit, 19936 on 19937 } = _ref; 19938 let initialized = false; 19939 const document = getDocument(); 19940 const window = getWindow(); 19941 extendParams({ 19942 hashNavigation: { 19943 enabled: false, 19944 replaceState: false, 19945 watchState: false, 19946 getSlideIndex(_s, hash) { 19947 if (swiper.virtual && swiper.params.virtual.enabled) { 19948 const slideWithHash = swiper.slides.find(slideEl => slideEl.getAttribute('data-hash') === hash); 19949 if (!slideWithHash) return 0; 19950 const index = parseInt(slideWithHash.getAttribute('data-swiper-slide-index'), 10); 19951 return index; 19952 } 19953 return swiper.getSlideIndex(elementChildren(swiper.slidesEl, `.${swiper.params.slideClass}[data-hash="${hash}"], swiper-slide[data-hash="${hash}"]`)[0]); 19954 } 19955 } 19956 }); 19957 const onHashChange = () => { 19958 emit('hashChange'); 19959 const newHash = document.location.hash.replace('#', ''); 19960 const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex]; 19961 const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') : ''; 19962 if (newHash !== activeSlideHash) { 19963 const newIndex = swiper.params.hashNavigation.getSlideIndex(swiper, newHash); 19964 if (typeof newIndex === 'undefined' || Number.isNaN(newIndex)) return; 19965 swiper.slideTo(newIndex); 19966 } 19967 }; 19968 const setHash = () => { 19969 if (!initialized || !swiper.params.hashNavigation.enabled) return; 19970 const activeSlideEl = swiper.virtual && swiper.params.virtual.enabled ? swiper.slidesEl.querySelector(`[data-swiper-slide-index="${swiper.activeIndex}"]`) : swiper.slides[swiper.activeIndex]; 19971 const activeSlideHash = activeSlideEl ? activeSlideEl.getAttribute('data-hash') || activeSlideEl.getAttribute('data-history') : ''; 19972 if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) { 19973 window.history.replaceState(null, null, `#${activeSlideHash}` || ''); 19974 emit('hashSet'); 19975 } else { 19976 document.location.hash = activeSlideHash || ''; 19977 emit('hashSet'); 19978 } 19979 }; 19980 const init = () => { 19981 if (!swiper.params.hashNavigation.enabled || swiper.params.history && swiper.params.history.enabled) return; 19982 initialized = true; 19983 const hash = document.location.hash.replace('#', ''); 19984 if (hash) { 19985 const speed = 0; 19986 const index = swiper.params.hashNavigation.getSlideIndex(swiper, hash); 19987 swiper.slideTo(index || 0, speed, swiper.params.runCallbacksOnInit, true); 19988 } 19989 if (swiper.params.hashNavigation.watchState) { 19990 window.addEventListener('hashchange', onHashChange); 19991 } 19992 }; 19993 const destroy = () => { 19994 if (swiper.params.hashNavigation.watchState) { 19995 window.removeEventListener('hashchange', onHashChange); 19996 } 19997 }; 19998 on('init', () => { 19999 if (swiper.params.hashNavigation.enabled) { 20000 init(); 20001 } 20002 }); 20003 on('destroy', () => { 20004 if (swiper.params.hashNavigation.enabled) { 20005 destroy(); 20006 } 20007 }); 20008 on('transitionEnd _freeModeNoMomentumRelease', () => { 20009 if (initialized) { 20010 setHash(); 20011 } 20012 }); 20013 on('slideChange', () => { 20014 if (initialized && swiper.params.cssMode) { 20015 setHash(); 20016 } 20017 }); 20018} 20019 20020 20021 20022;// ./node_modules/swiper/modules/autoplay.mjs 20023 20024 20025/* eslint no-underscore-dangle: "off" */ 20026/* eslint no-use-before-define: "off" */ 20027function Autoplay(_ref) { 20028 let { 20029 swiper, 20030 extendParams, 20031 on, 20032 emit, 20033 params 20034 } = _ref; 20035 swiper.autoplay = { 20036 running: false, 20037 paused: false, 20038 timeLeft: 0 20039 }; 20040 extendParams({ 20041 autoplay: { 20042 enabled: false, 20043 delay: 3000, 20044 waitForTransition: true, 20045 disableOnInteraction: false, 20046 stopOnLastSlide: false, 20047 reverseDirection: false, 20048 pauseOnMouseEnter: false 20049 } 20050 }); 20051 let timeout; 20052 let raf; 20053 let autoplayDelayTotal = params && params.autoplay ? params.autoplay.delay : 3000; 20054 let autoplayDelayCurrent = params && params.autoplay ? params.autoplay.delay : 3000; 20055 let autoplayTimeLeft; 20056 let autoplayStartTime = new Date().getTime(); 20057 let wasPaused; 20058 let isTouched; 20059 let pausedByTouch; 20060 let touchStartTimeout; 20061 let slideChanged; 20062 let pausedByInteraction; 20063 let pausedByPointerEnter; 20064 function onTransitionEnd(e) { 20065 if (!swiper || swiper.destroyed || !swiper.wrapperEl) return; 20066 if (e.target !== swiper.wrapperEl) return; 20067 swiper.wrapperEl.removeEventListener('transitionend', onTransitionEnd); 20068 if (pausedByPointerEnter || e.detail && e.detail.bySwiperTouchMove) { 20069 return; 20070 } 20071 resume(); 20072 } 20073 const calcTimeLeft = () => { 20074 if (swiper.destroyed || !swiper.autoplay.running) return; 20075 if (swiper.autoplay.paused) { 20076 wasPaused = true; 20077 } else if (wasPaused) { 20078 autoplayDelayCurrent = autoplayTimeLeft; 20079 wasPaused = false; 20080 } 20081 const timeLeft = swiper.autoplay.paused ? autoplayTimeLeft : autoplayStartTime + autoplayDelayCurrent - new Date().getTime(); 20082 swiper.autoplay.timeLeft = timeLeft; 20083 emit('autoplayTimeLeft', timeLeft, timeLeft / autoplayDelayTotal); 20084 raf = requestAnimationFrame(() => { 20085 calcTimeLeft(); 20086 }); 20087 }; 20088 const getSlideDelay = () => { 20089 let activeSlideEl; 20090 if (swiper.virtual && swiper.params.virtual.enabled) { 20091 activeSlideEl = swiper.slides.find(slideEl => slideEl.classList.contains('swiper-slide-active')); 20092 } else { 20093 activeSlideEl = swiper.slides[swiper.activeIndex]; 20094 } 20095 if (!activeSlideEl) return undefined; 20096 const currentSlideDelay = parseInt(activeSlideEl.getAttribute('data-swiper-autoplay'), 10); 20097 return currentSlideDelay; 20098 }; 20099 const run = delayForce => { 20100 if (swiper.destroyed || !swiper.autoplay.running) return; 20101 cancelAnimationFrame(raf); 20102 calcTimeLeft(); 20103 let delay = typeof delayForce === 'undefined' ? swiper.params.autoplay.delay : delayForce; 20104 autoplayDelayTotal = swiper.params.autoplay.delay; 20105 autoplayDelayCurrent = swiper.params.autoplay.delay; 20106 const currentSlideDelay = getSlideDelay(); 20107 if (!Number.isNaN(currentSlideDelay) && currentSlideDelay > 0 && typeof delayForce === 'undefined') { 20108 delay = currentSlideDelay; 20109 autoplayDelayTotal = currentSlideDelay; 20110 autoplayDelayCurrent = currentSlideDelay; 20111 } 20112 autoplayTimeLeft = delay; 20113 const speed = swiper.params.speed; 20114 const proceed = () => { 20115 if (!swiper || swiper.destroyed) return; 20116 if (swiper.params.autoplay.reverseDirection) { 20117 if (!swiper.isBeginning || swiper.params.loop || swiper.params.rewind) { 20118 swiper.slidePrev(speed, true, true); 20119 emit('autoplay'); 20120 } else if (!swiper.params.autoplay.stopOnLastSlide) { 20121 swiper.slideTo(swiper.slides.length - 1, speed, true, true); 20122 emit('autoplay'); 20123 } 20124 } else { 20125 if (!swiper.isEnd || swiper.params.loop || swiper.params.rewind) { 20126 swiper.slideNext(speed, true, true); 20127 emit('autoplay'); 20128 } else if (!swiper.params.autoplay.stopOnLastSlide) { 20129 swiper.slideTo(0, speed, true, true); 20130 emit('autoplay'); 20131 } 20132 } 20133 if (swiper.params.cssMode) { 20134 autoplayStartTime = new Date().getTime(); 20135 requestAnimationFrame(() => { 20136 run(); 20137 }); 20138 } 20139 }; 20140 if (delay > 0) { 20141 clearTimeout(timeout); 20142 timeout = setTimeout(() => { 20143 proceed(); 20144 }, delay); 20145 } else { 20146 requestAnimationFrame(() => { 20147 proceed(); 20148 }); 20149 } 20150 20151 // eslint-disable-next-line 20152 return delay; 20153 }; 20154 const start = () => { 20155 autoplayStartTime = new Date().getTime(); 20156 swiper.autoplay.running = true; 20157 run(); 20158 emit('autoplayStart'); 20159 }; 20160 const stop = () => { 20161 swiper.autoplay.running = false; 20162 clearTimeout(timeout); 20163 cancelAnimationFrame(raf); 20164 emit('autoplayStop'); 20165 }; 20166 const pause = (internal, reset) => { 20167 if (swiper.destroyed || !swiper.autoplay.running) return; 20168 clearTimeout(timeout); 20169 if (!internal) { 20170 pausedByInteraction = true; 20171 } 20172 const proceed = () => { 20173 emit('autoplayPause'); 20174 if (swiper.params.autoplay.waitForTransition) { 20175 swiper.wrapperEl.addEventListener('transitionend', onTransitionEnd); 20176 } else { 20177 resume(); 20178 } 20179 }; 20180 swiper.autoplay.paused = true; 20181 if (reset) { 20182 if (slideChanged) { 20183 autoplayTimeLeft = swiper.params.autoplay.delay; 20184 } 20185 slideChanged = false; 20186 proceed(); 20187 return; 20188 } 20189 const delay = autoplayTimeLeft || swiper.params.autoplay.delay; 20190 autoplayTimeLeft = delay - (new Date().getTime() - autoplayStartTime); 20191 if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop) return; 20192 if (autoplayTimeLeft < 0) autoplayTimeLeft = 0; 20193 proceed(); 20194 }; 20195 const resume = () => { 20196 if (swiper.isEnd && autoplayTimeLeft < 0 && !swiper.params.loop || swiper.destroyed || !swiper.autoplay.running) return; 20197 autoplayStartTime = new Date().getTime(); 20198 if (pausedByInteraction) { 20199 pausedByInteraction = false; 20200 run(autoplayTimeLeft); 20201 } else { 20202 run(); 20203 } 20204 swiper.autoplay.paused = false; 20205 emit('autoplayResume'); 20206 }; 20207 const onVisibilityChange = () => { 20208 if (swiper.destroyed || !swiper.autoplay.running) return; 20209 const document = ssr_window_esm_getDocument(); 20210 if (document.visibilityState === 'hidden') { 20211 pausedByInteraction = true; 20212 pause(true); 20213 } 20214 if (document.visibilityState === 'visible') { 20215 resume(); 20216 } 20217 }; 20218 const onPointerEnter = e => { 20219 if (e.pointerType !== 'mouse') return; 20220 pausedByInteraction = true; 20221 pausedByPointerEnter = true; 20222 if (swiper.animating || swiper.autoplay.paused) return; 20223 pause(true); 20224 }; 20225 const onPointerLeave = e => { 20226 if (e.pointerType !== 'mouse') return; 20227 pausedByPointerEnter = false; 20228 if (swiper.autoplay.paused) { 20229 resume(); 20230 } 20231 }; 20232 const attachMouseEvents = () => { 20233 if (swiper.params.autoplay.pauseOnMouseEnter) { 20234 swiper.el.addEventListener('pointerenter', onPointerEnter); 20235 swiper.el.addEventListener('pointerleave', onPointerLeave); 20236 } 20237 }; 20238 const detachMouseEvents = () => { 20239 if (swiper.el && typeof swiper.el !== 'string') { 20240 swiper.el.removeEventListener('pointerenter', onPointerEnter); 20241 swiper.el.removeEventListener('pointerleave', onPointerLeave); 20242 } 20243 }; 20244 const attachDocumentEvents = () => { 20245 const document = ssr_window_esm_getDocument(); 20246 document.addEventListener('visibilitychange', onVisibilityChange); 20247 }; 20248 const detachDocumentEvents = () => { 20249 const document = ssr_window_esm_getDocument(); 20250 document.removeEventListener('visibilitychange', onVisibilityChange); 20251 }; 20252 on('init', () => { 20253 if (swiper.params.autoplay.enabled) { 20254 attachMouseEvents(); 20255 attachDocumentEvents(); 20256 start(); 20257 } 20258 }); 20259 on('destroy', () => { 20260 detachMouseEvents(); 20261 detachDocumentEvents(); 20262 if (swiper.autoplay.running) { 20263 stop(); 20264 } 20265 }); 20266 on('_freeModeStaticRelease', () => { 20267 if (pausedByTouch || pausedByInteraction) { 20268 resume(); 20269 } 20270 }); 20271 on('_freeModeNoMomentumRelease', () => { 20272 if (!swiper.params.autoplay.disableOnInteraction) { 20273 pause(true, true); 20274 } else { 20275 stop(); 20276 } 20277 }); 20278 on('beforeTransitionStart', (_s, speed, internal) => { 20279 if (swiper.destroyed || !swiper.autoplay.running) return; 20280 if (internal || !swiper.params.autoplay.disableOnInteraction) { 20281 pause(true, true); 20282 } else { 20283 stop(); 20284 } 20285 }); 20286 on('sliderFirstMove', () => { 20287 if (swiper.destroyed || !swiper.autoplay.running) return; 20288 if (swiper.params.autoplay.disableOnInteraction) { 20289 stop(); 20290 return; 20291 } 20292 isTouched = true; 20293 pausedByTouch = false; 20294 pausedByInteraction = false; 20295 touchStartTimeout = setTimeout(() => { 20296 pausedByInteraction = true; 20297 pausedByTouch = true; 20298 pause(true); 20299 }, 200); 20300 }); 20301 on('touchEnd', () => { 20302 if (swiper.destroyed || !swiper.autoplay.running || !isTouched) return; 20303 clearTimeout(touchStartTimeout); 20304 clearTimeout(timeout); 20305 if (swiper.params.autoplay.disableOnInteraction) { 20306 pausedByTouch = false; 20307 isTouched = false; 20308 return; 20309 } 20310 if (pausedByTouch && swiper.params.cssMode) resume(); 20311 pausedByTouch = false; 20312 isTouched = false; 20313 }); 20314 on('slideChange', () => { 20315 if (swiper.destroyed || !swiper.autoplay.running) return; 20316 slideChanged = true; 20317 }); 20318 Object.assign(swiper.autoplay, { 20319 start, 20320 stop, 20321 pause, 20322 resume 20323 }); 20324} 20325 20326 20327 20328;// ./node_modules/swiper/modules/thumbs.mjs 20329 20330 20331 20332function Thumb(_ref) { 20333 let { 20334 swiper, 20335 extendParams, 20336 on 20337 } = _ref; 20338 extendParams({ 20339 thumbs: { 20340 swiper: null, 20341 multipleActiveThumbs: true, 20342 autoScrollOffset: 0, 20343 slideThumbActiveClass: 'swiper-slide-thumb-active', 20344 thumbsContainerClass: 'swiper-thumbs' 20345 } 20346 }); 20347 let initialized = false; 20348 let swiperCreated = false; 20349 swiper.thumbs = { 20350 swiper: null 20351 }; 20352 function onThumbClick() { 20353 const thumbsSwiper = swiper.thumbs.swiper; 20354 if (!thumbsSwiper || thumbsSwiper.destroyed) return; 20355 const clickedIndex = thumbsSwiper.clickedIndex; 20356 const clickedSlide = thumbsSwiper.clickedSlide; 20357 if (clickedSlide && clickedSlide.classList.contains(swiper.params.thumbs.slideThumbActiveClass)) return; 20358 if (typeof clickedIndex === 'undefined' || clickedIndex === null) return; 20359 let slideToIndex; 20360 if (thumbsSwiper.params.loop) { 20361 slideToIndex = parseInt(thumbsSwiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10); 20362 } else { 20363 slideToIndex = clickedIndex; 20364 } 20365 if (swiper.params.loop) { 20366 swiper.slideToLoop(slideToIndex); 20367 } else { 20368 swiper.slideTo(slideToIndex); 20369 } 20370 } 20371 function init() { 20372 const { 20373 thumbs: thumbsParams 20374 } = swiper.params; 20375 if (initialized) return false; 20376 initialized = true; 20377 const SwiperClass = swiper.constructor; 20378 if (thumbsParams.swiper instanceof SwiperClass) { 20379 if (thumbsParams.swiper.destroyed) { 20380 initialized = false; 20381 return false; 20382 } 20383 swiper.thumbs.swiper = thumbsParams.swiper; 20384 Object.assign(swiper.thumbs.swiper.originalParams, { 20385 watchSlidesProgress: true, 20386 slideToClickedSlide: false 20387 }); 20388 Object.assign(swiper.thumbs.swiper.params, { 20389 watchSlidesProgress: true, 20390 slideToClickedSlide: false 20391 }); 20392 swiper.thumbs.swiper.update(); 20393 } else if (isObject(thumbsParams.swiper)) { 20394 const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper); 20395 Object.assign(thumbsSwiperParams, { 20396 watchSlidesProgress: true, 20397 slideToClickedSlide: false 20398 }); 20399 swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams); 20400 swiperCreated = true; 20401 } 20402 swiper.thumbs.swiper.el.classList.add(swiper.params.thumbs.thumbsContainerClass); 20403 swiper.thumbs.swiper.on('tap', onThumbClick); 20404 return true; 20405 } 20406 function update(initial) { 20407 const thumbsSwiper = swiper.thumbs.swiper; 20408 if (!thumbsSwiper || thumbsSwiper.destroyed) return; 20409 const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' ? thumbsSwiper.slidesPerViewDynamic() : thumbsSwiper.params.slidesPerView; 20410 20411 // Activate thumbs 20412 let thumbsToActivate = 1; 20413 const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass; 20414 if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) { 20415 thumbsToActivate = swiper.params.slidesPerView; 20416 } 20417 if (!swiper.params.thumbs.multipleActiveThumbs) { 20418 thumbsToActivate = 1; 20419 } 20420 thumbsToActivate = Math.floor(thumbsToActivate); 20421 thumbsSwiper.slides.forEach(slideEl => slideEl.classList.remove(thumbActiveClass)); 20422 if (thumbsSwiper.params.loop || thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled) { 20423 for (let i = 0; i < thumbsToActivate; i += 1) { 20424 elementChildren(thumbsSwiper.slidesEl, `[data-swiper-slide-index="${swiper.realIndex + i}"]`).forEach(slideEl => { 20425 slideEl.classList.add(thumbActiveClass); 20426 }); 20427 } 20428 } else { 20429 for (let i = 0; i < thumbsToActivate; i += 1) { 20430 if (thumbsSwiper.slides[swiper.realIndex + i]) { 20431 thumbsSwiper.slides[swiper.realIndex + i].classList.add(thumbActiveClass); 20432 } 20433 } 20434 } 20435 const autoScrollOffset = swiper.params.thumbs.autoScrollOffset; 20436 const useOffset = autoScrollOffset && !thumbsSwiper.params.loop; 20437 if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) { 20438 const currentThumbsIndex = thumbsSwiper.activeIndex; 20439 let newThumbsIndex; 20440 let direction; 20441 if (thumbsSwiper.params.loop) { 20442 const newThumbsSlide = thumbsSwiper.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') === `${swiper.realIndex}`); 20443 newThumbsIndex = thumbsSwiper.slides.indexOf(newThumbsSlide); 20444 direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev'; 20445 } else { 20446 newThumbsIndex = swiper.realIndex; 20447 direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev'; 20448 } 20449 if (useOffset) { 20450 newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset; 20451 } 20452 if (thumbsSwiper.visibleSlidesIndexes && thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) { 20453 if (thumbsSwiper.params.centeredSlides) { 20454 if (newThumbsIndex > currentThumbsIndex) { 20455 newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1; 20456 } else { 20457 newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1; 20458 } 20459 } else if (newThumbsIndex > currentThumbsIndex && thumbsSwiper.params.slidesPerGroup === 1) ; 20460 thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined); 20461 } 20462 } 20463 } 20464 on('beforeInit', () => { 20465 const { 20466 thumbs 20467 } = swiper.params; 20468 if (!thumbs || !thumbs.swiper) return; 20469 if (typeof thumbs.swiper === 'string' || thumbs.swiper instanceof HTMLElement) { 20470 const document = getDocument(); 20471 const getThumbsElementAndInit = () => { 20472 const thumbsElement = typeof thumbs.swiper === 'string' ? document.querySelector(thumbs.swiper) : thumbs.swiper; 20473 if (thumbsElement && thumbsElement.swiper) { 20474 thumbs.swiper = thumbsElement.swiper; 20475 init(); 20476 update(true); 20477 } else if (thumbsElement) { 20478 const eventName = `${swiper.params.eventsPrefix}init`; 20479 const onThumbsSwiper = e => { 20480 thumbs.swiper = e.detail[0]; 20481 thumbsElement.removeEventListener(eventName, onThumbsSwiper); 20482 init(); 20483 update(true); 20484 thumbs.swiper.update(); 20485 swiper.update(); 20486 }; 20487 thumbsElement.addEventListener(eventName, onThumbsSwiper); 20488 } 20489 return thumbsElement; 20490 }; 20491 const watchForThumbsToAppear = () => { 20492 if (swiper.destroyed) return; 20493 const thumbsElement = getThumbsElementAndInit(); 20494 if (!thumbsElement) { 20495 requestAnimationFrame(watchForThumbsToAppear); 20496 } 20497 }; 20498 requestAnimationFrame(watchForThumbsToAppear); 20499 } else { 20500 init(); 20501 update(true); 20502 } 20503 }); 20504 on('slideChange update resize observerUpdate', () => { 20505 update(); 20506 }); 20507 on('setTransition', (_s, duration) => { 20508 const thumbsSwiper = swiper.thumbs.swiper; 20509 if (!thumbsSwiper || thumbsSwiper.destroyed) return; 20510 thumbsSwiper.setTransition(duration); 20511 }); 20512 on('beforeDestroy', () => { 20513 const thumbsSwiper = swiper.thumbs.swiper; 20514 if (!thumbsSwiper || thumbsSwiper.destroyed) return; 20515 if (swiperCreated) { 20516 thumbsSwiper.destroy(); 20517 } 20518 }); 20519 Object.assign(swiper.thumbs, { 20520 init, 20521 update 20522 }); 20523} 20524 20525 20526 20527;// ./node_modules/swiper/modules/free-mode.mjs 20528 20529 20530function freeMode(_ref) { 20531 let { 20532 swiper, 20533 extendParams, 20534 emit, 20535 once 20536 } = _ref; 20537 extendParams({ 20538 freeMode: { 20539 enabled: false, 20540 momentum: true, 20541 momentumRatio: 1, 20542 momentumBounce: true, 20543 momentumBounceRatio: 1, 20544 momentumVelocityRatio: 1, 20545 sticky: false, 20546 minimumVelocity: 0.02 20547 } 20548 }); 20549 function onTouchStart() { 20550 if (swiper.params.cssMode) return; 20551 const translate = swiper.getTranslate(); 20552 swiper.setTranslate(translate); 20553 swiper.setTransition(0); 20554 swiper.touchEventsData.velocities.length = 0; 20555 swiper.freeMode.onTouchEnd({ 20556 currentPos: swiper.rtl ? swiper.translate : -swiper.translate 20557 }); 20558 } 20559 function onTouchMove() { 20560 if (swiper.params.cssMode) return; 20561 const { 20562 touchEventsData: data, 20563 touches 20564 } = swiper; 20565 // Velocity 20566 if (data.velocities.length === 0) { 20567 data.velocities.push({ 20568 position: touches[swiper.isHorizontal() ? 'startX' : 'startY'], 20569 time: data.touchStartTime 20570 }); 20571 } 20572 data.velocities.push({ 20573 position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'], 20574 time: now() 20575 }); 20576 } 20577 function onTouchEnd(_ref2) { 20578 let { 20579 currentPos 20580 } = _ref2; 20581 if (swiper.params.cssMode) return; 20582 const { 20583 params, 20584 wrapperEl, 20585 rtlTranslate: rtl, 20586 snapGrid, 20587 touchEventsData: data 20588 } = swiper; 20589 // Time diff 20590 const touchEndTime = now(); 20591 const timeDiff = touchEndTime - data.touchStartTime; 20592 if (currentPos < -swiper.minTranslate()) { 20593 swiper.slideTo(swiper.activeIndex); 20594 return; 20595 } 20596 if (currentPos > -swiper.maxTranslate()) { 20597 if (swiper.slides.length < snapGrid.length) { 20598 swiper.slideTo(snapGrid.length - 1); 20599 } else { 20600 swiper.slideTo(swiper.slides.length - 1); 20601 } 20602 return; 20603 } 20604 if (params.freeMode.momentum) { 20605 if (data.velocities.length > 1) { 20606 const lastMoveEvent = data.velocities.pop(); 20607 const velocityEvent = data.velocities.pop(); 20608 const distance = lastMoveEvent.position - velocityEvent.position; 20609 const time = lastMoveEvent.time - velocityEvent.time; 20610 swiper.velocity = distance / time; 20611 swiper.velocity /= 2; 20612 if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) { 20613 swiper.velocity = 0; 20614 } 20615 // this implies that the user stopped moving a finger then released. 20616 // There would be no events with distance zero, so the last event is stale. 20617 if (time > 150 || now() - lastMoveEvent.time > 300) { 20618 swiper.velocity = 0; 20619 } 20620 } else { 20621 swiper.velocity = 0; 20622 } 20623 swiper.velocity *= params.freeMode.momentumVelocityRatio; 20624 data.velocities.length = 0; 20625 let momentumDuration = 1000 * params.freeMode.momentumRatio; 20626 const momentumDistance = swiper.velocity * momentumDuration; 20627 let newPosition = swiper.translate + momentumDistance; 20628 if (rtl) newPosition = -newPosition; 20629 let doBounce = false; 20630 let afterBouncePosition; 20631 const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio; 20632 let needsLoopFix; 20633 if (newPosition < swiper.maxTranslate()) { 20634 if (params.freeMode.momentumBounce) { 20635 if (newPosition + swiper.maxTranslate() < -bounceAmount) { 20636 newPosition = swiper.maxTranslate() - bounceAmount; 20637 } 20638 afterBouncePosition = swiper.maxTranslate(); 20639 doBounce = true; 20640 data.allowMomentumBounce = true; 20641 } else { 20642 newPosition = swiper.maxTranslate(); 20643 } 20644 if (params.loop && params.centeredSlides) needsLoopFix = true; 20645 } else if (newPosition > swiper.minTranslate()) { 20646 if (params.freeMode.momentumBounce) { 20647 if (newPosition - swiper.minTranslate() > bounceAmount) { 20648 newPosition = swiper.minTranslate() + bounceAmount; 20649 } 20650 afterBouncePosition = swiper.minTranslate(); 20651 doBounce = true; 20652 data.allowMomentumBounce = true; 20653 } else { 20654 newPosition = swiper.minTranslate(); 20655 } 20656 if (params.loop && params.centeredSlides) needsLoopFix = true; 20657 } else if (params.freeMode.sticky) { 20658 let nextSlide; 20659 for (let j = 0; j < snapGrid.length; j += 1) { 20660 if (snapGrid[j] > -newPosition) { 20661 nextSlide = j; 20662 break; 20663 } 20664 } 20665 if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') { 20666 newPosition = snapGrid[nextSlide]; 20667 } else { 20668 newPosition = snapGrid[nextSlide - 1]; 20669 } 20670 newPosition = -newPosition; 20671 } 20672 if (needsLoopFix) { 20673 once('transitionEnd', () => { 20674 swiper.loopFix(); 20675 }); 20676 } 20677 // Fix duration 20678 if (swiper.velocity !== 0) { 20679 if (rtl) { 20680 momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity); 20681 } else { 20682 momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity); 20683 } 20684 if (params.freeMode.sticky) { 20685 // If freeMode.sticky is active and the user ends a swipe with a slow-velocity 20686 // event, then durations can be 20+ seconds to slide one (or zero!) slides. 20687 // It's easy to see this when simulating touch with mouse events. To fix this, 20688 // limit single-slide swipes to the default slide duration. This also has the 20689 // nice side effect of matching slide speed if the user stopped moving before 20690 // lifting finger or mouse vs. moving slowly before lifting the finger/mouse. 20691 // For faster swipes, also apply limits (albeit higher ones). 20692 const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate); 20693 const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex]; 20694 if (moveDistance < currentSlideSize) { 20695 momentumDuration = params.speed; 20696 } else if (moveDistance < 2 * currentSlideSize) { 20697 momentumDuration = params.speed * 1.5; 20698 } else { 20699 momentumDuration = params.speed * 2.5; 20700 } 20701 } 20702 } else if (params.freeMode.sticky) { 20703 swiper.slideToClosest(); 20704 return; 20705 } 20706 if (params.freeMode.momentumBounce && doBounce) { 20707 swiper.updateProgress(afterBouncePosition); 20708 swiper.setTransition(momentumDuration); 20709 swiper.setTranslate(newPosition); 20710 swiper.transitionStart(true, swiper.swipeDirection); 20711 swiper.animating = true; 20712 elementTransitionEnd(wrapperEl, () => { 20713 if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return; 20714 emit('momentumBounce'); 20715 swiper.setTransition(params.speed); 20716 setTimeout(() => { 20717 swiper.setTranslate(afterBouncePosition); 20718 elementTransitionEnd(wrapperEl, () => { 20719 if (!swiper || swiper.destroyed) return; 20720 swiper.transitionEnd(); 20721 }); 20722 }, 0); 20723 }); 20724 } else if (swiper.velocity) { 20725 emit('_freeModeNoMomentumRelease'); 20726 swiper.updateProgress(newPosition); 20727 swiper.setTransition(momentumDuration); 20728 swiper.setTranslate(newPosition); 20729 swiper.transitionStart(true, swiper.swipeDirection); 20730 if (!swiper.animating) { 20731 swiper.animating = true; 20732 elementTransitionEnd(wrapperEl, () => { 20733 if (!swiper || swiper.destroyed) return; 20734 swiper.transitionEnd(); 20735 }); 20736 } 20737 } else { 20738 swiper.updateProgress(newPosition); 20739 } 20740 swiper.updateActiveIndex(); 20741 swiper.updateSlidesClasses(); 20742 } else if (params.freeMode.sticky) { 20743 swiper.slideToClosest(); 20744 return; 20745 } else if (params.freeMode) { 20746 emit('_freeModeNoMomentumRelease'); 20747 } 20748 if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) { 20749 emit('_freeModeStaticRelease'); 20750 swiper.updateProgress(); 20751 swiper.updateActiveIndex(); 20752 swiper.updateSlidesClasses(); 20753 } 20754 } 20755 Object.assign(swiper, { 20756 freeMode: { 20757 onTouchStart, 20758 onTouchMove, 20759 onTouchEnd 20760 } 20761 }); 20762} 20763 20764 20765 20766;// ./node_modules/swiper/modules/manipulation.mjs 20767 20768 20769function appendSlide(slides) { 20770 const swiper = this; 20771 const { 20772 params, 20773 slidesEl 20774 } = swiper; 20775 if (params.loop) { 20776 swiper.loopDestroy(); 20777 } 20778 const appendElement = slideEl => { 20779 if (typeof slideEl === 'string') { 20780 const tempDOM = document.createElement('div'); 20781 setInnerHTML(tempDOM, slideEl); 20782 slidesEl.append(tempDOM.children[0]); 20783 setInnerHTML(tempDOM, ''); 20784 } else { 20785 slidesEl.append(slideEl); 20786 } 20787 }; 20788 if (typeof slides === 'object' && 'length' in slides) { 20789 for (let i = 0; i < slides.length; i += 1) { 20790 if (slides[i]) appendElement(slides[i]); 20791 } 20792 } else { 20793 appendElement(slides); 20794 } 20795 swiper.recalcSlides(); 20796 if (params.loop) { 20797 swiper.loopCreate(); 20798 } 20799 if (!params.observer || swiper.isElement) { 20800 swiper.update(); 20801 } 20802} 20803 20804function prependSlide(slides) { 20805 const swiper = this; 20806 const { 20807 params, 20808 activeIndex, 20809 slidesEl 20810 } = swiper; 20811 if (params.loop) { 20812 swiper.loopDestroy(); 20813 } 20814 let newActiveIndex = activeIndex + 1; 20815 const prependElement = slideEl => { 20816 if (typeof slideEl === 'string') { 20817 const tempDOM = document.createElement('div'); 20818 setInnerHTML(tempDOM, slideEl); 20819 slidesEl.prepend(tempDOM.children[0]); 20820 setInnerHTML(tempDOM, ''); 20821 } else { 20822 slidesEl.prepend(slideEl); 20823 } 20824 }; 20825 if (typeof slides === 'object' && 'length' in slides) { 20826 for (let i = 0; i < slides.length; i += 1) { 20827 if (slides[i]) prependElement(slides[i]); 20828 } 20829 newActiveIndex = activeIndex + slides.length; 20830 } else { 20831 prependElement(slides); 20832 } 20833 swiper.recalcSlides(); 20834 if (params.loop) { 20835 swiper.loopCreate(); 20836 } 20837 if (!params.observer || swiper.isElement) { 20838 swiper.update(); 20839 } 20840 swiper.slideTo(newActiveIndex, 0, false); 20841} 20842 20843function addSlide(index, slides) { 20844 const swiper = this; 20845 const { 20846 params, 20847 activeIndex, 20848 slidesEl 20849 } = swiper; 20850 let activeIndexBuffer = activeIndex; 20851 if (params.loop) { 20852 activeIndexBuffer -= swiper.loopedSlides; 20853 swiper.loopDestroy(); 20854 swiper.recalcSlides(); 20855 } 20856 const baseLength = swiper.slides.length; 20857 if (index <= 0) { 20858 swiper.prependSlide(slides); 20859 return; 20860 } 20861 if (index >= baseLength) { 20862 swiper.appendSlide(slides); 20863 return; 20864 } 20865 let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer; 20866 const slidesBuffer = []; 20867 for (let i = baseLength - 1; i >= index; i -= 1) { 20868 const currentSlide = swiper.slides[i]; 20869 currentSlide.remove(); 20870 slidesBuffer.unshift(currentSlide); 20871 } 20872 if (typeof slides === 'object' && 'length' in slides) { 20873 for (let i = 0; i < slides.length; i += 1) { 20874 if (slides[i]) slidesEl.append(slides[i]); 20875 } 20876 newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer; 20877 } else { 20878 slidesEl.append(slides); 20879 } 20880 for (let i = 0; i < slidesBuffer.length; i += 1) { 20881 slidesEl.append(slidesBuffer[i]); 20882 } 20883 swiper.recalcSlides(); 20884 if (params.loop) { 20885 swiper.loopCreate(); 20886 } 20887 if (!params.observer || swiper.isElement) { 20888 swiper.update(); 20889 } 20890 if (params.loop) { 20891 swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false); 20892 } else { 20893 swiper.slideTo(newActiveIndex, 0, false); 20894 } 20895} 20896 20897function removeSlide(slidesIndexes) { 20898 const swiper = this; 20899 const { 20900 params, 20901 activeIndex 20902 } = swiper; 20903 let activeIndexBuffer = activeIndex; 20904 if (params.loop) { 20905 activeIndexBuffer -= swiper.loopedSlides; 20906 swiper.loopDestroy(); 20907 } 20908 let newActiveIndex = activeIndexBuffer; 20909 let indexToRemove; 20910 if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) { 20911 for (let i = 0; i < slidesIndexes.length; i += 1) { 20912 indexToRemove = slidesIndexes[i]; 20913 if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove(); 20914 if (indexToRemove < newActiveIndex) newActiveIndex -= 1; 20915 } 20916 newActiveIndex = Math.max(newActiveIndex, 0); 20917 } else { 20918 indexToRemove = slidesIndexes; 20919 if (swiper.slides[indexToRemove]) swiper.slides[indexToRemove].remove(); 20920 if (indexToRemove < newActiveIndex) newActiveIndex -= 1; 20921 newActiveIndex = Math.max(newActiveIndex, 0); 20922 } 20923 swiper.recalcSlides(); 20924 if (params.loop) { 20925 swiper.loopCreate(); 20926 } 20927 if (!params.observer || swiper.isElement) { 20928 swiper.update(); 20929 } 20930 if (params.loop) { 20931 swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false); 20932 } else { 20933 swiper.slideTo(newActiveIndex, 0, false); 20934 } 20935} 20936 20937function removeAllSlides() { 20938 const swiper = this; 20939 const slidesIndexes = []; 20940 for (let i = 0; i < swiper.slides.length; i += 1) { 20941 slidesIndexes.push(i); 20942 } 20943 swiper.removeSlide(slidesIndexes); 20944} 20945 20946function Manipulation(_ref) { 20947 let { 20948 swiper 20949 } = _ref; 20950 Object.assign(swiper, { 20951 appendSlide: appendSlide.bind(swiper), 20952 prependSlide: prependSlide.bind(swiper), 20953 addSlide: addSlide.bind(swiper), 20954 removeSlide: removeSlide.bind(swiper), 20955 removeAllSlides: removeAllSlides.bind(swiper) 20956 }); 20957} 20958 20959 20960 20961;// ./node_modules/swiper/shared/effect-target.mjs 20962 20963 20964function effect_target_effectTarget(effectParams, slideEl) { 20965 const transformEl = getSlideTransformEl(slideEl); 20966 if (transformEl !== slideEl) { 20967 transformEl.style.backfaceVisibility = 'hidden'; 20968 transformEl.style['-webkit-backface-visibility'] = 'hidden'; 20969 } 20970 return transformEl; 20971} 20972 20973 20974 20975;// ./node_modules/swiper/shared/effect-virtual-transition-end.mjs 20976 20977 20978function effect_virtual_transition_end_effectVirtualTransitionEnd(_ref) { 20979 let { 20980 swiper, 20981 duration, 20982 transformElements, 20983 allSlides 20984 } = _ref; 20985 const { 20986 activeIndex 20987 } = swiper; 20988 const getSlide = el => { 20989 if (!el.parentElement) { 20990 // assume shadow root 20991 const slide = swiper.slides.find(slideEl => slideEl.shadowRoot && slideEl.shadowRoot === el.parentNode); 20992 return slide; 20993 } 20994 return el.parentElement; 20995 }; 20996 if (swiper.params.virtualTranslate && duration !== 0) { 20997 let eventTriggered = false; 20998 let transitionEndTarget; 20999 if (allSlides) { 21000 transitionEndTarget = transformElements; 21001 } else { 21002 transitionEndTarget = transformElements.filter(transformEl => { 21003 const el = transformEl.classList.contains('swiper-slide-transform') ? getSlide(transformEl) : transformEl; 21004 return swiper.getSlideIndex(el) === activeIndex; 21005 }); 21006 } 21007 transitionEndTarget.forEach(el => { 21008 elementTransitionEnd(el, () => { 21009 if (eventTriggered) return; 21010 if (!swiper || swiper.destroyed) return; 21011 eventTriggered = true; 21012 swiper.animating = false; 21013 const evt = new window.CustomEvent('transitionend', { 21014 bubbles: true, 21015 cancelable: true 21016 }); 21017 swiper.wrapperEl.dispatchEvent(evt); 21018 }); 21019 }); 21020 } 21021} 21022 21023 21024 21025;// ./node_modules/swiper/modules/effect-fade.mjs 21026 21027 21028 21029 21030 21031function EffectFade(_ref) { 21032 let { 21033 swiper, 21034 extendParams, 21035 on 21036 } = _ref; 21037 extendParams({ 21038 fadeEffect: { 21039 crossFade: false 21040 } 21041 }); 21042 const setTranslate = () => { 21043 const { 21044 slides 21045 } = swiper; 21046 const params = swiper.params.fadeEffect; 21047 for (let i = 0; i < slides.length; i += 1) { 21048 const slideEl = swiper.slides[i]; 21049 const offset = slideEl.swiperSlideOffset; 21050 let tx = -offset; 21051 if (!swiper.params.virtualTranslate) tx -= swiper.translate; 21052 let ty = 0; 21053 if (!swiper.isHorizontal()) { 21054 ty = tx; 21055 tx = 0; 21056 } 21057 const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs(slideEl.progress), 0) : 1 + Math.min(Math.max(slideEl.progress, -1), 0); 21058 const targetEl = effectTarget(params, slideEl); 21059 targetEl.style.opacity = slideOpacity; 21060 targetEl.style.transform = `translate3d(${tx}px, ${ty}px, 0px)`; 21061 } 21062 }; 21063 const setTransition = duration => { 21064 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl)); 21065 transformElements.forEach(el => { 21066 el.style.transitionDuration = `${duration}ms`; 21067 }); 21068 effectVirtualTransitionEnd({ 21069 swiper, 21070 duration, 21071 transformElements, 21072 allSlides: true 21073 }); 21074 }; 21075 effectInit({ 21076 effect: 'fade', 21077 swiper, 21078 on, 21079 setTranslate, 21080 setTransition, 21081 overwriteParams: () => ({ 21082 slidesPerView: 1, 21083 slidesPerGroup: 1, 21084 watchSlidesProgress: true, 21085 spaceBetween: 0, 21086 virtualTranslate: !swiper.params.cssMode 21087 }) 21088 }); 21089} 21090 21091 21092 21093;// ./node_modules/swiper/modules/effect-cube.mjs 21094 21095 21096 21097function EffectCube(_ref) { 21098 let { 21099 swiper, 21100 extendParams, 21101 on 21102 } = _ref; 21103 extendParams({ 21104 cubeEffect: { 21105 slideShadows: true, 21106 shadow: true, 21107 shadowOffset: 20, 21108 shadowScale: 0.94 21109 } 21110 }); 21111 const createSlideShadows = (slideEl, progress, isHorizontal) => { 21112 let shadowBefore = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top'); 21113 let shadowAfter = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom'); 21114 if (!shadowBefore) { 21115 shadowBefore = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}`.split(' ')); 21116 slideEl.append(shadowBefore); 21117 } 21118 if (!shadowAfter) { 21119 shadowAfter = createElement('div', `swiper-slide-shadow-cube swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}`.split(' ')); 21120 slideEl.append(shadowAfter); 21121 } 21122 if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0); 21123 if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0); 21124 }; 21125 const recreateShadows = () => { 21126 // create new ones 21127 const isHorizontal = swiper.isHorizontal(); 21128 swiper.slides.forEach(slideEl => { 21129 const progress = Math.max(Math.min(slideEl.progress, 1), -1); 21130 createSlideShadows(slideEl, progress, isHorizontal); 21131 }); 21132 }; 21133 const setTranslate = () => { 21134 const { 21135 el, 21136 wrapperEl, 21137 slides, 21138 width: swiperWidth, 21139 height: swiperHeight, 21140 rtlTranslate: rtl, 21141 size: swiperSize, 21142 browser 21143 } = swiper; 21144 const r = getRotateFix(swiper); 21145 const params = swiper.params.cubeEffect; 21146 const isHorizontal = swiper.isHorizontal(); 21147 const isVirtual = swiper.virtual && swiper.params.virtual.enabled; 21148 let wrapperRotate = 0; 21149 let cubeShadowEl; 21150 if (params.shadow) { 21151 if (isHorizontal) { 21152 cubeShadowEl = swiper.wrapperEl.querySelector('.swiper-cube-shadow'); 21153 if (!cubeShadowEl) { 21154 cubeShadowEl = createElement('div', 'swiper-cube-shadow'); 21155 swiper.wrapperEl.append(cubeShadowEl); 21156 } 21157 cubeShadowEl.style.height = `${swiperWidth}px`; 21158 } else { 21159 cubeShadowEl = el.querySelector('.swiper-cube-shadow'); 21160 if (!cubeShadowEl) { 21161 cubeShadowEl = createElement('div', 'swiper-cube-shadow'); 21162 el.append(cubeShadowEl); 21163 } 21164 } 21165 } 21166 for (let i = 0; i < slides.length; i += 1) { 21167 const slideEl = slides[i]; 21168 let slideIndex = i; 21169 if (isVirtual) { 21170 slideIndex = parseInt(slideEl.getAttribute('data-swiper-slide-index'), 10); 21171 } 21172 let slideAngle = slideIndex * 90; 21173 let round = Math.floor(slideAngle / 360); 21174 if (rtl) { 21175 slideAngle = -slideAngle; 21176 round = Math.floor(-slideAngle / 360); 21177 } 21178 const progress = Math.max(Math.min(slideEl.progress, 1), -1); 21179 let tx = 0; 21180 let ty = 0; 21181 let tz = 0; 21182 if (slideIndex % 4 === 0) { 21183 tx = -round * 4 * swiperSize; 21184 tz = 0; 21185 } else if ((slideIndex - 1) % 4 === 0) { 21186 tx = 0; 21187 tz = -round * 4 * swiperSize; 21188 } else if ((slideIndex - 2) % 4 === 0) { 21189 tx = swiperSize + round * 4 * swiperSize; 21190 tz = swiperSize; 21191 } else if ((slideIndex - 3) % 4 === 0) { 21192 tx = -swiperSize; 21193 tz = 3 * swiperSize + swiperSize * 4 * round; 21194 } 21195 if (rtl) { 21196 tx = -tx; 21197 } 21198 if (!isHorizontal) { 21199 ty = tx; 21200 tx = 0; 21201 } 21202 const transform = `rotateX(${r(isHorizontal ? 0 : -slideAngle)}deg) rotateY(${r(isHorizontal ? slideAngle : 0)}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`; 21203 if (progress <= 1 && progress > -1) { 21204 wrapperRotate = slideIndex * 90 + progress * 90; 21205 if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90; 21206 } 21207 slideEl.style.transform = transform; 21208 if (params.slideShadows) { 21209 createSlideShadows(slideEl, progress, isHorizontal); 21210 } 21211 } 21212 wrapperEl.style.transformOrigin = `50% 50% -${swiperSize / 2}px`; 21213 wrapperEl.style['-webkit-transform-origin'] = `50% 50% -${swiperSize / 2}px`; 21214 if (params.shadow) { 21215 if (isHorizontal) { 21216 cubeShadowEl.style.transform = `translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${-swiperWidth / 2}px) rotateX(89.99deg) rotateZ(0deg) scale(${params.shadowScale})`; 21217 } else { 21218 const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90; 21219 const multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2); 21220 const scale1 = params.shadowScale; 21221 const scale2 = params.shadowScale / multiplier; 21222 const offset = params.shadowOffset; 21223 cubeShadowEl.style.transform = `scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${-swiperHeight / 2 / scale2}px) rotateX(-89.99deg)`; 21224 } 21225 } 21226 const zFactor = (browser.isSafari || browser.isWebView) && browser.needPerspectiveFix ? -swiperSize / 2 : 0; 21227 wrapperEl.style.transform = `translate3d(0px,0,${zFactor}px) rotateX(${r(swiper.isHorizontal() ? 0 : wrapperRotate)}deg) rotateY(${r(swiper.isHorizontal() ? -wrapperRotate : 0)}deg)`; 21228 wrapperEl.style.setProperty('--swiper-cube-translate-z', `${zFactor}px`); 21229 }; 21230 const setTransition = duration => { 21231 const { 21232 el, 21233 slides 21234 } = swiper; 21235 slides.forEach(slideEl => { 21236 slideEl.style.transitionDuration = `${duration}ms`; 21237 slideEl.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(subEl => { 21238 subEl.style.transitionDuration = `${duration}ms`; 21239 }); 21240 }); 21241 if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) { 21242 const shadowEl = el.querySelector('.swiper-cube-shadow'); 21243 if (shadowEl) shadowEl.style.transitionDuration = `${duration}ms`; 21244 } 21245 }; 21246 effectInit({ 21247 effect: 'cube', 21248 swiper, 21249 on, 21250 setTranslate, 21251 setTransition, 21252 recreateShadows, 21253 getEffectParams: () => swiper.params.cubeEffect, 21254 perspective: () => true, 21255 overwriteParams: () => ({ 21256 slidesPerView: 1, 21257 slidesPerGroup: 1, 21258 watchSlidesProgress: true, 21259 resistanceRatio: 0, 21260 spaceBetween: 0, 21261 centeredSlides: false, 21262 virtualTranslate: true 21263 }) 21264 }); 21265} 21266 21267 21268 21269;// ./node_modules/swiper/shared/create-shadow.mjs 21270 21271 21272function create_shadow_createShadow(suffix, slideEl, side) { 21273 const shadowClass = `swiper-slide-shadow${side ? `-${side}` : ''}${suffix ? ` swiper-slide-shadow-${suffix}` : ''}`; 21274 const shadowContainer = getSlideTransformEl(slideEl); 21275 let shadowEl = shadowContainer.querySelector(`.${shadowClass.split(' ').join('.')}`); 21276 if (!shadowEl) { 21277 shadowEl = createElement('div', shadowClass.split(' ')); 21278 shadowContainer.append(shadowEl); 21279 } 21280 return shadowEl; 21281} 21282 21283 21284 21285;// ./node_modules/swiper/modules/effect-flip.mjs 21286 21287 21288 21289 21290 21291 21292function EffectFlip(_ref) { 21293 let { 21294 swiper, 21295 extendParams, 21296 on 21297 } = _ref; 21298 extendParams({ 21299 flipEffect: { 21300 slideShadows: true, 21301 limitRotation: true 21302 } 21303 }); 21304 const createSlideShadows = (slideEl, progress) => { 21305 let shadowBefore = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top'); 21306 let shadowAfter = swiper.isHorizontal() ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom'); 21307 if (!shadowBefore) { 21308 shadowBefore = createShadow('flip', slideEl, swiper.isHorizontal() ? 'left' : 'top'); 21309 } 21310 if (!shadowAfter) { 21311 shadowAfter = createShadow('flip', slideEl, swiper.isHorizontal() ? 'right' : 'bottom'); 21312 } 21313 if (shadowBefore) shadowBefore.style.opacity = Math.max(-progress, 0); 21314 if (shadowAfter) shadowAfter.style.opacity = Math.max(progress, 0); 21315 }; 21316 const recreateShadows = () => { 21317 // Set shadows 21318 swiper.params.flipEffect; 21319 swiper.slides.forEach(slideEl => { 21320 let progress = slideEl.progress; 21321 if (swiper.params.flipEffect.limitRotation) { 21322 progress = Math.max(Math.min(slideEl.progress, 1), -1); 21323 } 21324 createSlideShadows(slideEl, progress); 21325 }); 21326 }; 21327 const setTranslate = () => { 21328 const { 21329 slides, 21330 rtlTranslate: rtl 21331 } = swiper; 21332 const params = swiper.params.flipEffect; 21333 const rotateFix = getRotateFix(swiper); 21334 for (let i = 0; i < slides.length; i += 1) { 21335 const slideEl = slides[i]; 21336 let progress = slideEl.progress; 21337 if (swiper.params.flipEffect.limitRotation) { 21338 progress = Math.max(Math.min(slideEl.progress, 1), -1); 21339 } 21340 const offset = slideEl.swiperSlideOffset; 21341 const rotate = -180 * progress; 21342 let rotateY = rotate; 21343 let rotateX = 0; 21344 let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset; 21345 let ty = 0; 21346 if (!swiper.isHorizontal()) { 21347 ty = tx; 21348 tx = 0; 21349 rotateX = -rotateY; 21350 rotateY = 0; 21351 } else if (rtl) { 21352 rotateY = -rotateY; 21353 } 21354 slideEl.style.zIndex = -Math.abs(Math.round(progress)) + slides.length; 21355 if (params.slideShadows) { 21356 createSlideShadows(slideEl, progress); 21357 } 21358 const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateFix(rotateX)}deg) rotateY(${rotateFix(rotateY)}deg)`; 21359 const targetEl = effectTarget(params, slideEl); 21360 targetEl.style.transform = transform; 21361 } 21362 }; 21363 const setTransition = duration => { 21364 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl)); 21365 transformElements.forEach(el => { 21366 el.style.transitionDuration = `${duration}ms`; 21367 el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => { 21368 shadowEl.style.transitionDuration = `${duration}ms`; 21369 }); 21370 }); 21371 effectVirtualTransitionEnd({ 21372 swiper, 21373 duration, 21374 transformElements 21375 }); 21376 }; 21377 effectInit({ 21378 effect: 'flip', 21379 swiper, 21380 on, 21381 setTranslate, 21382 setTransition, 21383 recreateShadows, 21384 getEffectParams: () => swiper.params.flipEffect, 21385 perspective: () => true, 21386 overwriteParams: () => ({ 21387 slidesPerView: 1, 21388 slidesPerGroup: 1, 21389 watchSlidesProgress: true, 21390 spaceBetween: 0, 21391 virtualTranslate: !swiper.params.cssMode 21392 }) 21393 }); 21394} 21395 21396 21397 21398;// ./node_modules/swiper/modules/effect-coverflow.mjs 21399 21400 21401 21402 21403 21404function EffectCoverflow(_ref) { 21405 let { 21406 swiper, 21407 extendParams, 21408 on 21409 } = _ref; 21410 extendParams({ 21411 coverflowEffect: { 21412 rotate: 50, 21413 stretch: 0, 21414 depth: 100, 21415 scale: 1, 21416 modifier: 1, 21417 slideShadows: true 21418 } 21419 }); 21420 const setTranslate = () => { 21421 const { 21422 width: swiperWidth, 21423 height: swiperHeight, 21424 slides, 21425 slidesSizesGrid 21426 } = swiper; 21427 const params = swiper.params.coverflowEffect; 21428 const isHorizontal = swiper.isHorizontal(); 21429 const transform = swiper.translate; 21430 const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2; 21431 const rotate = isHorizontal ? params.rotate : -params.rotate; 21432 const translate = params.depth; 21433 const r = getRotateFix(swiper); 21434 // Each slide offset from center 21435 for (let i = 0, length = slides.length; i < length; i += 1) { 21436 const slideEl = slides[i]; 21437 const slideSize = slidesSizesGrid[i]; 21438 const slideOffset = slideEl.swiperSlideOffset; 21439 const centerOffset = (center - slideOffset - slideSize / 2) / slideSize; 21440 const offsetMultiplier = typeof params.modifier === 'function' ? params.modifier(centerOffset) : centerOffset * params.modifier; 21441 let rotateY = isHorizontal ? rotate * offsetMultiplier : 0; 21442 let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; 21443 // var rotateZ = 0 21444 let translateZ = -translate * Math.abs(offsetMultiplier); 21445 let stretch = params.stretch; 21446 // Allow percentage to make a relative stretch for responsive sliders 21447 if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) { 21448 stretch = parseFloat(params.stretch) / 100 * slideSize; 21449 } 21450 let translateY = isHorizontal ? 0 : stretch * offsetMultiplier; 21451 let translateX = isHorizontal ? stretch * offsetMultiplier : 0; 21452 let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier); 21453 21454 // Fix for ultra small values 21455 if (Math.abs(translateX) < 0.001) translateX = 0; 21456 if (Math.abs(translateY) < 0.001) translateY = 0; 21457 if (Math.abs(translateZ) < 0.001) translateZ = 0; 21458 if (Math.abs(rotateY) < 0.001) rotateY = 0; 21459 if (Math.abs(rotateX) < 0.001) rotateX = 0; 21460 if (Math.abs(scale) < 0.001) scale = 0; 21461 const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px) rotateX(${r(rotateX)}deg) rotateY(${r(rotateY)}deg) scale(${scale})`; 21462 const targetEl = effectTarget(params, slideEl); 21463 targetEl.style.transform = slideTransform; 21464 slideEl.style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1; 21465 if (params.slideShadows) { 21466 // Set shadows 21467 let shadowBeforeEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-left') : slideEl.querySelector('.swiper-slide-shadow-top'); 21468 let shadowAfterEl = isHorizontal ? slideEl.querySelector('.swiper-slide-shadow-right') : slideEl.querySelector('.swiper-slide-shadow-bottom'); 21469 if (!shadowBeforeEl) { 21470 shadowBeforeEl = createShadow('coverflow', slideEl, isHorizontal ? 'left' : 'top'); 21471 } 21472 if (!shadowAfterEl) { 21473 shadowAfterEl = createShadow('coverflow', slideEl, isHorizontal ? 'right' : 'bottom'); 21474 } 21475 if (shadowBeforeEl) shadowBeforeEl.style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0; 21476 if (shadowAfterEl) shadowAfterEl.style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0; 21477 } 21478 } 21479 }; 21480 const setTransition = duration => { 21481 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl)); 21482 transformElements.forEach(el => { 21483 el.style.transitionDuration = `${duration}ms`; 21484 el.querySelectorAll('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').forEach(shadowEl => { 21485 shadowEl.style.transitionDuration = `${duration}ms`; 21486 }); 21487 }); 21488 }; 21489 effectInit({ 21490 effect: 'coverflow', 21491 swiper, 21492 on, 21493 setTranslate, 21494 setTransition, 21495 perspective: () => true, 21496 overwriteParams: () => ({ 21497 watchSlidesProgress: true 21498 }) 21499 }); 21500} 21501 21502 21503 21504;// ./node_modules/swiper/modules/effect-creative.mjs 21505 21506 21507 21508 21509 21510 21511function EffectCreative(_ref) { 21512 let { 21513 swiper, 21514 extendParams, 21515 on 21516 } = _ref; 21517 extendParams({ 21518 creativeEffect: { 21519 limitProgress: 1, 21520 shadowPerProgress: false, 21521 progressMultiplier: 1, 21522 perspective: true, 21523 prev: { 21524 translate: [0, 0, 0], 21525 rotate: [0, 0, 0], 21526 opacity: 1, 21527 scale: 1 21528 }, 21529 next: { 21530 translate: [0, 0, 0], 21531 rotate: [0, 0, 0], 21532 opacity: 1, 21533 scale: 1 21534 } 21535 } 21536 }); 21537 const getTranslateValue = value => { 21538 if (typeof value === 'string') return value; 21539 return `${value}px`; 21540 }; 21541 const setTranslate = () => { 21542 const { 21543 slides, 21544 wrapperEl, 21545 slidesSizesGrid 21546 } = swiper; 21547 const params = swiper.params.creativeEffect; 21548 const { 21549 progressMultiplier: multiplier 21550 } = params; 21551 const isCenteredSlides = swiper.params.centeredSlides; 21552 const rotateFix = getRotateFix(swiper); 21553 if (isCenteredSlides) { 21554 const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0; 21555 wrapperEl.style.transform = `translateX(calc(50% - ${margin}px))`; 21556 } 21557 for (let i = 0; i < slides.length; i += 1) { 21558 const slideEl = slides[i]; 21559 const slideProgress = slideEl.progress; 21560 const progress = Math.min(Math.max(slideEl.progress, -params.limitProgress), params.limitProgress); 21561 let originalProgress = progress; 21562 if (!isCenteredSlides) { 21563 originalProgress = Math.min(Math.max(slideEl.originalProgress, -params.limitProgress), params.limitProgress); 21564 } 21565 const offset = slideEl.swiperSlideOffset; 21566 const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0]; 21567 const r = [0, 0, 0]; 21568 let custom = false; 21569 if (!swiper.isHorizontal()) { 21570 t[1] = t[0]; 21571 t[0] = 0; 21572 } 21573 let data = { 21574 translate: [0, 0, 0], 21575 rotate: [0, 0, 0], 21576 scale: 1, 21577 opacity: 1 21578 }; 21579 if (progress < 0) { 21580 data = params.next; 21581 custom = true; 21582 } else if (progress > 0) { 21583 data = params.prev; 21584 custom = true; 21585 } 21586 // set translate 21587 t.forEach((value, index) => { 21588 t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(progress * multiplier)}))`; 21589 }); 21590 // set rotates 21591 r.forEach((value, index) => { 21592 let val = data.rotate[index] * Math.abs(progress * multiplier); 21593 r[index] = val; 21594 }); 21595 slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length; 21596 const translateString = t.join(', '); 21597 const rotateString = `rotateX(${rotateFix(r[0])}deg) rotateY(${rotateFix(r[1])}deg) rotateZ(${rotateFix(r[2])}deg)`; 21598 const scaleString = originalProgress < 0 ? `scale(${1 + (1 - data.scale) * originalProgress * multiplier})` : `scale(${1 - (1 - data.scale) * originalProgress * multiplier})`; 21599 const opacityString = originalProgress < 0 ? 1 + (1 - data.opacity) * originalProgress * multiplier : 1 - (1 - data.opacity) * originalProgress * multiplier; 21600 const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`; 21601 21602 // Set shadows 21603 if (custom && data.shadow || !custom) { 21604 let shadowEl = slideEl.querySelector('.swiper-slide-shadow'); 21605 if (!shadowEl && data.shadow) { 21606 shadowEl = createShadow('creative', slideEl); 21607 } 21608 if (shadowEl) { 21609 const shadowOpacity = params.shadowPerProgress ? progress * (1 / params.limitProgress) : progress; 21610 shadowEl.style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1); 21611 } 21612 } 21613 const targetEl = effectTarget(params, slideEl); 21614 targetEl.style.transform = transform; 21615 targetEl.style.opacity = opacityString; 21616 if (data.origin) { 21617 targetEl.style.transformOrigin = data.origin; 21618 } 21619 } 21620 }; 21621 const setTransition = duration => { 21622 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl)); 21623 transformElements.forEach(el => { 21624 el.style.transitionDuration = `${duration}ms`; 21625 el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => { 21626 shadowEl.style.transitionDuration = `${duration}ms`; 21627 }); 21628 }); 21629 effectVirtualTransitionEnd({ 21630 swiper, 21631 duration, 21632 transformElements, 21633 allSlides: true 21634 }); 21635 }; 21636 effectInit({ 21637 effect: 'creative', 21638 swiper, 21639 on, 21640 setTranslate, 21641 setTransition, 21642 perspective: () => swiper.params.creativeEffect.perspective, 21643 overwriteParams: () => ({ 21644 watchSlidesProgress: true, 21645 virtualTranslate: !swiper.params.cssMode 21646 }) 21647 }); 21648} 21649 21650 21651 21652;// ./node_modules/swiper/modules/effect-cards.mjs 21653 21654 21655 21656 21657 21658 21659function EffectCards(_ref) { 21660 let { 21661 swiper, 21662 extendParams, 21663 on 21664 } = _ref; 21665 extendParams({ 21666 cardsEffect: { 21667 slideShadows: true, 21668 rotate: true, 21669 perSlideRotate: 2, 21670 perSlideOffset: 8 21671 } 21672 }); 21673 const setTranslate = () => { 21674 const { 21675 slides, 21676 activeIndex, 21677 rtlTranslate: rtl 21678 } = swiper; 21679 const params = swiper.params.cardsEffect; 21680 const { 21681 startTranslate, 21682 isTouched 21683 } = swiper.touchEventsData; 21684 const currentTranslate = rtl ? -swiper.translate : swiper.translate; 21685 for (let i = 0; i < slides.length; i += 1) { 21686 const slideEl = slides[i]; 21687 const slideProgress = slideEl.progress; 21688 const progress = Math.min(Math.max(slideProgress, -4), 4); 21689 let offset = slideEl.swiperSlideOffset; 21690 if (swiper.params.centeredSlides && !swiper.params.cssMode) { 21691 swiper.wrapperEl.style.transform = `translateX(${swiper.minTranslate()}px)`; 21692 } 21693 if (swiper.params.centeredSlides && swiper.params.cssMode) { 21694 offset -= slides[0].swiperSlideOffset; 21695 } 21696 let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset; 21697 let tY = 0; 21698 const tZ = -100 * Math.abs(progress); 21699 let scale = 1; 21700 let rotate = -params.perSlideRotate * progress; 21701 let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75; 21702 const slideIndex = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.from + i : i; 21703 const isSwipeToNext = (slideIndex === activeIndex || slideIndex === activeIndex - 1) && progress > 0 && progress < 1 && (isTouched || swiper.params.cssMode) && currentTranslate < startTranslate; 21704 const isSwipeToPrev = (slideIndex === activeIndex || slideIndex === activeIndex + 1) && progress < 0 && progress > -1 && (isTouched || swiper.params.cssMode) && currentTranslate > startTranslate; 21705 if (isSwipeToNext || isSwipeToPrev) { 21706 const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5; 21707 rotate += -28 * progress * subProgress; 21708 scale += -0.5 * subProgress; 21709 tXAdd += 96 * subProgress; 21710 tY = `${-25 * subProgress * Math.abs(progress)}%`; 21711 } 21712 if (progress < 0) { 21713 // next 21714 tX = `calc(${tX}px ${rtl ? '-' : '+'} (${tXAdd * Math.abs(progress)}%))`; 21715 } else if (progress > 0) { 21716 // prev 21717 tX = `calc(${tX}px ${rtl ? '-' : '+'} (-${tXAdd * Math.abs(progress)}%))`; 21718 } else { 21719 tX = `${tX}px`; 21720 } 21721 if (!swiper.isHorizontal()) { 21722 const prevY = tY; 21723 tY = tX; 21724 tX = prevY; 21725 } 21726 const scaleString = progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`; 21727 21728 /* eslint-disable */ 21729 const transform = ` 21730 translate3d(${tX}, ${tY}, ${tZ}px) 21731 rotateZ(${params.rotate ? rtl ? -rotate : rotate : 0}deg) 21732 scale(${scaleString}) 21733 `; 21734 /* eslint-enable */ 21735 21736 if (params.slideShadows) { 21737 // Set shadows 21738 let shadowEl = slideEl.querySelector('.swiper-slide-shadow'); 21739 if (!shadowEl) { 21740 shadowEl = createShadow('cards', slideEl); 21741 } 21742 if (shadowEl) shadowEl.style.opacity = Math.min(Math.max((Math.abs(progress) - 0.5) / 0.5, 0), 1); 21743 } 21744 slideEl.style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length; 21745 const targetEl = effectTarget(params, slideEl); 21746 targetEl.style.transform = transform; 21747 } 21748 }; 21749 const setTransition = duration => { 21750 const transformElements = swiper.slides.map(slideEl => getSlideTransformEl(slideEl));
21751 transformElements.forEach(el => { 21752 el.style.transitionDuration = `${duration}ms`; 21753 el.querySelectorAll('.swiper-slide-shadow').forEach(shadowEl => { 21754 shadowEl.style.transitionDuration = `${duration}ms`; 21755 }); 21756 }); 21757 effectVirtualTransitionEnd({ 21758 swiper, 21759 duration, 21760 transformElements 21761 }); 21762 }; 21763 effectInit({ 21764 effect: 'cards', 21765 swiper, 21766 on, 21767 setTranslate, 21768 setTransition, 21769 perspective: () => true, 21770 overwriteParams: () => ({ 21771 _loopSwapReset: false, 21772 watchSlidesProgress: true, 21773 loopAdditionalSlides: swiper.params.cardsEffect.rotate ? 3 : 2, 21774 centeredSlides: true, 21775 virtualTranslate: !swiper.params.cssMode 21776 }) 21777 }); 21778} 21779 21780 21781 21782;// ./node_modules/swiper/modules/index.mjs 21783 21784 21785 21786 21787 21788 21789 21790 21791 21792 21793 21794 21795 21796 21797 21798 21799 21800 21801 21802 21803 21804 21805 21806;// ./wp-content/themes/sfrtheme/assets/js/slider.js 21807 21808 21809 21810 21811 21812 21813// On parcourt tous les sliders 21814document.addEventListener("DOMContentLoaded", () => { 21815 document.querySelectorAll(".swiper").forEach(swiperElement => { 21816 const id = swiperElement.getAttribute("id"); 21817 const spacingAttr = swiperElement.getAttribute("data-spacing"); 21818 const spacing = spacingAttr !== null ? parseInt(spacingAttr, 10) : 0; 21819 const mobileSpacingAttr = swiperElement.getAttribute("data-mobile-spacing"); 21820 const mobileSpacing = mobileSpacingAttr !== null ? parseInt(mobileSpacingAttr, 10) : 0; 21821 const autoHeight = String(swiperElement.getAttribute("data-auto-height")) === "true"; 21822 const autoPlay = String(swiperElement.getAttribute("data-auto-play")) === "true"; 21823 const autoPlayDelayAttr = swiperElement.getAttribute("data-auto-play-delay"); 21824 const autoPlayDelay = autoPlayDelayAttr !== null ? parseInt(autoPlayDelayAttr, 10) : 3000; 21825 21826 // On peut définir un breakpoint via data-attribute ou par défaut (ex: null pour toujours actif) 21827 const minWidth = swiperElement.getAttribute("data-mobile-no-slide") === "true" ? 1080 : swiperElement.getAttribute("data-min-width"); 21828 const maxWidth = swiperElement.getAttribute("data-max-width"); 21829 let swiperInstance = null; 21830 let mql = null; 21831 if (minWidth) { 21832 //actif au dessus de la min width 21833 mql = window.matchMedia(`(min-width: ${minWidth}px)`); 21834 } else if (maxWidth) { 21835 //actif en dessous de la max width 21836 mql = window.matchMedia(`(max-width: ${maxWidth}px)`); 21837 } 21838 const initSwiper = () => { 21839 if (swiperInstance) return; 21840 const autoplay = autoPlay ? { 21841 delay: autoPlayDelay, 21842 disableOnInteraction: false 21843 } : false; 21844 swiperInstance = new Swiper(swiperElement, { 21845 autoplay, 21846 slidesPerView: "auto", 21847 watchOverflow: true, 21848 breakpoints: { 21849 // quand la largeur est >= 320px 21850 320: { 21851 spaceBetween: mobileSpacing 21852 }, 21853 // quand la largeur est >= 1340px 21854 1340: { 21855 spaceBetween: spacing 21856 } 21857 }, 21858 grabCursor: true, 21859 autoHeight, 21860 pagination: { 21861 el: `#swiper-pagination-${id}`, 21862 clickable: true 21863 }, 21864 navigation: { 21865 nextEl: `#swiper-button-next-${id}`, 21866 prevEl: `#swiper-button-prev-${id}` 21867 }, 21868 scrollbar: { 21869 el: `#swiper-scrollbar-${id}`, 21870 draggable: true 21871 }, 21872 modules: [Navigation, Pagination, Autoplay] 21873 }); 21874 }; 21875 const destroySwiper = () => { 21876 if (swiperInstance) { 21877 swiperInstance.destroy(true, true); 21878 swiperInstance = null; 21879 } 21880 }; 21881 const handleMediaChange = e => { 21882 if (e.matches) { 21883 initSwiper(); 21884 } else { 21885 destroySwiper(); 21886 } 21887 }; 21888 if (mql) { 21889 mql.addEventListener("change", handleMediaChange); 21890 if (mql.matches) { 21891 initSwiper(); 21892 } 21893 } else { 21894 initSwiper(); 21895 } 21896 }); 21897}); 21898;// ./wp-content/themes/sfrtheme/assets/js/jquery.easy-autocomplete.min.js 21899 21900 21901/* 21902 * easy-autocomplete 21903 * jQuery plugin for autocompletion 21904 * 21905 * @author Åukasz PaweÅczak (http://github.com/pawelczak) 21906 * @version 1.3.5 21907 * Copyright License: 21908 */ 21909 21910var EasyAutocomplete = function (a) { 21911 return a.Configuration = function (a) { 21912 function b() { 21913 if ("xml" === a.dataType && (a.getValue || (a.getValue = function (a) { 21914 return $(a).text(); 21915 }), a.list || (a.list = {}), a.list.sort || (a.list.sort = {}), a.list.sort.method = function (b, c) { 21916 return b = a.getValue(b), c = a.getValue(c), c > b ? -1 : b > c ? 1 : 0; 21917 }, a.list.match || (a.list.match = {}), a.list.match.method = function (a, b) { 21918 return a.search(b) > -1; 21919 }), void 0 !== a.categories && a.categories instanceof Array) { 21920 for (var b = [], c = 0, d = a.categories.length; d > c; c += 1) { 21921 var e = a.categories[c]; 21922 for (var f in h.categories[0]) void 0 === e[f] && (e[f] = h.categories[0][f]); 21923 b.push(e); 21924 } 21925 a.categories = b; 21926 } 21927 } 21928 function c() { 21929 function b(a, c) { 21930 var d = a || {}; 21931 for (var e in a) void 0 !== c[e] && null !== c[e] && ("object" != typeof c[e] || c[e] instanceof Array ? d[e] = c[e] : b(a[e], c[e])); 21932 return void 0 !== c.data && null !== c.data && "object" == typeof c.data && (d.data = c.data), d; 21933 } 21934 h = b(h, a); 21935 } 21936 function d() { 21937 if ("list-required" !== h.url && "function" != typeof h.url) { 21938 var b = h.url; 21939 h.url = function () { 21940 return b; 21941 }; 21942 } 21943 if (void 0 !== h.ajaxSettings.url && "function" != typeof h.ajaxSettings.url) { 21944 var b = h.ajaxSettings.url; 21945 h.ajaxSettings.url = function () { 21946 return b; 21947 }; 21948 } 21949 if ("string" == typeof h.listLocation) { 21950 var c = h.listLocation; 21951 "XML" === h.dataType.toUpperCase() ? h.listLocation = function (a) { 21952 return $(a).find(c); 21953 } : h.listLocation = function (a) { 21954 return a[c]; 21955 }; 21956 } 21957 if ("string" == typeof h.getValue) { 21958 var d = h.getValue; 21959 h.getValue = function (a) { 21960 return a[d]; 21961 }; 21962 } 21963 void 0 !== a.categories && (h.categoriesAssigned = !0); 21964 } 21965 function e() {
21966 void 0 !== a.ajaxSettings && "object" == typeof a.ajaxSettings ? h.ajaxSettings = a.ajaxSettings : h.ajaxSettings = {}; 21967 } 21968 function f(a) { 21969 return void 0 !== h[a] && null !== h[a]; 21970 } 21971 function g(a, b) { 21972 function c(b, d) { 21973 for (var e in d) void 0 === b[e] && a.log("Property '" + e + "' does not exist in EasyAutocomplete options API."), "object" == typeof b[e] && -1 === $.inArray(e, i) && c(b[e], d[e]); 21974 } 21975 c(h, b); 21976 } 21977 var h = { 21978 data: "list-required", 21979 url: "list-required", 21980 dataType: "json", 21981 listLocation: function (a) { 21982 return a; 21983 }, 21984 xmlElementName: "", 21985 getValue: function (a) { 21986 return a; 21987 }, 21988 autocompleteOff: !0, 21989 placeholder: !1, 21990 ajaxCallback: function () {}, 21991 matchResponseProperty: !1, 21992 list: { 21993 sort: { 21994 enabled: !1, 21995 method: function (a, b) { 21996 return a = h.getValue(a), b = h.getValue(b), b > a ? -1 : a > b ? 1 : 0; 21997 } 21998 }, 21999 maxNumberOfElements: 6, 22000 hideOnEmptyPhrase: !0, 22001 match: { 22002 enabled: !1, 22003 caseSensitive: !1, 22004 method: function (a, b) { 22005 return a.search(b) > -1; 22006 } 22007 }, 22008 showAnimation: { 22009 type: "normal", 22010 time: 400, 22011 callback: function () {} 22012 }, 22013 hideAnimation: { 22014 type: "normal", 22015 time: 400, 22016 callback: function () {} 22017 }, 22018 onClickEvent: function () {}, 22019 onSelectItemEvent: function () {}, 22020 onLoadEvent: function () {}, 22021 onChooseEvent: function () {}, 22022 onKeyEnterEvent: function () {}, 22023 onMouseOverEvent: function () {}, 22024 onMouseOutEvent: function () {}, 22025 onShowListEvent: function () {}, 22026 onHideListEvent: function () {} 22027 }, 22028 highlightPhrase: !0, 22029 theme: "", 22030 cssClasses: "", 22031 minCharNumber: 0, 22032 requestDelay: 0, 22033 adjustWidth: !0, 22034 ajaxSettings: {}, 22035 preparePostData: function (a, b) { 22036 return a; 22037 }, 22038 loggerEnabled: !0, 22039 template: "", 22040 categoriesAssigned: !1, 22041 categories: [{ 22042 maxNumberOfElements: 4 22043 }] 22044 }, 22045 i = ["ajaxSettings", "template"]; 22046 this.get = function (a) { 22047 return h[a]; 22048 }, this.equals = function (a, b) { 22049 return !(!f(a) || h[a] !== b); 22050 }, this.checkDataUrlProperties = function () { 22051 return "list-required" !== h.url || "list-required" !== h.data; 22052 }, this.checkRequiredProperties = function () { 22053 for (var a in h) if ("required" === h[a]) return logger.error("Option " + a + " must be defined"), !1; 22054 return !0; 22055 }, this.printPropertiesThatDoesntExist = function (a, b) { 22056 g(a, b); 22057 }, b(), c(), h.loggerEnabled === !0 && g(console, a), e(), d(); 22058 }, a; 22059 }(EasyAutocomplete || {}), 22060 EasyAutocomplete = function (a) { 22061 return a.Logger = function () { 22062 this.error = function (a) { 22063 console.log("ERROR: " + a); 22064 }, this.warning = function (a) { 22065 console.log("WARNING: " + a); 22066 }; 22067 }, a; 22068 }(EasyAutocomplete || {}), 22069 EasyAutocomplete = function (a) { 22070 return a.Constans = function () { 22071 var a = { 22072 CONTAINER_CLASS: "easy-autocomplete-container", 22073 CONTAINER_ID: "eac-container-", 22074 WRAPPER_CSS_CLASS: "easy-autocomplete" 22075 }; 22076 this.getValue = function (b) { 22077 return a[b]; 22078 }; 22079 }, a; 22080 }(EasyAutocomplete || {}), 22081 EasyAutocomplete = function (a) { 22082 return a.ListBuilderService = function (a, b) { 22083 function c(b, c) { 22084 function d() { 22085 var d, 22086 e = {}; 22087 return void 0 !== b.xmlElementName && (e.xmlElementName = b.xmlElementName), void 0 !== b.listLocation ? d = b.listLocation : void 0 !== a.get("listLocation") && (d = a.get("listLocation")), void 0 !== d ? "string" == typeof d ? e.data = $(c).find(d) : "function" == typeof d && (e.data = d(c)) : e.data = c, e; 22088 } 22089 function e() { 22090 var a = {}; 22091 return void 0 !== b.listLocation ? "string" == typeof b.listLocation ? a.data = c[b.listLocation] : "function" == typeof b.listLocation && (a.data = b.listLocation(c)) : a.data = c, a; 22092 } 22093 var f = {}; 22094 if (f = "XML" === a.get("dataType").toUpperCase() ? d() : e(), void 0 !== b.header && (f.header = b.header), void 0 !== b.maxNumberOfElements && (f.maxNumberOfElements = b.maxNumberOfElements), void 0 !== a.get("list").maxNumberOfElements && (f.maxListSize = a.get("list").maxNumberOfElements), void 0 !== b.getValue) { 22095 if ("string" == typeof b.getValue) { 22096 var g = b.getValue; 22097 f.getValue = function (a) { 22098 return a[g]; 22099 }; 22100 } else "function" == typeof b.getValue && (f.getValue = b.getValue); 22101 } else f.getValue = a.get("getValue"); 22102 return f; 22103 } 22104 function d(b) { 22105 var c = []; 22106 return void 0 === b.xmlElementName && (b.xmlElementName = a.get("xmlElementName")), $(b.data).find(b.xmlElementName).each(function () { 22107 c.push(this); 22108 }), c; 22109 } 22110 this.init = function (b) { 22111 var c = [], 22112 d = {}; 22113 return d.data = a.get("listLocation")(b), d.getValue = a.get("getValue"), d.maxListSize = a.get("list").maxNumberOfElements, c.push(d), c; 22114 }, this.updateCategories = function (b, d) { 22115 if (a.get("categoriesAssigned")) { 22116 b = []; 22117 for (var e = 0; e < a.get("categories").length; e += 1) { 22118 var f = c(a.get("categories")[e], d); 22119 b.push(f); 22120 } 22121 } 22122 return b; 22123 }, this.convertXml = function (b) { 22124 if ("XML" === a.get("dataType").toUpperCase()) for (var c = 0; c < b.length; c += 1) b[c].data = d(b[c]); 22125 return b; 22126 }, this.processData = function (c, d) { 22127 for (var e = 0, f = c.length; f > e; e += 1) c[e].data = b(a, c[e], d); 22128 return c; 22129 }, this.checkIfDataExists = function (a) { 22130 for (var b = 0, c = a.length; c > b; b += 1) if (void 0 !== a[b].data && a[b].data instanceof Array && a[b].data.length > 0) return !0; 22131 return !1; 22132 }; 22133 }, a; 22134 }(EasyAutocomplete || {}), 22135 EasyAutocomplete = function (a) { 22136 return a.proccess = function (b, c, d) { 22137 function e(a, c) { 22138 var d = [], 22139 e = ""; 22140 if (b.get("list").match.enabled) for (var g = 0, h = a.length; h > g; g += 1) e = b.get("getValue")(a[g]), f(e, c) && d.push(a[g]);else d = a; 22141 return d; 22142 } 22143 function f(a, c) { 22144 return b.get("list").match.caseSensitive || ("string" == typeof a && (a = a.toLowerCase()), c = c.toLowerCase()), !!b.get("list").match.method(a, c); 22145 }
22146 function g(a) { 22147 return void 0 !== c.maxNumberOfElements && a.length > c.maxNumberOfElements && (a = a.slice(0, c.maxNumberOfElements)), a; 22148 } 22149 function h(a) { 22150 return b.get("list").sort.enabled && a.sort(b.get("list").sort.method), a; 22151 } 22152 a.proccess.match = f; 22153 var i = c.data, 22154 j = d; 22155 return i = e(i, j), i = g(i), i = h(i); 22156 }, a; 22157 }(EasyAutocomplete || {}), 22158 EasyAutocomplete = function (a) { 22159 return a.Template = function (a) { 22160 var b = { 22161 basic: { 22162 type: "basic", 22163 method: function (a) { 22164 return a; 22165 }, 22166 cssClass: "" 22167 }, 22168 description: { 22169 type: "description", 22170 fields: { 22171 description: "description" 22172 }, 22173 method: function (a) { 22174 return a + " - description"; 22175 }, 22176 cssClass: "eac-description" 22177 }, 22178 iconLeft: { 22179 type: "iconLeft", 22180 fields: { 22181 icon: "" 22182 }, 22183 method: function (a) { 22184 return a; 22185 }, 22186 cssClass: "eac-icon-left" 22187 }, 22188 iconRight: { 22189 type: "iconRight", 22190 fields: { 22191 iconSrc: "" 22192 }, 22193 method: function (a) { 22194 return a; 22195 }, 22196 cssClass: "eac-icon-right" 22197 }, 22198 links: { 22199 type: "links", 22200 fields: { 22201 link: "" 22202 }, 22203 method: function (a) { 22204 return a; 22205 }, 22206 cssClass: "" 22207 }, 22208 custom: { 22209 type: "custom", 22210 method: function () {}, 22211 cssClass: "" 22212 } 22213 }, 22214 c = function (a) { 22215 var c, 22216 d = a.fields; 22217 return "description" === a.type ? (c = b.description.method, "string" == typeof d.description ? c = function (a, b) { 22218 return a + " - <span>" + b[d.description] + "</span>"; 22219 } : "function" == typeof d.description && (c = function (a, b) { 22220 return a + " - <span>" + d.description(b) + "</span>"; 22221 }), c) : "iconRight" === a.type ? ("string" == typeof d.iconSrc ? c = function (a, b) { 22222 return a + "<img class='eac-icon' src='" + b[d.iconSrc] + "' />"; 22223 } : "function" == typeof d.iconSrc && (c = function (a, b) { 22224 return a + "<img class='eac-icon' src='" + d.iconSrc(b) + "' />"; 22225 }), c) : "iconLeft" === a.type ? ("string" == typeof d.iconSrc ? c = function (a, b) { 22226 return "<img class='eac-icon' src='" + b[d.iconSrc] + "' />" + a; 22227 } : "function" == typeof d.iconSrc && (c = function (a, b) { 22228 return "<img class='eac-icon' src='" + d.iconSrc(b) + "' />" + a; 22229 }), c) : "links" === a.type ? ("string" == typeof d.link ? c = function (a, b) { 22230 return "<a href='" + b[d.link] + "' >" + a + "</a>"; 22231 } : "function" == typeof d.link && (c = function (a, b) { 22232 return "<a href='" + d.link(b) + "' >" + a + "</a>"; 22233 }), c) : "custom" === a.type ? a.method : b.basic.method; 22234 }, 22235 d = function (a) { 22236 return a && a.type && a.type && b[a.type] ? c(a) : b.basic.method; 22237 }, 22238 e = function (a) { 22239 var c = function () { 22240 return ""; 22241 }; 22242 return a && a.type && a.type && b[a.type] ? function () { 22243 var c = b[a.type].cssClass; 22244 return function () { 22245 return c; 22246 }; 22247 }() : c; 22248 }; 22249 this.getTemplateClass = e(a), this.build = d(a); 22250 }, a; 22251 }(EasyAutocomplete || {}), 22252 EasyAutocomplete = function (a) { 22253 return a.main = function (b, c) { 22254 function d() { 22255 return 0 === t.length ? void p.error("Input field doesn't exist.") : o.checkDataUrlProperties() ? o.checkRequiredProperties() ? (e(), void g()) : void p.error("Will not work without mentioned properties.") : void p.error("One of options variables 'data' or 'url' must be defined."); 22256 } 22257 function e() { 22258 function a() { 22259 var a = $("<div>"), 22260 c = n.getValue("WRAPPER_CSS_CLASS"); 22261 o.get("theme") && "" !== o.get("theme") && (c += " eac-" + o.get("theme")), o.get("cssClasse
22261s") && "" !== o.get("cssClasses") && (c += " " + o.get("cssClasses")), "" !== q.getTemplateClass() && (c += " " + q.getTemplateClass()), a.addClass(c), t.wrap(a), o.get("adjustWidth") === !0 && b(); 22262 } 22263 function b() { 22264 var a = t.outerWidth(); 22265 t.parent().css("width", a); 22266 } 22267 function c() { 22268 t.unwrap(); 22269 } 22270 function d() { 22271 var a = $("<div>").addClass(n.getValue("CONTAINER_CLASS")); 22272 a.attr("id", f()).prepend($("<ul>")), function () { 22273 a.on("show.eac", function () { 22274 switch (o.get("list").showAnimation.type) { 22275 case "slide": 22276 var b = o.get("list").showAnimation.time, 22277 c = o.get("list").showAnimation.callback; 22278 a.find("ul").slideDown(b, c); 22279 break; 22280 case "fade": 22281 var b = o.get("list").showAnimation.time, 22282 c = o.get("list").showAnimation.callback; 22283 a.find("ul").fadeIn(b), c; 22284 break; 22285 default: 22286 a.find("ul").show(); 22287 } 22288 o.get("list").onShowListEvent(); 22289 }).on("hide.eac", function () { 22290 switch (o.get("list").hideAnimation.type) { 22291 case "slide": 22292 var b = o.get("list").hideAnimation.time, 22293 c = o.get("list").hideAnimation.callback; 22294 a.find("ul").slideUp(b, c); 22295 break; 22296 case "fade": 22297 var b = o.get("list").hideAnimation.time, 22298 c = o.get("list").hideAnimation.callback; 22299 a.find("ul").fadeOut(b, c); 22300 break; 22301 default: 22302 a.find("ul").hide(); 22303 } 22304 o.get("list").onHideListEvent(); 22305 }).on("selectElement.eac", function () { 22306 a.find("ul li").removeClass("selected"), a.find("ul li").eq(w).addClass("selected"), o.get("list").onSelectItemEvent(); 22307 }).on("loadElements.eac", function (b, c, d) { 22308 var e = "", 22309 f = a.find("ul"); 22310 f.empty().detach(), v = []; 22311 for (var h = 0, i = 0, k = c.length; k > i; i += 1) { 22312 var l = c[i].data; 22313 if (0 !== l.length) { 22314 void 0 !== c[i].header && c[i].header.length > 0 && f.append("<div class='eac-category' >" + c[i].header + "</div>"); 22315 for (var m = 0, n = l.length; n > m && h < c[i].maxListSize; m += 1) e = $("<li><div class='eac-item'></div></li>"), function () { 22316 var a = m, 22317 b = h, 22318 f = c[i].getValue(l[a]); 22319 e.find(" > div").on("click", function () { 22320 t.val(f).trigger("change"), w = b, j(b), o.get("list").onClickEvent(), o.get("list").onChooseEvent(); 22321 }).mouseover(function () { 22322 w = b, j(b), o.get("list").onMouseOverEvent(); 22323 }).mouseout(function () { 22324 o.get("list").onMouseOutEvent(); 22325 }).html(q.build(g(f, d), l[a])); 22326 }(), f.append(e), v.push(l[m]), h += 1; 22327 } 22328 } 22329 a.append(f), o.get("list").onLoadEvent(); 22330 }); 22331 }(), t.after(a); 22332 } 22333 function e() { 22334 t.next("." + n.getValue("CONTAINER_CLASS")).remove(); 22335 } 22336 function g(a, b) { 22337 return o.get("highlightPhrase") && "" !== b ? i(a, b) : a; 22338 } 22339 function h(a) { 22340 return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); 22341 } 22342 function i(a, b) { 22343 var c = h(b); 22344 return (a + "").replace(new RegExp("(" + c + ")", "gi"), "<b>$1</b>"); 22345 } 22346 t.parent().hasClass(n.getValue("WRAPPER_CSS_CLASS")) && (e(), c()), a(), d(), u = $("#" + f()), o.get("placeholder") && t.attr("placeholder", o.get("placeholder")); 22347 } 22348 function f() { 22349 var a = t.attr("id"); 22350 return a = n.getValue("CONTAINER_ID") + a; 22351 } 22352 function g() { 22353 function a() { 22354 s("autocompleteOff", !0) && n(), b(), c(), d(), e(), f(), g(); 22355 } 22356 function b() { 22357 t.focusout(function () { 22358 var a, 22359 b = t.val(); 22360 o.get("list").match.caseSensitive || (b = b.toLowerCase()); 22361 for (var c = 0, d = v.length; d > c; c += 1) if (a = o.get("getValue")(v[c]), o.get("list").match.caseSensitive || (a = a.toLowerCase()), a === b) return w = c, void j(w); 22362 }); 22363 } 22364 function c() { 22365 t.off("keyup").keyup(function (a) { 22366 function b(a) { 22367 function b() { 22368 var a = {}, 22369 b = o.get("ajaxSettings") || {}; 22370 for (var c in b) a[c] = b[c]; 22371 return a; 22372 } 22373 function c(a, b) { 22374 return o.get("matchResponseProperty") !== !1 ? "string" == typeof o.get("matchResponseProperty") ? b[o.get("matchResponseProperty")] === a : "function" == typeof o.get("matchResponseProperty") ? o.get("matchResponseProperty")(b) === a : !0 : !0; 22375 } 22376 if (!(a.length < o.get("minCharNumber"))) { 22377 if ("list-required" !== o.get("data")) { 22378 var d = o.get("data"), 22379 e = r.init(d); 22380 e = r.updateCategories(e, d), e = r.processData(e, a), k(e, a), t.parent().find("li").length > 0 ? h() : i(); 22381 } 22382 var f = b(); 22383 void 0 !== f.url && "" !== f.url || (f.url = o.get("url")), void 0 !== f.dataType && "" !== f.dataType || (f.dataType = o.get("dataType")), void 0 !== f.url && "list-required" !== f.url && (f.url = f.url(a), f.data = o.get("preparePostData")(f.data, a), $.ajax(f).done(function (b) { 22384 var d = r.init(b); 22385 d = r.updateCategories(d, b), d = r.convertXml(d), c(a, b) && (d = r.processData(d, a), k(d, a)), r.checkIfDataExists(d) && t.parent().find("li").length > 0 ? h() : i(), o.get("ajaxCallback")(); 22386 }).fail(function () { 22387 p.warning("Fail to load response data"); 22388 }).always(function () {})); 22389 } 22390 } 22391 switch (a.keyCode) { 22392 case 27: 22393 i(), l(); 22394 break; 22395 case 38: 22396 a.preventDefault(), v.length > 0 && w > 0 && (w -= 1, t.val(o.get("getValue")(v[w])), j(w)); 22397 break; 22398 case 40: 22399 a.preventDefault(), v.length > 0 && w < v.length - 1 && (w += 1, t.val(o.get("getValue")(v[w])), j(w)); 22400 break; 22401 default: 22402 if (a.keyCode > 40 || 8 === a.keyCode) { 22403 var c = t.val(); 22404 o.get("list").hideOnEmptyPhrase !== !0 || 8 !== a.keyCode || "" !== c ? o.get("requestDelay") > 0 ? (void 0 !== m && clearTimeout(m), m = setTimeout(function () { 22405 b(c); 22406 }, o.get("requestDelay"))) : b(c) : i(); 22407 } 22408 } 22409 }); 22410 } 22411 function d() {
22412 t.on("keydown", function (a) { 22413 a = a || window.event; 22414 var b = a.keyCode; 22415 return 38 === b ? (suppressKeypress = !0, !1) : void 0; 22416 }).keydown(function (a) { 22417 13 === a.keyCode && w > -1 && (t.val(o.get("getValue")(v[w])), o.get("list").onKeyEnterEvent(), o.get("list").onChooseEvent(), w = -1, i(), a.preventDefault()); 22418 }); 22419 } 22420 function e() { 22421 t.off("keypress"); 22422 } 22423 function f() { 22424 t.focus(function () { 22425 "" !== t.val() && v.length > 0 && (w = -1, h()); 22426 }); 22427 } 22428 function g() { 22429 t.blur(function () { 22430 setTimeout(function () { 22431 w = -1, i(); 22432 }, 250); 22433 }); 22434 } 22435 function n() { 22436 t.attr("autocomplete", "off"); 22437 } 22438 a(); 22439 } 22440 function h() { 22441 u.trigger("show.eac"); 22442 } 22443 function i() { 22444 u.trigger("hide.eac"); 22445 } 22446 function j(a) { 22447 u.trigger("selectElement.eac", a); 22448 } 22449 function k(a, b) { 22450 u.trigger("loadElements.eac", [a, b]); 22451 } 22452 function l() { 22453 t.trigger("blur"); 22454 } 22455 var m, 22456 n = new a.Constans(), 22457 o = new a.Configuration(c), 22458 p = new a.Logger(), 22459 q = new a.Template(c.template), 22460 r = new a.ListBuilderService(o, a.proccess), 22461 s = o.equals, 22462 t = b, 22463 u = "", 22464 v = [], 22465 w = -1; 22466 a.consts = n, this.getConstants = function () { 22467 return n; 22468 }, this.getConfiguration = function () { 22469 return o; 22470 }, this.getContainer = function () { 22471 return u; 22472 }, this.getSelectedItemIndex = function () { 22473 return w; 22474 }, this.getItems = function () { 22475 return v; 22476 }, this.getItemData = function (a) { 22477 return v.length < a || void 0 === v[a] ? -1 : v[a]; 22478 }, this.getSelectedItemData = function () { 22479 return this.getItemData(w); 22480 }, this.build = function () { 22481 e(); 22482 }, this.init = function () { 22483 d(); 22484 }; 22485 }, a.eacHandles = [], a.getHandle = function (b) { 22486 return a.eacHandles[b]; 22487 }, a.inputHasId = function (a) { 22488 return void 0 !== $(a).attr("id") && $(a).attr("id").length > 0; 22489 }, a.assignRandomId = function (b) { 22490 var c = ""; 22491 do c = "eac-" + Math.floor(1e4 * Math.random()); while (0 !== $("#" + c).length); 22492 elementId = a.consts.getValue("CONTAINER_ID") + c, $(b).attr("id", c); 22493 }, a.setHandle = function (b, c) { 22494 a.eacHandles[c] = b; 22495 }, a; 22496 }(EasyAutocomplete || {}); 22497!function (a) { 22498 a.fn.easyAutocomplete = function (b) { 22499 return this.each(function () { 22500 var c = a(this), 22501 d = new EasyAutocomplete.main(c, b); 22502 EasyAutocomplete.inputHasId(c) || EasyAutocomplete.assignRandomId(c), d.init(), EasyAutocomplete.setHandle(d, c.attr("id")); 22503 }); 22504 }, a.fn.getSelectedItemIndex = function () { 22505 var b = a(this).attr("id"); 22506 return void 0 !== b ? EasyAutocomplete.getHandle(b).getSelectedItemIndex() : -1; 22507 }, a.fn.getItems = function () { 22508 var b = a(this).attr("id"); 22509 return void 0 !== b ? EasyAutocomplete.getHandle(b).getItems() : -1; 22510 }, a.fn.getItemData = function (b) { 22511 var c = a(this).attr("id"); 22512 return void 0 !== c && b > -1 ? EasyAutocomplete.getHandle(c).getItemData(b) : -1; 22513 }, a.fn.getSelectedItemData = function () { 22514 var b = a(this).attr("id"); 22515 return void 0 !== b ? EasyAutocomplete.getHandle(b).getSelectedItemData() : -1; 22516 }; 22517}((jquery_default())); 22518;// ./wp-content/themes/sfrtheme/assets/js/LazyLoad.js 22519class LazyLoad { 22520 constructor(element = 'lazy', threshold = 0, timeout = 70) { 22521 this.element = element; 22522 this.threshold = threshold; 22523 this.timeout = timeout; 22524 this.onChange = this.onChange.bind(this); 22525 this.observer = new IntersectionObserver(this.onChange, { 22526 threshold: [this.threshold] 22527 }); 22528 this.lazyLoadinit; 22529 } 22530 get lazyLoadinit() { 22531 const { 22532 element, 22533 observer 22534 } = this; 22535 $.each($(`.${element}`), (index, img) => { 22536 observer.observe(img); 22537 }); 22538 return this.element; 22539 }
22540 onChange(changes) { 22541 let i = 0; 22542 const { 22543 observer, 22544 timeout 22545 } = this; 22546 $.each(changes, (index, change) => { 22547 if (change.isIntersecting) { 22548 if (change.target.classList.contains('lazy') && !change.target.classList.contains('anim')) { 22549 if (change.target.localName === 'img') { 22550 change.target.src = change.target.dataset.src; 22551 } else { 22552 change.target.style.backgroundImage = 'url("' + change.target.dataset.src + '")'; 22553 } 22554 } 22555 setTimeout(function () { 22556 change.target.classList.add('visible'); 22557 }, timeout * i); 22558 i++; 22559 observer.unobserve(change.target); 22560 } 22561 }); 22562 } 22563} 22564;// ./wp-content/themes/sfrtheme/assets/js/popins.js 22565function ajaxGetPopinContent(contentID, phoneID) { 22566 $('body').append('<div class="loader"></div>'); 22567 $('body').addClass('loading'); 22568 var params = { 22569 contentID: contentID 22570 }; 22571 if (phoneID != false) { 22572 var params = { 22573 contentID: contentID, 22574 phoneID: phoneID 22575 }; 22576 } 22577 $.ajax({ 22578 url: sfrJSVars.ajaxurl, 22579 method: 'POST', 22580 data: { 22581 'action': 'ajaxGetPopinContentHTML', 22582 'params': params 22583 }, 22584 success: function (data) { 22585 data = JSON.parse(data); 22586 $(data).insertAfter('.footer'); 22587 modalActions(); 22588 $('body').addClass('stop_scrolling'); 22589 $('body').removeClass('loading'); 22590 $('body>.loader').remove(); 22591 }, 22592 error: function (request, error) { 22593 console.log(error); 22594 } 22595 }); 22596} 22597function initForfaitTypePopin() { 22598 $(document).on('click', '.forfait-type-learn-more', function (e) { 22599 e.preventDefault(); 22600 const forfaitType = $(this).data('forfait-type'); 22601 $('body').append('<div class="loader"></div>'); 22602 $('body').addClass('loading'); 22603 $.ajax({ 22604 url: sfrJSVars.ajaxurl, 22605 method: 'POST', 22606 data: { 22607 action: 'ajaxGetPopinContentHTML', 22608 params: { 22609 contentID: 'forfait_type', 22610 forfaitType: forfaitType 22611 } 22612 }, 22613 success: function (data) { 22614 data = JSON.parse(data); 22615 $(data).insertAfter('.footer'); 22616 modalActions(); 22617 $('body').addClass('stop_scrolling'); 22618 $('body').removeClass('loading'); 22619 $('body>.loader').remove(); 22620 }, 22621 error: function (request, error) { 22622 console.log(error); 22623 $('body').removeClass('loading'); 22624 $('body>.loader').remove(); 22625 } 22626 }); 22627 }); 22628} 22629 22630// Handle energy class modal click 22631function initEnergyClassModal() { 22632 $('.energy-class-modal').on('click', function (e) { 22633 e.preventDefault(); 22634 const phoneId = $(this).data('phone-id'); 22635 const energyClass = $(this).data('class'); 22636 $('body').append('<div class="loader"></div>'); 22637 $('body').addClass('loading'); 22638 $.ajax({ 22639 url: sfrJSVars.ajaxurl, 22640 method: 'POST', 22641 data: { 22642 'action': 'ajaxGetPopinContentHTML', 22643 'params': { 22644 'contentID': 'energy_class', 22645 'phoneID': phoneId, 22646 'class': energyClass 22647 } 22648 }, 22649 success: function (data) { 22650 data = JSON.parse(data); 22651 $(data).insertAfter('.footer'); 22652 modalActions(); 22653 $('body').addClass('stop_scrolling'); 22654 $('body').removeClass('loading'); 22655 $('body>.loader').remove(); 22656 }, 22657 error: function (request, error) { 22658 console.log(error); 22659 } 22660 }); 22661 }); 22662} 22663function modalActions() { 22664 $('.modal footer>p').click(function () { 22665 $(this).parents('footer').find('>div').slideToggle(200); 22666 $('.modal .content').animate({ 22667 scrollTop: $('.modal footer').offset().top 22668 }, 200); 22669 }); 22670 $('.modal .close').click(function () { 22671 $(this).parents('.modal').remove(); 22672 $('body').removeClass('stop_scrolling'); 22673 }); 22674 $('.modal .choose_accessory').click(function () { 22675 $(this).parents('.modal').remove(); 22676 $('body').removeClass('stop_scrolling'); 22677 }); 22678} 22679;// ./wp-content/themes/sfrtheme/assets/js/datalayer/planTracking.js 22680const STORAGE_PLAN_KEY = 'plan_tracking'; 22681const STORAGE_USER_KEY = 'plan_user_data'; 22682const parsePrice = text => { 22683 const normalized = String(text || '').replace(/\s/g, ''); 22684 const match = normalized.match(/([\d]+)[,.]([\d]+)/); 22685 if (!match) { 22686 return 0; 22687 } 22688 return parseFloat(`${match[1]}.${match[2]}`); 22689}; 22690const PlanTracking = { 22691 config: { 22692 planName: '', 22693 planPrice: 0, 22694 phonePrefix: '+33' 22695 }, 22696 sha256(value) { 22697 if (!value || !window.crypto?.subtle) { 22698 return Promise.resolve(''); 22699 } 22700 return window.crypto.subtle.digest('SHA-256', new TextEncoder().encode(value)).then(buffer => Array.from(new Uint8Array(buffer)).map(byte => byte.toString(16).padStart(2, '0')).join('')); 22701 }, 22702 normalizeEmail(email) { 22703 return String(email || '').trim().toLowerCase(); 22704 }, 22705 normalizePhone(phone, prefix = this.config.phonePrefix) { 22706 let digits = String(phone || '').replace(/\D/g, ''); 22707 const phonePrefix = prefix || '+33'; 22708 if (digits.startsWith('0')) { 22709 digits = phonePrefix.replace('+', '') + digits.slice(1); 22710 } else if (!digits.startsWith(phonePrefix.replace('+', ''))) { 22711 digits = phonePrefix.replace('+', '') + digits; 22712 } 22713 return '+' + digits.replace(/^\+/, ''); 22714 }, 22715 async buildUserData(email, phone) { 22716 const userData = {}; 22717 if (email) { 22718 userData.sha256_email_address = await this.sha256(this.normalizeEmail(email)); 22719 } 22720 if (phone) { 22721 userData.sha256_phone_number = await this.sha256(this.normalizePhone(phone)); 22722 } 22723 return userData; 22724 }, 22725 persistPlan(planName, planPrice) { 22726 const plan = { 22727 planName, 22728 planPrice: Number(planPrice) || 0 22729 }; 22730 sessionStorage.setItem(STORAGE_PLAN_KEY, JSON.stringify(plan)); 22731 this.config.planName = planName; 22732 this.config.planPrice = plan.planPrice; 22733 }, 22734 loadPlan() { 22735 const stored = sessionStorage.getItem(STORAGE_PLAN_KEY); 22736 if (!stored) { 22737 return null; 22738 } 22739 try { 22740 const plan = JSON.parse(stored); 22741 if (plan.planName) { 22742 this.config.planName = plan.planName; 22743 } 22744 if (typeof plan.planPrice !== 'undefined') { 22745 this.config.planPrice = Number(plan.planPrice) || 0; 22746 } 22747 return plan; 22748 } catch (error) { 22749 return null; 22750 } 22751 }, 22752 readPlanData($element) { 22753 const planName = $element.attr('data-plan-name') || $element.data('plan-name') || ''; 22754 const planPriceRaw = $element.attr('data-plan-price') ?? $element.data('plan-price'); 22755 const planPrice = planPriceRaw !== undefined && planPriceRaw !== '' ? Number(planPriceRaw) : NaN; 22756 return { 22757 planName: String(planName).trim(), 22758 planPrice 22759 }; 22760 }, 22761 getPlanFromElement($element) { 22762 const $card = $element.closest('#archive_ff li, .forfait, li'); 22763 let { 22764 planName, 22765 planPrice 22766 } = this.readPlanData($element); 22767 if (!planName || Number.isNaN(planPrice)) { 22768 const $visiblePrice = $card.find('.prices li:visible').first(); 22769 const visiblePlan = this.readPlanData($visiblePrice); 22770 planName = planName || visiblePlan.planName; 22771 planPrice = Number.isNaN(planPrice) ? visiblePlan.planPrice : planPrice; 22772 } 22773 if (!planName) { 22774 planName = $card.find('.title-price .title').first().text().trim() || $card.find('h2 span').first().text().trim(); 22775 } 22776 if (Number.isNaN(planPrice) || !planPrice) { 22777 planPrice = parsePrice($card.find('.prices li:visible .current').first().text()); 22778 } 22779 return { 22780 planName, 22781 planPrice: Number(planPrice) || 0 22782 }; 22783 }, 22784 buildPayload(eventName, planName, planPrice, extra = {}) { 22785 return { 22786 event: eventName, 22787 plan_name: planName, 22788 plan_price: Number(planPrice) || 0, 22789 ...extra 22790 }; 22791 }, 22792 push(eventName, extra = {}) { 22793 const payload = this.buildPayload(eventName, this.config.planName, this.config.planPrice, extra); 22794 window.dataLayer = window.dataLayer || []; 22795 window.dataLayer.push(payload); 22796 }, 22797 pushPlanEvent(eventName, planName, planPrice, extra = {}) { 22798 this.persistPlan(planName, planPrice); 22799 const payload = this.buildPayload(eventName, planName, planPrice, extra); 22800 window.dataLayer = window.dataLayer || []; 22801 window.dataLayer.push(payload); 22802 }, 22803 pushPlanEventWithUserData(eventName, planName, planPrice, userData, extra = {}) { 22804 const payloadExtra = { 22805 ...extra 22806 }; 22807 if (userData && Object.keys(userData).length > 0) { 22808 payloadExtra.user_data = userData; 22809 } 22810 this.pushPlanEvent(eventName, planName, planPrice, payloadExtra); 22811 } 22812}; 22813PlanTracking.loadPlan(); 22814/* harmony default export */ const planTracking = (PlanTracking); 22815;// ./wp-content/themes/sfrtheme/assets/js/pageForfaits.js 22816 22817 22818 22819 22820 22821jquery_default()(document).ready(function () { 22822 forfaitPageEventListener(); 22823 //carrouselForfait(); 22824 forfaitsFiltersListener(); 22825 forfaitsFiltersPosition(); 22826 initEngagementFilter(); 22827 initPlanAddPhonePopin(); 22828}); 22829function forfaitsFiltersListener() { 22830 // Gestion des filtres mob/box (comportement existant avec AJAX) 22831 // Utiliser la délégation d'événements pour gérer les éléments ajoutés dynamiquement 22832 jquery_default()(document).on("click", "#archive_ff .filters form:not(.engagement-filter) label", function (e) { 22833 if (jquery_default()("#archive_ff .filters form").hasClass("busy")) { 22834 e.preventDefault(); 22835 } 22836 }); 22837 jquery_default()(document).on("change", "#archive_ff .filters form:not(.engagement-filter) input", function (e) { 22838 if (!jquery_default()("#archive_ff .filters form").hasClass("busy")) { 22839 const action = jquery_default()(this).parents("form").hasClass("mob") ? "ajaxChangeForfaitMobType" : "ajaxChangeForfaitBoxType"; 22840 changeSessionSettings({ 22841 params: { 22842 postType: jquery_default()("#archive_ff").data("posttype"), 22843 pageID: jquery_default()("#archive_ff").data("pageid"), 22844 forfaitType: jquery_default()(this).val() 22845 }, 22846 action 22847 }); 22848 } 22849 }); 22850 22851 // Gestion du filtre d'engagement (filtrage côté client, sans AJAX) 22852 jquery_default()(document).on("change", ".engagement-filter input", function (e) { 22853 applyFilters(); 22854 }); 22855 22856 // Gestion du filtre Gold/Silver avec boutons (filtrage côté client, sans AJAX) 22857 jquery_default()(document).on("click", ".forfait_type_btn", function (e) { 22858 // Ne rien faire si le bouton cliqué est déjà actif 22859 if (jquery_default()(this).hasClass("active")) { 22860 return; 22861 } 22862 22863 // Retirer la classe active de tous les boutons et l'ajouter au bouton cliqué 22864 jquery_default()(".forfait_type_btn").removeClass("active"); 22865 jquery_default()(this).addClass("active"); 22866 22867 // Mettre à jour le titre en fonction du type sélectionné 22868 updateForfaitTypeTitle(jquery_default()(this).data("forfait-type")); 22869 22870 // Appliquer les filtres 22871 applyFilters(); 22872 }); 22873} 22874function updateForfaitTypeTitle(type) { 22875 const $goldTitle = jquery_default()(".forfait-type-title.gold"); 22876 const $silverTitle = jquery_default()(".forfait-type-title.silver"); 22877 const $goldContent = jquery_default()(".forfait-type-contents .gold"); 22878 const $silverContent = jquery_default()(".forfait-type-contents .silver"); 22879 if (type === "gold") { 22880 $goldTitle.addClass("active"); 22881 $silverTitle.removeClass("active"); 22882 $goldContent.addClass("active"); 22883 $silverContent.removeClass("active"); 22884 } else if (type === "silver") { 22885 $silverTitle.addClass("active"); 22886 $goldTitle.removeClass("active"); 22887 $silverContent.addClass("active"); 22888 $goldContent.removeClass("active"); 22889 } 22890} 22891function applyFilters() { 22892 jquery_default()(".forfaits_container").each(function () { 22893 const $container = jquery_default()(this); 22894 const selectedEngagement = $container.find(".engagement-filter input:checked").val(); 22895 22896 // On ne récupère le type que si le filtre est visible 22897 const $typeFilter = $container.find(".forfait-type-filter"); 22898 const selectedForfaitType = $typeFilter.length > 0 && !$typeFilter.hasClass("hidden") ? $container.find(".forfait_type_btn.active").data("forfait-type") : null; 22899 22900 // Masquer tous les prix du conteneur d'abord 22901 $container.find(".advantages > li .prices ul li").hide(); 22902 22903 // Appliquer les filtres forfait par forfait 22904 $container.find(".advantages > li").each(function () { 22905 const $forfait = jquery_default()(this); 22906 const $forfaitPrices = $forfait.find(".prices ul li"); 22907 22908 // Vérifier si un prix "Silver" existe dans ce forfait précis 22909 let hasSilver = false;
22910 $forfaitPrices.each(function () { 22911 if ((jquery_default()(this).data("forfait-type") || "").toLowerCase() === "silver") { 22912 hasSilver = true; 22913 } 22914 }); 22915 let hasMatchingPrice = false; 22916 $forfaitPrices.each(function (index) { 22917 const $price = jquery_default()(this); 22918 const priceEngagement = $price.data("engagement"); 22919 const priceType = $price.data("forfait-type"); 22920 const planPrice = $price.attr("data-plan-price"); 22921 const hasPrice = planPrice !== undefined && planPrice !== ""; 22922 let matchesEngagement = false; 22923 let matchesForfaitType = false; 22924 if (selectedEngagement) { 22925 matchesEngagement = priceEngagement === selectedEngagement; 22926 } else { 22927 matchesEngagement = true; 22928 } 22929 if (selectedForfaitType) { 22930 matchesForfaitType = priceType === selectedForfaitType; 22931 } else if (!selectedEngagement) { 22932 if (hasSilver) { 22933 matchesForfaitType = priceType === "silver"; 22934 } else { 22935 matchesForfaitType = index === 0; 22936 } 22937 } else { 22938 matchesForfaitType = true; 22939 } 22940 if (matchesEngagement && matchesForfaitType && hasPrice) { 22941 $price.show(); 22942 hasMatchingPrice = true; 22943 } 22944 }); 22945 if (selectedEngagement) { 22946 $forfait.toggle(hasMatchingPrice); 22947 } else { 22948 $forfait.show(); 22949 } 22950 updateDynamicFormulaButtons($forfait); 22951 }); 22952 const $noResult = $container.find(".engagement-no-result"); 22953 if ($noResult.length) { 22954 const hasVisibleForfait = $container.find(".advantages > li:visible").length > 0; 22955 $noResult.toggle(!!selectedEngagement && !hasVisibleForfait); 22956 } 22957 }); 22958} 22959function initEngagementFilter() { 22960 applyFilters(); 22961 jquery_default()('#archive_ff .forfaits_container .advantages > li').each(function () { 22962 updateDynamicFormulaButtons(jquery_default()(this)); 22963 }); 22964} 22965function updateDynamicFormulaButtons($forfait) { 22966 // Trouver le prix visible (celui qui n'est pas caché) 22967 const $visiblePrice = $forfait.find(".prices ul li:visible").first(); 22968 if ($visiblePrice.length === 0) return; 22969 22970 // Récupérer les données de la formule visible 22971 const formulaId = $visiblePrice.data("formula-id"); 22972 const lockedFormulaId = $visiblePrice.data("locked-formula-id"); 22973 const planName = $visiblePrice.attr("data-plan-name") || $visiblePrice.data("plan-name"); 22974 const planPrice = $visiblePrice.attr("data-plan-price") || $visiblePrice.data("plan-price"); 22975 const $dynamicButtons = $forfait.find(".actions .dynamic-formula-btn"); 22976 $dynamicButtons.each(function () { 22977 const $btn = jquery_default()(this); 22978 if (planName) { 22979 $btn.attr("data-plan-name", planName); 22980 } 22981 if (planPrice !== undefined && planPrice !== "") { 22982 $btn.attr("data-plan-price", planPrice); 22983 } 22984 if ($btn.is("a")) { 22985 const currentHref = $btn.attr("href"); 22986 22987 // Remplacer l'ID de la formule dans l'URL 22988 const newHref = currentHref.replace(/formula=\d+/, "formula=" + formulaId); 22989 $btn.attr("href", newHref); 22990 } 22991 // Si c'est un span avec popin_action 22992 else if ($btn.is("span") && $btn.hasClass("popin_action")) { 22993 if (lockedFormulaId) { 22994 $btn.attr("data-id", lockedFormulaId); 22995 } 22996 } else { 22997 $btn.attr("data-formula-id", formulaId); 22998 } 22999 }); 23000} 23001function forfaitsFiltersPosition() { 23002 if (jquery_default()("#archive_ff").length > 0 && jquery_default()("#archive_ff .filters").length > 0) { 23003 var $filters = jquery_default()("#archive_ff .filters"); 23004 23005 // Create or find the spacer element 23006 var $spacer = jquery_default()("#archive_ff .filters-spacer"); 23007 if ($spacer.length === 0) { 23008 // Create spacer if it doesn't exist 23009 $spacer = jquery_default()('<div class="filters-spacer"></div>'); 23010 $filters.before($spacer); 23011 } 23012 onScrollMoveFilters($filters, $spacer); 23013 jquery_default()(document).on("scroll", function () { 23014 onScrollMoveFilters($filters, $spacer); 23015 }); 23016 jquery_default()(window).resize(function () { 23017 onScrollMoveFilters($filters, $spacer); 23018 }); 23019 } 23020} 23021function onScrollMoveFilters($filters, $spacer) { 23022 // Add null/existence checks 23023 if (!$filters || $filters.length === 0 || !$spacer || $spacer.length === 0) { 23024 return; 23025 } 23026 var filtersTop = parseInt($spacer.offset().top), 23027 filtersHeight = $filters.innerHeight(), 23028 siteHeaderHeight = jquery_default()("#heading").innerHeight() + (jquery_default()("#wpadminbar").length > 0 ? jquery_default()("#wpadminbar").innerHeight() : 0), 23029 screenTopScrollPosition = jquery_default()(document).scrollTop(), 23030 $container = jquery_default()("#archive_ff .forfait_list"); 23031 23032 // Check if container exists 23033 if ($container.length === 0) { 23034 return; 23035 } 23036 var containerBottomPosition = parseInt($container.offset().top) + $container.innerHe
23036ight(), 23037 startPosition = screenTopScrollPosition + siteHeaderHeight, 23038 stopPosition = containerBottomPosition - (siteHeaderHeight + filtersHeight); 23039 if (filtersTop < startPosition) { 23040 if (stopPosition > screenTopScrollPosition) { 23041 $filters.addClass("scrolled"); 23042 $filters.css({ 23043 top: `${siteHeaderHeight}px` 23044 }); 23045 $spacer.css({ 23046 height: `${filtersHeight}px` 23047 }); 23048 } else { 23049 $filters.css({ 23050 top: `${siteHeaderHeight - (screenTopScrollPosition - stopPosition)}px` 23051 }); 23052 } 23053 } else { 23054 $filters.removeClass("scrolled"); 23055 $filters.css({ 23056 top: `auto` 23057 }); 23058 $spacer.css({ 23059 height: `0` 23060 }); 23061 } 23062} 23063 23064/** 23065 * FOR DATAS 23066 **/ 23067function forfaitPageEventListener() { 23068 // Utiliser la délégation d'événements pour tous les listeners 23069 jquery_default()(document).on("click", "#archive_ff .phone_block .phone_btn", function (e) { 23070 if (!jquery_default()(this).parents(".forfaits_container").hasClass("busy")) { 23071 const phoneOption = jquery_default()(this).data("phone-option"); 23072 const displayPhone = phoneOption === "with"; 23073 23074 // Ne rien faire si le bouton cliqué est déjà actif 23075 if (jquery_default()(this).hasClass("active")) { 23076 return; 23077 } 23078 jquery_default()(this).parents(".forfaits_container").addClass("busy"); 23079 23080 // Retirer la classe active de tous les boutons et l'ajouter au bouton cliqué 23081 jquery_default()(this).parents(".forfaits_container").parent().find(".phone_block .phone_btn").removeClass("active"); 23082 jquery_default()(this).parents(".forfaits_container").parent().find('.phone_block .phone_btn[data-phone-option="' + phoneOption + '"]').addClass("active"); 23083 23084 // Automatisation JS : "Sans téléphone" décoche "Avec engagement" 23085 const $container = jquery_default()(this).parents(".forfaits_container"); 23086 const $withoutEngagementLi = $container.find(".without-engagement-li"); 23087 if (displayPhone) { 23088 $container.find('.engagement-filter input[value="with-engagement"]').prop("checked", true); 23089 $withoutEngagementLi.hide(); 23090 } else { 23091 $container.find('.engagement-filter input[value="without-engagement"]').prop("checked", true); 23092 $withoutEngagementLi.show(); 23093 } 23094 23095 // Afficher/masquer le filtre Gold/Silver en fonction du choix 23096 const $forfaitTypeFilter = jquery_default()(this).parents(".forfaits_container").parent().find(".forfait-type-filter"); 23097 if (displayPhone) { 23098 $forfaitTypeFilter.removeClass("hidden"); 23099 } else { 23100 $forfaitTypeFilter.addClass("hidden"); 23101 } 23102 changeSessionSettings({ 23103 params: { 23104 postType: jquery_default()("#archive_ff").data("posttype"), 23105 pageID: jquery_default()("#archive_ff").data("pageid"), 23106 displayPhone: displayPhone 23107 }, 23108 action: "ajaxToggleAddPhoneToForfait", 23109 reload: true // On garde le reload ici pour que le PHP se synchronise 23110 }); 23111 } 23112 }); 23113 jquery_default()(document).on("click", ".container .advantages > li .accordion .title", function () { 23114 if (jquery_default()(this).closest(".forfaits_blocs").hasClass("loading")) { 23115 return; 23116 } 23117 const $title = jquery_default()(this); 23118 const $list = $title.siblings("ul").first(); 23119 if (!$list.length) { 23120 return; 23121 } 23122 const isOpen = $list.is(":visible"); 23123 $list.stop(true, true); 23124 if (isOpen) { 23125 $list.slideUp(); 23126 $title.removeClass("open"); 23127 } else { 23128 $list.slideDown(); 23129 $title.addClass("open"); 23130 } 23131 }); 23132 jquery_default()(document).on("click", "#archive_ff .popin_action", function () { 23133 if (jquery_default()(this).data("phoneid")) { 23134 ajaxGetPopinContent(jquery_default()(this).data("id"), jquery_default()(this).data("phoneid")); 23135 } else { 23136 ajaxGetPopinContent(jquery_default()(this).data("id")); 23137 } 23138 }); 23139 jquery_default()(document).on("click", "#archive_ff .phone_block .portabilite", function (e) { 23140 if (!jquery_default()(this).parents(".forfaits_container").hasClass("busy")) { 23141 jquery_default()(this).parents(".forfaits_container").addClass("busy"); 23142 jquery_default()(this).parents(".forfaits_container").parent().find(".phone_block .portabilite").toggleClass("active"); 23143 let portability = false;
23144 if (jquery_default()(this).parents(".forfaits_container").parent().find(".phone_block .portabilite").hasClass("active")) { 23145 portability = true; 23146 } 23147 changeSessionSettings({ 23148 params: { 23149 postType: jquery_default()("#archive_ff").data("posttype"), 23150 pageID: jquery_default()("#archive_ff").data("pageid"), 23151 portability: portability 23152 }, 23153 action: "ajaxTogglePortability" 23154 }); 23155 } 23156 }); 23157 jquery_default()(document).on("click", ".switchboxtv", function (e) { 23158 e.preventDefault(); 23159 if (!jquery_default()(this).parents(".forfaits_container").hasClass("busy")) { 23160 jquery_default()(this).parents(".forfaits_container").addClass("busy"); 23161 jquery_default()(this).toggleClass("active"); 23162 let isBoxTV = jquery_default()(this).hasClass("active"); 23163 const archiveRoot = jquery_default()(this).closest("#archive_ff"); 23164 changeSessionSettings({ 23165 params: { 23166 postType: archiveRoot.data("posttype"), 23167 pageID: archiveRoot.data("pageid"), 23168 isBoxTV: isBoxTV 23169 }, 23170 action: "ajaxToggleBoxTV", 23171 archiveRoot: archiveRoot.length ? archiveRoot : null 23172 }); 23173 } 23174 }); 23175} 23176function changeSessionSettings({ 23177 params, 23178 action, 23179 reload = true, 23180 archiveRoot = null 23181}) { 23182 if (params.postType && params.pageID) { 23183 const $archive = archiveRoot && archiveRoot.length ? archiveRoot : jquery_default()("#archive_ff").first(); 23184 if (reload) { 23185 $archive.find(".forfait_list .forfaits_blocs").addClass("loading"); 23186 } 23187 jquery_default().ajax({ 23188 url: sfrJSVars.ajaxurl, 23189 method: "POST", 23190 data: { 23191 action: action, 23192 params: params 23193 }, 23194 success: function (data) { 23195 if (reload) { 23196 reloadForfaitVue(params, $archive); 23197 } else { 23198 jquery_default()(".forfaits_container").removeClass("busy"); 23199 } 23200 }, 23201 error: function (request, error) { 23202 console.log(error); 23203 jquery_default()(".forfaits_container").removeClass("busy"); 23204 if (reload) { 23205 $archive.find(".forfait_list .forfaits_blocs").removeClass("loading"); 23206 } 23207 } 23208 }); 23209 } else { 23210 console.log("Error no postType has been set"); 23211 } 23212} 23213function reloadForfaitVue(params, archiveRoot = null) { 23214 if (params.postType && params.pageID) { 23215 const $archive = archiveRoot && archiveRoot.length ? archiveRoot : jquery_default()("#archive_ff").first(); 23216 jquery_default().ajax({ 23217 url: sfrJSVars.ajaxurl, 23218 method: "POST", 23219 data: { 23220 action: "reloadForfaitVue", 23221 params: params 23222 }, 23223 success: function (data) { 23224 $archive.find(".forfait_list .forfaits_blocs").html(data).append('<div class="loader"></div>').removeClass("loading"); 23225 jquery_default()(".forfaits_container").removeClass("busy"); 23226 new LazyLoad("lazy", 0); 23227 if (typeof initTooltips === "function") { 23228 initTooltips(); 23229 } 23230 initEngagementFilter(); 23231 const activeForfaitType = jquery_default()(".forfait_type_btn.active").data("forfait-type"); 23232 if (activeForfaitType) { 23233 updateForfaitTypeTitle(activeForfaitType); 23234 } 23235 }, 23236 error: function (request, error) { 23237 console.log(error); 23238 $archive.find(".forfait_list .forfaits_blocs").removeClass("loading"); 23239 jquery_default()(".forfaits_container").removeClass("busy"); 23240 } 23241 }); 23242 } 23243} 23244 23245/** 23246 * FOR CARROUSEL 23247 **/ 23248 23249function carrouselForfait() { 23250 //Initialisatation du carrousel des forfaits 23251 $("#archive_ff .forfait_list article").each(function () { 23252 $(this).data("scrolled", 0); 23253 $(this).find(">.container>ul").css({ 23254 transform: "translateX(0px)" 23255 }); 23256 $(this).find(">.container>ul .loader").css({ 23257 transform: "translateX(0px)" 23258 }); 23259 $(this).find(".arrows span span.prev").addClass("hide"); 23260 }); 23261 resetFFCarrousel(); 23262 onScrollCalculArrowForfaits(); 23263 $(window).resize(function () { 23264 resetFFCarrousel(); 23265 onScrollCalculArrowForfaits(); 23266 }); 23267 23268 //Action des clics sur les flèches 23269 $("#archive_ff .forfait_list article").each(function () { 23270 var $currentArticle = $(this);
23271 $currentArticle.find(".arrows span span").off("click"); 23272 $currentArticle.find(".arrows span span").on("click", function () { 23273 $currentArticle.find(".arrows span span").removeClass("hide"); 23274 var limit = 0; 23275 $currentArticle.find(">.container>ul:first-of-type>li").each(function () { 23276 limit += $currentArticle.find(">.container>ul:first-of-type>li").outerWidth(true); 23277 }); 23278 if ($(this).hasClass("next")) { 23279 $currentArticle.data("scrolled", $currentArticle.data("scrolled") + 1); 23280 } else { 23281 $currentArticle.data("scrolled", $currentArticle.data("scrolled") - 1); 23282 } 23283 var distance = 0; 23284 for (let i = 1; i <= $currentArticle.data("scrolled"); i++) { 23285 distance += $currentArticle.find(">.container>ul:first-of-type>li:nth-child(" + i + ")").outerWidth(true); 23286 } 23287 $currentArticle.find(">.container>ul").css({ 23288 transform: "translateX(-" + distance + "px)" 23289 }); 23290 $currentArticle.find(">.container>ul .loader").css({ 23291 transform: "translateX(" + distance + "px)" 23292 }); 23293 if (distance + $currentArticle.innerWidth() > limit) { 23294 $currentArticle.find(".arrows span span.next").addClass("hide"); 23295 } 23296 if ($currentArticle.data("scrolled") <= 0) { 23297 $currentArticle.find(".arrows span span.prev").addClass("hide"); 23298 } 23299 }); 23300 }); 23301} 23302function resetFFCarrousel() { 23303 $("#archive_ff .forfait_list article").each(function () { 23304 var limit = 0; 23305 $(this).find(">.container>ul:first-of-type>li").each(function () { 23306 limit += $(this).outerWidth(true); 23307 }); 23308 if ($(this).innerWidth() < limit) { 23309 if ($(this).data("scrolled") == 0) { 23310 $(this).find(".arrows span span.next").removeClass("hide"); 23311 $(this).find(">.container ul").addClass("carr-ready"); 23312 } 23313 } else { 23314 $(this).find(">.container ul").removeClass("carr-ready"); 23315 $(this).find(".arrows span span.next").addClass("hide"); 23316 } 23317 }); 23318} 23319function onScrollCalculArrowForfaits() { 23320 if ($("#archive_ff").length > 0) { 23321 $(".forfait_list .wrapper article").each(function () { 23322 var $forfaitList = $(this), 23323 $forfaitListSpecialOffer = $forfaitList.find(".container .advantages > li > span"), 23324 arrowsTop = parseInt($forfaitList.find(".arrows").offset().top), 23325 forfaitListSpecialOfferHighest = 0; // Hauteur du header 23326 23327 $forfaitListSpecialOffer.each(function (index, element) { 23328 forfaitListSpecialOfferHighest = $(element).outerHeight(true) > forfaitListSpecialOfferHighest ? $(element).outerHeight(true) : forfaitListSpecialOfferHighest; 23329 }); 23330 onScrollMoveForfaits(arrowsTop, $forfaitList, forfaitListSpecialOfferHighest); 23331 $(document).on("scroll", function () { 23332 onScrollMoveForfaits(arrowsTop, $forfaitList, forfaitListSpecialOfferHighest); 23333 }); 23334 }); 23335 } 23336} 23337function onScrollMoveForfaits(arrowsTop, $forfaitList, forfaitListSpecialOfferHighest) { 23338 var someHeightToAdd = parseInt($("body > #heading").height() + forfaitListSpecialOfferHighest / 2), 23339 forfaitListBottom = parseInt($forfaitList.offset().top + $forfaitList.find(".container").outerHeight(true)) + parseFloat($forfaitList.find(".container").css("margin-top")) + parseFloat($forfaitList.find(".container").css("padding-top")), 23340 arrowsTranslate = parseInt($(document).scrollTop()) - (arrowsTop - someHeightToAdd), 23341 newArrowsTop = arrowsTop + arrowsTranslate, 23342 arrowsBottom = parseInt(newArrowsTop + $forfaitList.find(".arrows").height()); 23343 if (arrowsTop - someHeightToAdd < $(document).scrollTop() && forfaitListBottom > arrowsBottom) { 23344 $forfaitList.find(".arrows").animate({ 23345 top: arrowsTranslate 23346 }, 0); 23347 } 23348} 23349let skipPlanAddPhonePopin = false; 23350let planAddPhonePendingBtn = null; 23351function closePlanAddPhonePopin() { 23352 jquery_default()(".plan-add-phone-popin").remove(); 23353 jquery_default()("body").removeClass("stop_scrolling"); 23354 planAddPhonePendingBtn = null; 23355 window.planAddPhonePendingBtn = null; 23356} 23357function openPlanAddPhonePopin($sourceBtn) { 23358 const $popinContent = jquery_default()("#plan-add-phone-popin"); 23359 if ($popinContent.length === 0) { 23360 return false;
23361 } 23362 planAddPhonePendingBtn = $sourceBtn; 23363 window.planAddPhonePendingBtn = $sourceBtn.get(0); 23364 jquery_default()($popinContent.html()).insertAfter(".footer"); 23365 jquery_default()("body").addClass("stop_scrolling"); 23366 jquery_default()(document).on("click.planAddPhonePopin", ".plan-add-phone-popin .close", function () { 23367 closePlanAddPhonePopin(); 23368 }); 23369 return true; 23370} 23371function initPlanAddPhonePopin() { 23372 jquery_default()(document).on("click", "#archive_ff[data-posttype='sfr_forfaits_phone'] .dynamic-formula-btn.nophone:not(.popin_action), #archive_ff[data-posttype='sfr_forfaits_tab'] .dynamic-formula-btn.nophone:not(.popin_action)", function (event) { 23373 if (skipPlanAddPhonePopin || !jquery_default()(this).is("button")) { 23374 return; 23375 } 23376 const { 23377 planName, 23378 planPrice 23379 } = planTracking.getPlanFromElement(jquery_default()(this)); 23380 if (planName) { 23381 planTracking.persistPlan(planName, planPrice); 23382 } 23383 if (!openPlanAddPhonePopin(jquery_default()(this))) { 23384 return; 23385 } 23386 event.preventDefault(); 23387 event.stopImmediatePropagation(); 23388 }); 23389 jquery_default()(document).on("click", "[data-plan-tracking=\"modal_continue_without_phone\"]", function () { 23390 if (!planAddPhonePendingBtn) { 23391 return; 23392 } 23393 const $pendingBtn = planAddPhonePendingBtn; 23394 closePlanAddPhonePopin(); 23395 window.planTrackingSkipSelectPlan = true; 23396 skipPlanAddPhonePopin = true; 23397 $pendingBtn.trigger("click"); 23398 skipPlanAddPhonePopin = false; 23399 }); 23400 jquery_default()(document).on("click", "[data-plan-tracking=\"modal_continue_with_phone\"]", function () { 23401 closePlanAddPhonePopin(); 23402 const $phoneBtnWith = jquery_default()("#archive_ff .phone_btn_with").first(); 23403 if ($phoneBtnWith.length && !$phoneBtnWith.hasClass("active")) { 23404 $phoneBtnWith.trigger("click"); 23405 } 23406 }); 23407} 23408;// ./wp-content/themes/sfrtheme/assets/js/pagePhone.js 23409 23410jquery_default()(document).ready(function () { 23411 phonePageEventListener(); 23412}); 23413function phonePageEventListener() { 23414 jquery_default()("#single-phone #phone .phone-description .informations .with_ff .phoneandforfait").click(function (e) { 23415 const link = jquery_default()(this).data('href'); 23416 jquery_default().ajax({ 23417 url: sfrJSVars.ajaxurl, 23418 method: 'POST', 23419 data: { 23420 'action': 'ajaxToggleAddPhoneToForfait', 23421 'params': { 23422 displayPhone: true 23423 } 23424 }, 23425 success: function (data) { 23426 document.location.href = link; 23427 }, 23428 error: function (request, error) { 23429 console.log(error); 23430 } 23431 }); 23432 }); 23433} 23434// EXTERNAL MODULE: ./wp-content/themes/sfrtheme/assets/js/polyfills.js 23435var polyfills = __webpack_require__(58); 23436;// ./wp-content/themes/sfrtheme/assets/js/utils/utils.js 23437const getPositionRelativeToDocument = ({ 23438 el, 23439 parent = null, 23440 float = true 23441}) => { 23442 const box = el.getBoundingClientRect(); 23443 let boxParent = {}; 23444 if (parent) { 23445 boxParent = parent.getBoundingClientRect(); 23446 } 23447 const body = document.body; 23448 const docEl = document.documentElement; 23449 const scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop; 23450 const scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft; 23451 const clientTop = boxParent.top || docEl.clientTop || body.clientTop || 0; 23452 const clientLeft = boxParent.left || docEl.clientLeft || body.clientLeft || 0; 23453 let top = box.top + scrollTop - clientTop; 23454 let left = box.left + scrollLeft - clientLeft; 23455 if (!float) { 23456 left = wrap(left, 0, window.outerWidth); 23457 top = wrap(top, 0, window.outerHeight); 23458 } 23459 return { 23460 top, 23461 left 23462 }; 23463}; 23464const wrap = (num, min, max) => { 23465 return ((num - min) % (max - min) + (max - min)) % (max - min) + min; 23466}; 23467;// ./wp-content/themes/sfrtheme/assets/js/Tooltip.js 23468/** 23469 * Permet d'afficher des Tooltips 23470 */ 23471 23472 23473class Tooltip { 23474 constructor(element) { 23475 this.element = element; 23476 this.content = element.querySelector('.tooltip-content'); 23477 this.isShowed = false; 23478 this.horizontalSpacing = null; 23479 this.classNames = { 23480 show: 'show' 23481 }; 23482 this.setListeners(); 23483 } 23484 23485 /** 23486 * Permet de définir les events listeners 23487 */ 23488 setListeners() { 23489 const { 23490 element 23491 } = this; 23492 element.addEventListener('mouseenter', () => { 23493 this.onMouseEnter(); 23494 }); 23495 element.addEventListener('mouseleave', () => { 23496 this.onMouseLeave(); 23497 }); 23498 this.setPosition(); 23499 window.addEventListener('resize', () => { 23500 // Obligé de mettre un setTimeout, car on doit attendre le replacement du carrousel pour ne pas avoir 23501 // une position décalée 23502 setTimeout(() => { 23503 this.setPosition(); 23504 }, 500); 23505 }); 23506 } 23507 23508 /** 23509 * Lorsque la souris entre dans l'élément 23510 */ 23511 onMouseEnter() { 23512 this.show(); 23513 } 23514 23515 /** 23516 * Lorsque la souris sort de l'élément 23517 */ 23518 onMouseLeave() { 23519 this.hide(); 23520 } 23521 23522 /** 23523 * Permet de récupérer la position du contenu 23524 */ 23525 setPosition() { 23526 const { 23527 element, 23528 content 23529 } = this; 23530 const rec = element.getBoundingClientRect(); 23531 // On récupère la position de l'élément dans la fenêtre 23532 const positionRelative = getPositionRelativeToDocument({ 23533 el: element, 23534 float: false 23535 }); 23536 // On vérifie la place libre 23537 const spacing = positionRelative.left + rec.width; 23538 // Si il n'y a pas suffisamment de place libre 23539 if (content.scrollWidth >= spacing) { 23540 // On ajoute de l'espace 23541 this.horizontalSpacing = content.scrollWidth - spacing + 5; 23542 } else { 23543 this.horizontalSpacing = null; 23544 } 23545 } 23546 23547 /** 23548 * Permet d'afficher l'élément 23549 */ 23550 show() { 23551 const { 23552 classNames, 23553 content, 23554 horizontalSpacing, 23555 element 23556 } = this;
23557 this.isShowed = true; 23558 content.style.right = horizontalSpacing ? `-${horizontalSpacing}px` : 0; 23559 element.classList.add(classNames.show); 23560 } 23561 23562 /** 23563 * Permet de cacher l'élément 23564 */ 23565 hide() { 23566 const { 23567 classNames, 23568 element 23569 } = this; 23570 this.isShowed = false; 23571 element.classList.remove(classNames.show); 23572 } 23573} 23574;// ./wp-content/themes/sfrtheme/assets/js/datalayer/GtmDatalayer.js 23575 23576let GtmDatalayer_self; 23577class GtmDatalayer { 23578 constructor() { 23579 GtmDatalayer_self = this; // this.pushEvent ne fonctionne pas... 23580 } 23581 23582 /** 23583 * Si on est en development, on voit un console log, sinon on envoie au GTM 23584 * @param {String} e - L'event 23585 * @param {String} c - La catégorie 23586 * @param {String} a - L'action 23587 * @param {String} l - Le label 23588 * @param {Object} v - Variables custom 23589 */ 23590 send(event, type, click, click_placement, v = {}) { 23591 const params = { 23592 'event': event, 23593 'type': type, 23594 'click': click, 23595 'click_placement': click_placement, 23596 ...v 23597 }; 23598 if (typeof dataLayer !== 'undefined') { 23599 dataLayer.push(params); 23600 } 23601 } 23602 23603 /** 23604 * Au clic sur les éléments fournis en paramètres 23605 * @param elements - Texte du lien 23606 */ 23607 handleClicks(elements, type = "navigation", event = "click", placement = "body") { 23608 elements.forEach(element => { 23609 const { 23610 selector, 23611 text, 23612 textSelector 23613 } = element; 23614 const e = element.event ? element.event : event; 23615 const t = element.type ? element.type : type; 23616 const p = element.placement ? element.placement : placement; 23617 const v = element.v ? element.v : {}; 23618 $(document).on('click', selector, function () { 23619 GtmDatalayer_self.pushEvent($(this), text, textSelector, e, t, p, v); 23620 }); 23621 }); 23622 } 23623 23624 /** 23625 * Au clic sur les éléments fournis en paramètres 23626 * @param elements - Texte du lien 23627 */ 23628 pushEvent(el, text, textSelector, event, type, placement, v = {}) { 23629 let request = textSelector == 'element' ? el.text() : el.find(textSelector).text(); 23630 if (text) { 23631 request = text; 23632 } 23633 this.send(event, type, request, placement, v); 23634 } 23635} 23636/* harmony default export */ const datalayer_GtmDatalayer = (GtmDatalayer); 23637;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/ContactEvents.js 23638 23639const gtmDatalayer = new datalayer_GtmDatalayer(); 23640 23641const ContactEvents_elements = [{ 23642 selector: ".page-template-formEligibility form button", 23643 textSelector: "element" 23644}]; 23645const ContactEvents = () => { 23646 const { 23647 handleClicks 23648 } = gtmDatalayer; 23649 handleClicks(ContactEvents_elements); 23650}; 23651jquery_default()(document).on('click', ".bloc_full_page .btn", function () { 23652 const href = jquery_default()(this).attr('href'); 23653 const { 23654 hostname 23655 } = new URL(href); 23656 const trackButtons = [{ 23657 'domain': 'wa.me', 23658 'click': 'nous_contacter_whatsapp' 23659 }, { 23660 'domain': 'm.me', 23661 'click': 'nous_contacter_facebook' 23662 }]; 23663 const button = trackButtons.find(b => b.domain == hostname); 23664 if (button) { 23665 gtmDatalayer.send('click', 'navigation', button.click, 'body'); 23666 } 23667}); 23668/* harmony default export */ const tracking_ContactEvents = (ContactEvents); 23669;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/EligibiliteEvents.js 23670 23671const EligibiliteEvents_gtmDatalayer = new datalayer_GtmDatalayer(); 23672const EligibiliteEvents_elements = [{ 23673 selector: ".page-template-eligibility .searchform button", 23674 text: "recherche_adresse" 23675}]; 23676const EligibiliteEvents = () => { 23677 const { 23678 handleClicks 23679 } = EligibiliteEvents_gtmDatalayer; 23680 handleClicks(EligibiliteEvents_elements); 23681}; 23682/* harmony default export */ const tracking_EligibiliteEvents = (EligibiliteEvents); 23683;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/FooterEvents.js 23684 23685const FooterEvents_gtmDatalayer = new datalayer_GtmDatalayer(); 23686const FooterEvents_elements = [{ 23687 selector: "#line-footer li a", 23688 textSelector: "element", 23689 placement: "footer" 23690}]; 23691const FooterEvents = () => { 23692 const { 23693 handleClicks 23694 } = FooterEvents_gtmDatalayer; 23695 handleClicks(FooterEvents_elements); 23696}; 23697/* harmony default export */ const tracking_FooterEvents = (FooterEvents); 23698;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/ForfaitMobileEvents.js 23699 23700const ForfaitMobileEvents_gtmDatalayer = new datalayer_GtmDatalayer(); 23701 23702const ForfaitMobileEvents_elements = [{ 23703 selector: ".page-template-complement form button", 23704 textSelector: "element" 23705}]; 23706const ForfaitMobileEvents = () => { 23707 const { 23708 handleClicks 23709 } = ForfaitMobileEvents_gtmDatalayer; 23710 handleClicks(ForfaitMobileEvents_elements); 23711}; 23712const getProductName = $element => { 23713 const $card = $element.closest(".forfait, li"); 23714 return $card.find(".title-price .title").first().text().trim() || $card.find("h2 span").first().text().trim(); 23715}; 23716jquery_default()('.post-type-archive-sfr_forfaits_phone .forfaits_container .advantages > li').each(function () { 23717 const title = jquery_default()(this).find("h2 span").text(); 23718 jquery_default()(this).on('click', ".prices li .btn", function () { 23719 ForfaitMobileEvents_gtmDatalayer.send('click', 'navigation', title, 'body', { 23720 'achat_telephone': jquery_default()('.phone_block .phone').hasClass('active') ? 'acheter' : 'ne_pas_acheter', 23721 'choix_numero': jquery_default()('.phone_block .portabilite').hasClass('active') ? 'conserver' : 'ne_pas_conserver' 23722 }); 23723 }); 23724}); 23725jquery_default()(document).on('click', ".post-type-archive-sfr_forfaits_phone .forfaits_container .sfr_family li .btn", function () { 23726 ForfaitMobileEvents_gtmDatalayer.send('click', 'navigation', 'sfr_family', 'body', { 23727 'choix_techno': jquery_default()('.forfait_list .filters form ul li input:checked + label').text(), 23728 'choix_numero': jquery_default()('.phone_block .portabilite').hasClass('active') ? 'conserver' : 'ne_pas_conserver', 23729 'achat_telephone': jquery_default()('.phone_block .phone').hasClass('active') ? 'acheter' : 'ne_pas_acheter' 23730 }); 23731}); 23732jquery_default()(document).on("click", ".post-type-archive-sfr_forfaits_phone .forfaits_container .actions .dynamic-formula-btn, .post-type-archive-sfr_forfaits_phone .forfaits_container .actions .btn.primary.red", function () { 23733 const productName = getProductName(jquery_default()(this)); 23734 ForfaitMobileEvents_gtmDatalayer.send("click", "navigation", "choisir_ce_forfait", "body", { 23735 produit: productName, 23736 choix_numero: jquery_default()(".phone_block .portabilite").hasClass("active") ? "conserver" : "ne_pas_conserver", 23737 achat_telephone: jquery_default()(".phone_block .phone").hasClass("active") ? "acheter" : "ne_pas_acheter" 23738 }); 23739}); 23740jquery_default()(document).on("click", ".post-type-archive-sfr_forfaits_phone .forfaits_container .actions .accordion .title", function () { 23741 const productName = getProductName(jquery_default()(this)); 23742 ForfaitMobileEvents_gtmDatalayer.send("click", "navigation", "voir_le_detail_de_l_offre", "body", { 23743 produit: productName, 23744 choix_numero: jquery_default()(".phone_block .portabilite").hasClass("active") ? "conserver" : "ne_pas_conserver", 23745 achat_telephone: jquery_default()(".phone_block .phone").hasClass("active") ? "acheter" : "ne_pas_acheter" 23746 }); 23747}); 23748/* harmony default export */ const tracking_ForfaitMobileEvents = (ForfaitMobileEvents); 23749;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/HomeEvents.js 23750 23751const HomeEvents_gtmDatalayer = new datalayer_GtmDatalayer(); 23752 23753const HomeEvents_elements = [{ 23754 selector: "#home .short_link a", 23755 textSelector: "p" 23756}, { 23757 selector: ".slide-v2 a", 23758 textSelector: "element" 23759}, { 23760 selector: ".slide a", 23761 textSelector: "element" 23762}, { 23763 selector: "#home .wysiwyg_content a", 23764 textSelector: "element" 23765}]; 23766const HomeEvents = () => { 23767 const { 23768 handleClicks 23769 } = HomeEvents_gtmDatalayer; 23770 handleClicks(HomeEvents_elements); 23771}; 23772const HomeEvents_getProductName = $element => { 23773 const $card = $element.closest(".forfait, li"); 23774 return $card.find(".title-price .title").first().text().trim() || $card.find("h2 span").first().text().trim(); 23775}; 23776jquery_default()(document).on("click", ".forfaits_container .actions .dynamic-formula-btn, .forfaits_container .actions .btn.primary.red", function () { 23777 if (jquery_default()("body").hasClass("post-type-archive-sfr_forfaits_phone")) { 23778 return; 23779 } 23780 const productName = HomeEvents_getProductName(jquery_default()(this)); 23781 HomeEvents_gtmDatalayer.send("click", "navigation", "choisir_ce_forfait", "body", { 23782 produit: productName 23783 }); 23784}); 23785jquery_default()(document).on("click", ".forfaits_container .actions .accordion .title", function () { 23786 if (jquery_default()("body").hasClass("post-type-archive-sfr_forfaits_phone")) { 23787 return; 23788 } 23789 const productName = HomeEvents_getProductName(jquery_default()(this)); 23790 HomeEvents_gtmDatalayer.send("click", "navigation", "voir_le_detail_de_l_offre", "body", { 23791 produit: productName 23792 }); 23793}); 23794jquery_default()(document).on("click", ".forfaits_container .switchboxtv", function () { 23795 const productName = HomeEvents_getProductName(jquery_default()(this)); 23796 const clickLabel = jquery_default()(this).find(".text").first().text().trim() || jquery_default()(this).text().trim(); 23797 HomeEvents_gtmDatalayer.send("click", "navigation", clickLabel, "body", { 23798 produit: productName 23799 }); 23800}); 23801jquery_default()(document).on("click", ".modal-client .client-modal-buttons .client-modal-yes, .modal
23801-client .client-modal-buttons .client-modal-no", function () { 23802 const clickLabel = jquery_default()(this).text().trim(); 23803 const modalTitle = jquery_default()(this).closest(".client-modal-step").find("h5").first().text().trim(); 23804 HomeEvents_gtmDatalayer.send("click", "navigation", clickLabel, "body", { 23805 produit: modalTitle 23806 }); 23807}); 23808jquery_default()(document).on("click", ".forfaits_container .phone_toggle_buttons .phone_btn", function () { 23809 const clickLabel = jquery_default()(this).text().trim(); 23810 const blockTitle = jquery_default()(this).closest(".with-phone").find("h1, h2, h3, h4, h5").first().text().trim(); 23811 HomeEvents_gtmDatalayer.send("click", "navigation", clickLabel, "body", { 23812 produit: blockTitle 23813 }); 23814}); 23815jquery_default()(document).on("click", ".forfaits_container .forfait_type_buttons .forfait_type_btn", function () { 23816 const clickLabel = jquery_default()(this).text().trim(); 23817 const blockTitle = jquery_default()(this).closest(".forfait-type-filter").find(".forfait-type-title.active h5").first().text().trim() || jquery_default()(this).closest(".forfait-type-filter").find(".forfait-type-title h5").first().text().trim(); 23818 HomeEvents_gtmDatalayer.send("click", "navigation", clickLabel, "body", { 23819 produit: blockTitle 23820 }); 23821}); 23822jquery_default()(document).on("click", ".test-eligibility .searchform .btn.primary.button", function () { 23823 const clickLabel = jquery_default()(this).text().trim(); 23824 const blockTitle = jquery_default()(this).closest(".test-eligibility").find(".eligibility-step .content h1, .eligibility-step .content .h4").first().text().trim(); 23825 HomeEvents_gtmDatalayer.send("click", "navigation", clickLabel, "body", { 23826 produit: blockTitle 23827 }); 23828}); 23829/* harmony default export */ const tracking_HomeEvents = (HomeEvents); 23830;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/MenuEvents.js 23831 23832const MenuEvents_gtmDatalayer = new datalayer_GtmDatalayer(); 23833const MenuEvents_elements = [{ 23834 selector: "#header li a", 23835 textSelector: "element", 23836 placement: "header" 23837}]; 23838const MenuEvents = () => { 23839 const { 23840 handleClicks 23841 } = MenuEvents_gtmDatalayer; 23842 handleClicks(MenuEvents_elements); 23843}; 23844/* harmony default export */ const tracking_MenuEvents = (MenuEvents); 23845;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/OffreBoxEvents.js 23846 23847const OffreBoxEvents_gtmDatalayer = new datalayer_GtmDatalayer(); 23848 23849const OffreBoxEvents_elements = [{ 23850 selector: ".post-type-archive-sfr_forfaits_box .breadcrumbs .right a", 23851 textSelector: "element" 23852}, { 23853 selector: ".post-type-archive-sfr_forfaits_box #forfait_box_type ul li label", 23854 textSelector: "element" 23855}]; 23856const OffreBoxEvents = () => { 23857 const { 23858 handleClicks 23859 } = OffreBoxEvents_gtmDatalayer; 23860 handleClicks(OffreBoxEvents_elements); 23861}; 23862jquery_default()('.post-type-archive-sfr_forfaits_box .forfaits_container .advantages > li').each(function () { 23863 const title = jquery_default()(this).find("h2 span").text(); 23864 jquery_default()(this).on('click', ".prices li .btn", function () { 23865 OffreBoxEvents_gtmDatalayer.send('click', 'navigation', title, 'body', { 23866 'choix_techno': jquery_default()('.forfait_list .filters form ul li input:checked + label').text(), 23867 'choix_numero': jquery_default()('.phone_block .portabilite').hasClass('active') ? 'conserver' : 'ne_pas_conserver' 23868 }); 23869 }); 23870}); 23871jquery_default()(document).on('click', "#complement aside .btn_modif", function () { 23872 OffreBoxEvents_gtmDatalayer.send('click', 'navigation', 'modifier_mon_choix_adresse', 'body'); 23873}); 23874jquery_default()(document).on('click', "#complement section .btn_modif", function () { 23875 OffreBoxEvents_gtmDatalayer.send('click', 'navigation', 'modifier_mon_choix_forfait', 'body'); 23876}); 23877/* harmony default export */ const tracking_OffreBoxEvents = (OffreBoxEvents); 23878;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/TelephoneEvents.js 23879 23880const TelephoneEvents_gtmDatalayer = new datalayer_GtmDatalayer(); 23881 23882const TelephoneEvents_elements = [{ 23883 selector: ".single-sfr_phone .bottom .informations .btn", 23884 textSelector: "element" 23885}, { 23886 selector: ".page-template-recapitulatif .price .foot .btn", 23887 textSelector: "element" 23888}]; 23889const TelephoneEvents = () => { 23890 const { 23891 handleClicks 23892 } = TelephoneEvents_gtmDatalayer; 23893 handleClicks(TelephoneEvents_elements); 23894}; 23895jquery_default()(document).on('click', "#archive_phones .phones .cards li.phone a.btn.primary", function () { 23896 const $card = jquery_default()(this).closest("li.phone"); 23897 const productName = $card.find(".phone-title-container .title").first().text().trim(); 23898 TelephoneEvents_gtmDatalayer.send('click', 'navigation', jquery_default()(this).text().trim(), 'body', { 23899 'produit': productName 23900 }); 23901}); 23902jquery_default()(document).on('click', ".page-template-recapitulatif .cards-choices .card-choice:not(.box-tv) .buttons.yes-no .btn", function () { 23903 const $choiceCard = jquery_default()(this).closest(".card-choice"); 23904 const choiceTitle = $choiceCard.find("h2").first().text().trim(); 23905 TelephoneEvents_gtmDatalayer.send('click', 'navigation', jquery_default()(this).text().trim(), 'body', { 23906 'produit': choiceTitle 23907 }); 23908}); 23909/* harmony default export */ const tracking_TelephoneEvents = (TelephoneEvents); 23910;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/AdvantageEvents.js 23911 23912const AdvantageEvents_gtmDatalayer = new datalayer_GtmDatalayer(); 23913 23914const AdvantageEvents = () => {}; 23915jquery_default()('.container .advantages > li').each(function () { 23916 const title = jquery_default()(this).find("h2 span").text(); 23917 jquery_default()(this).on('click', ".accordion .title", function () { 23918 if (jquery_default()(this).closest("#home").length || jquery_default()("body").hasClass("home") || jquery_default()(this).closest("#archive_ff[data-posttype='sfr_forfaits_phone']").length || jquery_default()(this).closest("#archive_ff[data-posttype='sfr_forfaits_tab']").length || jquery_default()("body").hasClass("post-type-archive-sfr_forfaits_phone")) { 23919 return; 23920 } 23921 if (jquery_default()(this).hasClass('open')) { 23922 AdvantageEvents_gtmDatalayer.send('click', 'action', jquery_default()(this).text(), 'body', { 23923 'produit': title 23924 }); 23925 } 23926 }); 23927}); 23928/* harmony default export */ const tracking_AdvantageEvents = (AdvantageEvents); 23929;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/AddOnTracking.js 23930 23931const AddOnTracking = () => {}; 23932jquery_default()(".page-template-recapitulatif .price .foot .btn.print").click(function () { 23933 if (sfrJSVars.themeName == 'sfrtheme') { 23934 dataLayer.push({ 23935 event: "print", 23936 conversionId: sfrJSVars.datalayerConversionId, 23937 conversionLabel: "PuXrCKHf-L8ZEIzegpsD" 23938 }); 23939 } 23940}); 23941jquery_default()(".post-type-archive-sfr_forfaits_phone .forfaits_blocs .prices .btn.primary.red.eligibility_btn").click(function () { 23942 if (sfrJSVars.themeName == 'sfrtheme') { 23943 dataLayer.push({ 23944 event: "eligibility_test", 23945 conversionId: sfrJSVars.datalayerConversionId, 23946 conversionLabel: "VcgOCN6rkKUCEIzegpsD" 23947 }); 23948 } 23949}); 23950jquery_default()(".page-template-client .block_link.not_client .btn").click(function () { 23951 if (sfrJSVars.themeName == 'sfrtheme') { 23952 dataLayer.push({ 23953 event: "subscribe_plan_new_customer", 23954 conversionId: sfrJSVars.datalayerConversionId, 23955 conversionLabel: "hEH3CJPztqUCEIzegpsD" 23956 }); 23957 } 23958}); 23959jquery_default()(".single-sfr_phone .validate .btn.primary.phone_alone").click(function () { 23960 dataLayer.push({ 23961 event: "add_to_cart_only_phone", 23962 conversionId: sfrJSVars.datalayerConversionId, 23963 conversionLabel: sfrJSVars.themeName == 'sfrtheme' ? "8utlCICf_L8ZEIzegpsD" : "VcgOCN6rkKUCEIzegpsD" 23964 }); 23965}); 23966jquery_default()("#sur-footer .wrapper > ul > li:nth-of-type(2) a").click(function () { 23967 if (sfrJSVars.themeName == 'sfrtheme') { 23968 dataLayer.push({ 23969 event: "meet_in_store", 23970 conversionId: sfrJSVars.datalayerConversionId, 23971 conversionLabel: "EJqtCNeft6UCEIzegpsD" 23972 }); 23973 } 23974}); 23975jquery_default()('main#edito a[data-datalayer="meet_in_store"]').click(function () { 23976 if (sfrJSVars.themeName == 'sfrtheme') { 23977 dataLayer.push({ 23978 event: "meet_in_store", 23979 conversionId: sfrJSVars.datalayerConversionId, 23980 conversionLabel: "EJqtCNeft6UCEIzegpsD" 23981 }); 23982 } 23983}); 23984/* harmony default export */ const tracking_AddOnTracking = (AddOnTracking); 23985;// ./wp-content/themes/sfrtheme/assets/js/datalayer/tracking/PlanAdsEvents.js 23986 23987 23988const FORFAIT_SELECTOR = '#archive_ff[data-posttype="sfr_forfaits_phone"], #archive_ff[data-posttype="sfr_forfaits_tab"]'; 23989const getRecapPlan = () => { 23990 const $recap = jquery_default()('#recapitulatif'); 23991 if ($recap.length) { 23992 const planName = $recap.attr('data-plan-name') || ''; 23993 const planPrice = parseFloat($recap.attr('data-plan-price')); 23994 if (planName) { 23995 return { 23996 planName: String(planName).trim(), 23997 planPrice: Number.isNaN(planPrice) ? 0 : planPrice 23998 }; 23999 } 24000 } 24001 const stored = planTracking.loadPlan(); 24002 if (stored?.planName) { 24003 return stored; 24004 } 24005 return null; 24006}; 24007const initRecapPlanTracking = () => { 24008 const plan = getRecapPlan(); 24009 if (!plan?.planName) { 24010 return; 24011 } 24012 planTracking.persistPlan(plan.planName, plan.planPrice); 24013}; 24014const pushSelectPlan = $button => { 24015 if (window.planTrackingSkipSelectPlan) { 24016 window.planTrackingSkipSelectPlan = false;
24017 return; 24018 } 24019 const { 24020 planName, 24021 planPrice 24022 } = planTracking.getPlanFromElement($button); 24023 if (!planName) { 24024 return; 24025 } 24026 planTracking.pushPlanEvent('select_plan', planName, planPrice); 24027}; 24028const pushModalPlanEvent = eventName => { 24029 const pendingBtn = window.planAddPhonePendingBtn ? jquery_default()(window.planAddPhonePendingBtn) : null; 24030 const storedPlan = planTracking.loadPlan(); 24031 const plan = storedPlan?.planName ? storedPlan : pendingBtn ? planTracking.getPlanFromElement(pendingBtn) : null; 24032 if (!plan?.planName) { 24033 return; 24034 } 24035 planTracking.pushPlanEvent(eventName, plan.planName, plan.planPrice); 24036}; 24037const PlanAdsEvents = () => { 24038 initRecapPlanTracking(); 24039 jquery_default()(document).on('click', `${FORFAIT_SELECTOR} .actions .dynamic-formula-btn:not(.popin_action)`, function () { 24040 if (!jquery_default()(this).is('button, a')) { 24041 return; 24042 } 24043 pushSelectPlan(jquery_default()(this)); 24044 }); 24045 jquery_default()(document).on('click', `${FORFAIT_SELECTOR} .prices li .btn`, function () { 24046 pushSelectPlan(jquery_default()(this)); 24047 }); 24048 jquery_default()(document).on('click', '#recapitulatif .payment_flow_btn, #documents-modal .payment_flow_btn', function () { 24049 const plan = getRecapPlan(); 24050 if (!plan?.planName) { 24051 return; 24052 } 24053 planTracking.pushPlanEvent('plan_summary_validation', plan.planName, plan.planPrice); 24054 }); 24055 jquery_default()(document).on('click', '[data-plan-tracking="modal_continue_without_phone"]', function () { 24056 pushModalPlanEvent('modal_continue_without_phone'); 24057 }); 24058 jquery_default()(document).on('click', '[data-plan-tracking="modal_continue_with_phone"]', function () { 24059 pushModalPlanEvent('modal_continue_with_phone'); 24060 }); 24061}; 24062/* harmony default export */ const tracking_PlanAdsEvents = (PlanAdsEvents); 24063;// ./wp-content/themes/sfrtheme/assets/js/datalayer/Tracking.js 24064 24065 24066 24067 24068 24069 24070 24071 24072 24073 24074 24075const Tracking = () => { 24076 tracking_ContactEvents(); 24077 tracking_EligibiliteEvents(); 24078 tracking_FooterEvents(); 24079 tracking_ForfaitMobileEvents(); 24080 tracking_HomeEvents(); 24081 tracking_MenuEvents(); 24082 tracking_OffreBoxEvents(); 24083 tracking_TelephoneEvents(); 24084 tracking_AdvantageEvents(); 24085 tracking_PlanAdsEvents(); 24086 tracking_AddOnTracking(); 24087}; 24088/* harmony default export */ const datalayer_Tracking = (Tracking); 24089;// ./wp-content/themes/sfrtheme/assets/js/carrousel.js 24090if (navigator.userAgent.indexOf("Chrome") != -1 || navigator.userAgent.indexOf("Safari") != -1 || navigator.userAgent.indexOf("AppleWebKit") != -1) { 24091 var transitEndEv = "webkitTransitionEnd"; 24092} else { 24093 var transitEndEv = "transitionend"; 24094} 24095 24096//Gère les carrousels 24097const carrouselInit = Cookie => { 24098 if ($('html').hasClass('ie11')) { 24099 $('html').find('.carrousel_container').addClass('noloop'); 24100 $('.carrousel_container .carrousel .container .el_carr').each(function () { 24101 $(this).css({ 24102 'min-width': $(this).find('.slide').innerWidth() + 'px' 24103 }); 24104 }); 24105 } 24106 checkCarrouselSize(); 24107 $('html').find('.carrousel_container.is_sliding').each(function () { 24108 if (!$(this).hasClass('noloop')) { 24109 var carrousel = this, 24110 width = $(carrousel).find('.container .el_carr').innerWidth() * -1, 24111 limit = $(carrousel).find('.container .el_carr').length - 1, 24112 positions = [0, limit + 1], 24113 by = $(carrousel).data('by'), 24114 xStart = 0; 24115 $(carrousel).find('.container').addClass('container_0'); 24116 $(carrousel).find('.carrousel').append('<div class="container container_1" style="position:absolute; opacity:1; visibility:visible; z-index:-1; transform:translateX(' + positions[1] * width + 'px)">' + $(carrousel).find('.container').html() + '</div>'); 24117 $(carrousel).off('mousedown touchstart'); 24118 $(carrousel).on({ 24119 'mousedown touchstart': function (ev) { 24120 xStart = typeof ev.pageX === 'undefined' ? ev.originalEvent.changedTouches[0].pageX : ev.pageX; 24121 } 24122 }); 24123 $(carrousel).off('mouseup touchend'); 24124 $(carrousel).on({ 24125 'mouseup touchend': function (ev) { 24126 var pageX = typeof ev.pageX === 'undefined' ? ev.originalEvent.changedTouches[0].pageX : ev.pageX, 24127 // On check si on est en mobile ou en desktop 24128 deltaX = parseInt(pageX) - parseInt(xStart), 24129 // On regarde la différence de position entre le début du click et la fin du click 24130 opa = Math.abs(Math.abs(deltaX) / 100 + 0.2); // On fait un calcul permettant de savoir si on va à gauche ou à droite 24131 if (opa >= 1 && deltaX > 0.1) { 24132 carrouselGoPrev(carrousel, limit, positions, by); 24133 } else if (opa >= 1 && deltaX < 0.1) { 24134 carrouselGoNext(carrousel, limit, positions, by); 24135 } 24136 } 24137 }); 24138 $(this).parent().find('.prev').off('click'); 24139 $(this).parent().find('.prev').on('click', function () { 24140 carrouselGoPrev(carrousel, limit, positions, by); 24141 }); 24142 $(this).parent().find('.next').off('click'); 24143 $(this).parent().find('.next').on('click', function () { 24144 carrouselGoNext(carrousel, limit, positions, by); 24145 }); 24146 } else { 24147 var carrousel = this, 24148 position = [0], 24149 xStart = 0; 24150 $(carrousel).find('.prev').addClass('hide'); 24151 $(carrousel).off('mousedown touchstart'); 24152 $(carrousel).on({ 24153 'mousedown touchstart': function (ev) { 24154 xStart = typeof ev.pageX === 'undefined' ? ev.originalEvent.changedTouches[0].pageX : ev.pageX; 24155 } 24156 }); 24157 $(carrousel).off('mouseup touchend'); 24158 $(carrousel).on({ 24159 'mouseup touchend': function (ev) { 24160 var pageX = typeof ev.pageX === 'undefined' ? ev.originalEvent.changedTouches[0].pageX : ev.pageX, 24161 // On check si on est en mobile ou en desktop 24162 deltaX = parseInt(pageX) - parseInt(xStart), 24163 // On regarde la différence de position entre le début du click et la fin du click 24164 opa = Math.abs(Math.abs(deltaX) / 100 + 0.2); // On fait un calcul permettant de savoir si on va à gauche ou à droite 24165 if (opa >= 1 && deltaX > 0.1) { 24166 carrouselNoLoopGoPrev(carrousel, position); 24167 } else if (opa >= 1 && deltaX < 0.1) { 24168 carrouselNoLoopGoNext(carrousel, position); 24169 } 24170 } 24171 }); 24172 $(this).parent().find('.prev').off('click'); 24173 $(this).parent().find('.prev').on('click', function () { 24174 carrouselNoLoopGoPrev(carrousel, position); 24175 }); 24176 $(this).parent().find('.next').off('click'); 24177 $(this).parent().find('.next').on('click', function () { 24178 carrouselNoLoopGoNext(carrousel, position); 24179 }); 24180 } 24181 window.addEventListener('resize', () => { 24182 carrousel_onResize(carrousel, positions); 24183 }); 24184 }); 24185}; 24186/* harmony default export */ const carrousel = (carrouselInit); 24187function checkCarrouselSize() { 24188 $('html').find('.carrousel_container').each(function () { 24189 if (!$(this).hasClass('phone-images')) { 24190 if (!$(this).hasClass('is_sliding') && $(this).find('.carrousel .container').innerWidth() > $(this).innerWidth()) { 24191 $(this).addClass('is_sliding'); 24192 } else if ($(this).hasClass('is_sliding') && $(this).find('.carrousel .container').innerWidth() <= $(this).innerWidth()) { 24193 $(this).removeClass('is_sliding'); 24194 } 24195 } 24196 }); 24197} 24198function carrouselNoLoopGoNext(carrousel, position) { 24199 if (!$(carrousel).hasClass('busy')) { 24200 $(carrousel).addClass('busy'); 24201 let totalWidth = $(carrousel).find('.container').innerWidth(); 24202 let visible = $(carrousel).innerWidth(); 24203 let gap = 0; 24204 let moveBy = 0; 24205 for (let i = 0; i <= position[0]; i++) { 24206 if (i != position[0]) { 24207 gap += $(carrousel).find('.container .el_carr:nth-child(' + (i + 1) + ')').innerWidth(); 24208 } 24209 moveBy += $(carrousel).find('.container .el_carr:nth-child(' + (i + 1) + ')').innerWidth(); 24210 } 24211 if (totalWidth - gap > visible) { 24212 $(carrousel).find('.container').css({ 24213 'transform': 'translateX(' + moveBy * -1 + 'px)' 24214 }); 24215 position[0]++; 24216 $(carrousel).find('.container').one(transitEndEv, function () { 24217 if ($('html').hasClass('ie11')) { 24218 totalWidth = totalWidth - moveBy / visible * 15; 24219 } 24220 if (totalWidth - moveBy < visible) { 24221 $(carrousel).find('.next').addClass('hide'); 24222 } 24223 if (position[0] > 0) { 24224 $(carrousel).find('.prev').removeClass('hide'); 24225 } 24226 $(carrousel).removeClass('busy'); 24227 }); 24228 } else { 24229 $(carrousel).removeClass('busy'); 24230 } 24231 } 24232} 24233function carrouselNoLoopGoPrev(carrousel, position) { 24234 if (!$(carrousel).hasClass('busy')) { 24235 $(carrousel).addClass('busy'); 24236 var width = $(carrousel).find('.container .el_carr').innerWidth() * -1, 24237 limit = ($(carrousel).find('.container').innerWidth() - $(carrousel).innerWidth()) * -1; 24238 if (position[0] > 0) { 24239 position[0]--; 24240 $(carrousel).find('.container').css({ 24241 'transform': 'translateX(' + position[0] * width + 'px)' 24242 }); 24243 $(carrousel).find('.container').one(transitEndEv, function () { 24244 if (position[0] * width > limit) { 24245 $(carrousel).find('.next').removeClass('hide'); 24246 } 24247 if (position[0] <= 0) { 24248 $(carrousel).find('.prev').addClass('hide'); 24249 } 24250 $(carrousel).find('.container').css({ 24251 'z-index': '1', 24252 'opacity': '1' 24253 }); 24254 $(carrousel).removeClass('busy'); 24255 }); 24256 } else { 24257 $(carrousel).removeClass('busy'); 24258 } 24259 } 24260} 24261function carrouselGoPrev(carrousel, limit, positions, by) { 24262 if (!$(carrousel).hasClass('busy')) { 24263 $(carrousel).addClass('busy'); 24264 var width = $(carrousel).find('.container .el_carr').innerWidth() * -1; 24265 positions[0]--; 24266 positions[1]--; 24267 if (positions[0] < -by) { 24268 $(carrousel).find('.container_0').css({ 24269 'z-index': '-1', 24270 'opacity': '0' 24271 }); 24272 positions[0] = limit + positions[1] + 1; 24273 } 24274 if (positions[1] < -by) { 24275 $(carrousel).find('.container_1').css({ 24276 'z-index': '-1', 24277 'opacity': '0' 24278 }); 24279 positions[1] = limit + positions[0] + 1; 24280 } 24281 $(carrousel).find('.container_0').css({ 24282 'transform': 'translateX(' + positions[0] * width + 'px)' 24283 }); 24284 $(carrousel).find('.container_1').css({ 24285 'transform': 'translateX(' + positions[1] * width + 'px)' 24286 }); 24287 $(carrousel).find('.container_0').one(transitEndEv, function () { 24288 $(carrousel).find('.container_0').css({ 24289 'z-index': '1', 24290 'opacity': '1' 24291 }); 24292 $(carrousel).removeClass('busy'); 24293 }); 24294 $(carrousel).find('.container_1').one(transitEndEv, function () { 24295 $(carrousel).find('.container_1').css({ 24296 'z-index': '1', 24297 'opacity': '1' 24298 }); 24299 $(carrousel).removeClass('busy'); 24300 }); 24301 } 24302} 24303function carrouselGoNext(carrousel, limit, positions) { 24304 if (!$(carrousel).hasClass('busy')) { 24305 $(carrousel).addClass('busy'); 24306 var width = $(carrousel).find('.container .el_carr').innerWidth() * -1; 24307 positions[0]++; 24308 positions[1]++; 24309 if (positions[0] > limit + 1) { 24310 $(carrousel).find('.container_0').css({ 24311 'z-index': '-1', 24312 'opacity': '0' 24313 }); 24314 positions[0] = -(limit - positions[1] + 1); 24315 } 24316 if (positions[1] > limit + 1) { 24317 $(carrousel).find('.container_1').css({ 24318 'z-index': '-1', 24319 'opacity': '0' 24320 }); 24321 positions[1] = -(limit - positions[0] + 1); 24322 } 24323 $(carrousel).find('.container_0').css({ 24324 'transform': 'translateX(' + positions[0] * width + 'px)' 24325 }); 24326 $(carrousel).find('.container_1').css({ 24327 'transform': 'translateX(' + positions[1] * width + 'px)' 24328 }); 24329 $(carrousel).find('.container_0').one(transitEndEv, function () { 24330 $(carrousel).find('.container_0').css({ 24331 'z-index': '1', 24332 'opacity': '1' 24333 }); 24334 $(carrousel).removeClass('busy'); 24335 }); 24336 $(carrousel).find('.container_1').one(transitEndEv, function () { 24337 $(carrousel).find('.container_1').css({ 24338 'z-index': '1', 24339 'opacity': '1' 24340 }); 24341 $(carrousel).removeClass('busy'); 24342 }); 24343 } 24344} 24345function carrousel_onResize(carrousel, positions) { 24346 carrousel.classList.add('no-transition'); 24347 var width = $(carrousel).find('.container .el_carr').innerWidth() * -1; 24348 $(carrousel).find('.container_0').css({ 24349 'transform': 'translateX(' + positions[0] * width + 'px)' 24350 }); 24351 $(carrousel).find('.container_1').css({ 24352 'transform': 'translateX(' + positions[1] * width + 'px)' 24353 }); 24354 carrousel.classList.remove('no-transition'); 24355} 24356;// ./wp-content/themes/sfrtheme/assets/js/cookies.js 24357const Cookie = { 24358 read: function (name) { 24359 var data, 24360 result = "null"; 24361 var cookie = document.cookie.split("; "); 24362 for (const i in cookie) { 24363 data = cookie[i].split("="); 24364 if (name == data[0]) { 24365 result = data[1]; 24366 break; 24367 } 24368 } 24369 return result; 24370 }, 24371 write: function (name, value, days) { 24372 var cookie; 24373 if (days == null) { 24374 cookie = name + "=" + value + "; domain=" + location.hostname.split('.').reverse()[1] + "." + location.hostname.split('.').reverse()[0] + ";" + sfrJSVars.cookiesConfig; 24375 } else { 24376 var date = new Date().getTime() + 1000 * 3600 * 24 * days; 24377 var expires = new Date(date).toUTCString(); 24378 cookie = name + "=" + value + "; expires=" + expires + "; domain=" + location.hostname.split('.').reverse()[1] + "." + location.hostname.split('.').reverse()[0] + ";" + sfrJSVars.cookiesConfig; 24379 } 24380 document.cookie = cookie; 24381 } 24382}; 24383/* harmony default export */ const cookies = (Cookie); 24384;// ./wp-content/themes/sfrtheme/assets/js/webCallback.js 24385function webCallback() { 24386 let scrollY = 0; 24387 $('.webcallback').click(function () { 24388 //document.body.style.position = 'fixed'; 24389 openPopin(); 24390 }); 24391 function openPopin() { 24392 $('.webcallback').after(`<div class="popwebcallback"><div><iframe class="" src="${webCallbackVars.popinUrl}"></iframe><div class="close"></div></<div></div>`); 24393 disableScroll(); 24394 addCloseEvents(); 24395 } 24396 function disableScroll() { 24397 $("body").addClass('stop_listening'); 24398 scrollY = window.scrollY; 24399 document.body.style.top = `-${scrollY}px`;
24400 document.body.style.position = 'fixed'; 24401 } 24402 function enableScroll() { 24403 console.log(scrollY); 24404 document.body.style.position = ''; 24405 document.body.style.top = ''; 24406 window.scrollTo(0, scrollY); 24407 $("body").removeClass('stop_listening'); 24408 } 24409 function addCloseEvents() { 24410 document.addEventListener('keydown', e => { 24411 if (e.key === "Escape") { 24412 closePopin(); 24413 } 24414 }); 24415 $('.popwebcallback').click(function () { 24416 closePopin(); 24417 }); 24418 } 24419 function closePopin() { 24420 $('.popwebcallback').remove(); 24421 enableScroll(); 24422 } 24423} 24424;// ./wp-content/themes/sfrtheme/assets/js/localePopin.js 24425/** 24426 * Locale Popin JavaScript 24427 * Loads the locale selection popup via AJAX and displays it after page load 24428 */ 24429 24430/** 24431 * Load the popin content via AJAX 24432 * @returns {Promise} jQuery AJAX promise 24433 */ 24434function loadLocalePopinContent() { 24435 return $.ajax({ 24436 url: window.sfrJSVars.ajaxurl, 24437 type: "POST", 24438 dataType: "json", 24439 data: { 24440 action: "get_locale_popin", 24441 nonce: window.sfrJSVars.localePopin.nonce 24442 } 24443 }).always(function () { 24444 // Enlever la classe page-loading pour afficher la page 24445 $("html").removeClass("page-loading"); 24446 }); 24447} 24448 24449/** 24450 * Create the popin container if it doesn't exist 24451 * @returns {jQuery} The popin container jQuery element 24452 */ 24453function createPopinContainer() { 24454 if ($("#locale-popin-container").length === 0) { 24455 $("body").append('<div id="locale-popin-container" style="display:none;"></div>'); 24456 } 24457 return $("#locale-popin-container"); 24458} 24459 24460/** 24461 * Display the popin with animation 24462 * @param {jQuery} $container - The container element 24463 * @param {string} html - The HTML content to display 24464 */ 24465function displayPopin($container, html) { 24466 // Add the HTML to the container 24467 $container.html(html); 24468 24469 // Apply styles for fullscreen overlay 24470 $container.css({ 24471 position: "fixed", 24472 top: "0", 24473 left: "0", 24474 width: "100%", 24475 height: "100%", 24476 "background-color": "rgba(0, 0, 0, 0.8)", 24477 "z-index": "9999", 24478 display: "flex", 24479 "justify-content": "center", 24480 "align-items": "center", 24481 opacity: "0", 24482 transition: "opacity 0.3s ease-in-out" 24483 }); 24484 24485 // Show the container with fade-in effect 24486 $container.show().css("opacity", "1"); 24487 24488 // Make sure the body doesn't scroll while popin is open 24489 $("body").css("overflow", "hidden"); 24490 24491 // Ajouter les gestionnaires d'événements pour les boutons de sélection de locale 24492 $container.find(".locale-select-btn").on("click", function () { 24493 var locale = $(this).data("locale"); 24494 setLocaleAndReload(locale); 24495 }); 24496} 24497 24498/** 24499 * Initialize the locale popin functionality 24500 */ 24501/** 24502 * Set the locale cookie and reload the page 24503 * @param {string} locale - The locale to set (mtq, gpe, guy) 24504 */ 24505function setLocaleAndReload(locale) { 24506 // Définir le cookie avec une durée de vie d'un an 24507 var expiryDate = new Date(); 24508 expiryDate.setTime(expiryDate.getTime() + 365 * 24 * 60 * 60 * 1000); 24509 document.cookie = "locale=" + locale + "; expires=" + expiryDate.toUTCString() + "; path=/"; 24510 24511 // Recharger la page courante 24512 window.location.reload(); 24513} 24514function initLocalePopin() { 24515 // Only proceed if the localePopin data is available in sfrJSVars 24516 if (typeof window.sfrJSVars === "undefined") { 24517 return; 24518 } 24519 if (typeof window.sfrJSVars.localePopin === "undefined") { 24520 return; 24521 } 24522 if (!window.sfrJSVars.localePopin.enabled) { 24523 return; 24524 } 24525 var $container = createPopinContainer(); 24526 console.log("hello"); 24527 loadLocalePopinContent().done(function (response) { 24528 if (response.success && response.data.html) { 24529 displayPopin($container, response.data.html); 24530 } 24531 }).fail(function (xhr) { 24532 console.error("Failed to load locale popin:", xhr); 24533 }); 24534} 24535;// ./wp-content/themes/sfrtheme/assets/js/functions.js 24536__webpack_require__(127); 24537 24538 24539 24540 24541 24542 24543/* OLD ELIGIBILITY */ 24544 24545 24546 24547 24548 24549 24550 24551 24552 24553 24554 24555 24556 24557window.jQuery = (jquery_default()); 24558window.$ = (jquery_default()); 24559const appVersion = true ? "1.0.0" : 0; 24560const buildTime = true ? "2026-09-02T09:33:42.948Z" : 0; 24561console.log(`%cSFR Caraïbe â build v${appVersion} (${buildTime})`, "color:#e30a0a;font-weight:bold;"); 24562 24563/* END OLD ELIGIBILITY */ 24564 24565var loadAnalytics = false;
24566if (cookies.read("cookieconsent_status") == "null") { 24567 loadAnalytics = true; 24568} 24569/* Au chargement de la page */ 24570$(document).ready(function () { 24571 $("html").removeClass("page-loading"); 24572 selectCountryLocation(); 24573 footerSubMenuSlide(); 24574 allDropdownSlide(); 24575 filterPhonesList(); 24576 menuHamburger(); 24577 changePhoneVariant(); 24578 initLocalePopin(); // Initialize the locale popin 24579 pageChannel(); 24580 ajaxPortabilite(); 24581 pageComplement(); 24582 channelGoTop(); 24583 functions_cookies(); 24584 carrousel(); 24585 datalayer_Tracking(); 24586 webCallback(); 24587 initEnergyClassModal(); 24588 initForfaitTypePopin(); 24589 if (typeof sfrJSVars.headbandSpeed !== "undefined" && typeof sfrJSVars.headbandSpeed.time !== "undefined" && sfrJSVars.headbandSpeed.time) { 24590 headBand(); 24591 } 24592 new LazyLoad("lazy", 0); 24593 functions_initTooltips(); 24594 24595 /*$( ".carrousel_container.is_sliding" ).each(function() { 24596 new Carrousel($( this ), { 24597 auto: false, 24598 puces: false 24599 }).init() 24600 });*/ 24601}); 24602 24603/* A la fin du chargement de la page */ 24604$(window).on("load", function () { 24605 headerSticky(); 24606 //carrouselInit(); 24607 //new LazyLoad('lazy', 0); 24608}); 24609 24610/* Au resize du navigateur */ 24611$(window).resize(function () { 24612 if (typeof sfrJSVars.headbandSpeed !== "undefined" && typeof sfrJSVars.headbandSpeed.time !== "undefined" && sfrJSVars.headbandSpeed.time) { 24613 headBand(); 24614 } 24615}); 24616 24617/* Au scroll */ 24618$(window).scroll(function () { 24619 headerSticky(); 24620 channelGoTop(); 24621}); 24622 24623/* Gère la redirection en fonction du pays choisis. */ 24624function selectCountryLocation() { 24625 $("#zone-geographique").on("change", function () { 24626 document.location.href = $(this).val(); 24627 }); 24628} 24629 24630/* Gère le dropdown dans le footer. */ 24631function footerSubMenuSlide() { 24632 if ($(window).width() <= 540) { 24633 $(".footer").find(".sub-menu").css("display", "none"); 24634 $("#column-footer > li").click(function () { 24635 $(this).find(".sub-menu").slideToggle("fast"); 24636 }); 24637 } else { 24638 $(".footer").find(".sub-menu").css("display", "block"); 24639 } 24640} 24641 24642/* Gère les dropdowns du site */ 24643function allDropdownSlide() { 24644 $(".toggle-dropdown .active_toggle_event").unbind().on("click", function () { 24645 if ($(this).closest(".toggle-dropdown").hasClass("opened")) { 24646 $(this).closest(".toggle-dropdown").removeClass("opened").find(".accordeon").slide
24646Up(); 24647 } else { 24648 $(this).closest(".toggle-dropdown").addClass("opened").find(".accordeon").slideDown(); 24649 } 24650 }); 24651} 24652 24653/* Helper function to initialize tooltips */ 24654function functions_initTooltips() { 24655 const tooltips = document.querySelectorAll(".tooltip"); 24656 tooltips.forEach(el => { 24657 // Ãviter de réinitialiser un tooltip déjà initialisé 24658 if (!el.classList.contains("tooltip-initialized")) { 24659 new Tooltip(el); 24660 el.classList.add("tooltip-initialized"); 24661 } 24662 }); 24663} 24664 24665// Rendre la fonction accessible globalement pour les autres modules 24666window.initTooltips = functions_initTooltips; 24667function filterPhonesList() { 24668 $(".phones-list .filters select, .phones-list .filters input, .phones-list .filters select").on("change", function () { 24669 ajaxListPhones($(this)); 24670 }); 24671 $("#archive_phones .phones-list .filters .reset").click(function () { 24672 var $filters = $(this).parents(".filters"); 24673 $filters.find(".form-group select").each(function () { 24674 $(this).find("option:eq(0)").prop("selected", true); 24675 }); 24676 $filters.find(".form-group-checkbox input").each(function () { 24677 $(this).prop("checked", false); 24678 }); 24679 ajaxListPhones($(this)); 24680 }); 24681} 24682function ajaxListPhones(current) { 24683 const $phones = current.parents(".phones-list").find(".phones"); 24684 $phones.addClass("loading"); 24685 var params = {}; 24686 24687 // Only collect filter selects (brands and techno), exclude sort 24688 $.each(current.parents(".filters").find("select:not(#sort)"), function (index, element) { 24689 params[index] = { 24690 term: $(element).attr("id"), 24691 val: $(element).val() 24692 }; 24693 if ($(element).val() == "all") { 24694 $(element).find("option").removeAttr("selected"); 24695 $(element).find("option:first-of-type").attr("selected", "selected"); 24696 } 24697 }); 24698 24699 // Check if promos checkbox exists before trying to read it 24700 var promosChecked = $("#promos").length > 0 ? $("#promos").is(":checked") : false; 24701 $.ajax({ 24702 url: sfrJSVars.ajaxurl, 24703 // Wordpress ajax 24704 method: "POST", 24705 data: { 24706 action: "displayFilterPhones", 24707 params: params, 24708 pageID: $("#archive_phones").data("id"), 24709 type: $("#archive_phones").data("type"), 24710 sort: $("#sort").val() || "news", 24711 promos: promosChecked 24712 }, 24713 success: function (data) { 24714 //console.log(data); 24715 $phones.find(".wrapper .cards").html($(data).filter("li")); 24716 var $breadCrumbs = $(".breadcrumbs"); 24717 var $countResult = $breadCrumbs.find(".wrapper .count-result"); 24718 var phrase = $(data).filter("li:not(.no_result)").length === 0 || $(data).filter("li:not(.no_result)").length === 1 ? $(data).filter("li:not(.no_result)").length + " " + $countResult.data("singular") : $(data).filter("li:not(.no_result)").length + " " + $countResult.data("plural"); 24719 $breadCrumbs.find(".wrapper .count-result").text(phrase); 24720 $phones.removeClass("loading"); 24721 new LazyLoad("lazy", 0); 24722 functions_initTooltips(); // Réinitialiser les tooltips après le rechargement AJAX 24723 }, 24724 error: function (request, error) { 24725 console.log(error); 24726 } 24727 }); 24728} 24729 24730/* JS pour la page liste chaînes */ 24731function pageChannel() { 24732 //Init Filters 24733 if ($("#archive_channel").get(0)) { 24734 let dataFF = $("#archive_channel .filters ul.filters-cat li button.selected").data("ff") ?? ""; 24735 let searchForForfaits = dataFF.split(",").slice(0, dataFF.split(",").length - 1); 24736 $("#archive_channel .filters").find(".filters-techno li button").each(function () { 24737 let availableForfaits = $(this).data("ff").split(",").slice(0, $(this).data("ff").split(",").length - 1); 24738 }); 24739 } 24740 24741 //Filters 24742 $("#archive_channel .channel-filters ul li button").click(function () { 24743 if (!$(this).hasClass("unavailable")) { 24744 if (!$(this).parents("ul").hasClass("type")) { 24745 $(this).parents("ul").find("li button").removeClass("selected"); 24746 $(this).addClass("selected"); 24747 let ffVisible = []; 24748 let ffAvailable = []; 24749 let ffData = []; 24750 $(this).parents("ul").parent().find(".filters-techno li button").each(function () { 24751 if ($(this).hasClass("selected")) { 24752 // S'assurer que data('ff') existe et est une chaîne avant d'appeler split() 24753 let dataFF = $(this).data("ff") || ""; 24754 ffVisible = typeof dataFF === "string" ? dataFF.split(",").slice(0, dataFF.split(",").length - 1) : []; 24755 } 24756 }); 24757 24758 // S'assurer que ffVisible est un tableau 24759 ffVisible = Array.isArray(ffVisible) ? ffVisible : []; 24760 $(this).parents("ul").parent().find(".filters-cat li button").each(function () { 24761 // S'assurer que data('ff') existe et est une chaîne avant d'appeler split() 24762 let buttonDataFF = $(this).data("ff") || ""; 24763 let buttonFFArray = typeof buttonDataFF === "string" ? buttonDataFF.split(",").slice(0, buttonDataFF.split(",").length - 1) : []; 24764 let isAvailable = buttonFFArray.filter(function (n) { 24765 return ffVisible.indexOf(n) !== -1; 24766 }); 24767 if (isAvailable.length < 1) { 24768 $(this).addClass("unavailable").removeClass("selected"); 24769 } else { 24770 $(this).removeClass("unavailable"); 24771 if (!$(this).parents("ul").parent().find(".filters-cat li button.selected").get(0)) { 24772 $(this).addClass("selected"); 24773 } 24774 } 24775 if ($(this).hasClass("selected")) { 24776 ffAvailable = Array.isArray(isAvailable) ? isAvailable : []; 24777 } 24778 let data = { 24779 text: $(this).data("availabletext"),
24780 color: $(this).data("color") 24781 }; 24782 24783 // Utiliser les variables déjà déclarées 24784 $.each(buttonFFArray, function (index, value) { 24785 ffData[value] = data; 24786 }); 24787 }); 24788 $("#archive_channel .channel_list ul li").each(function () { 24789 // S'assurer que data('ff') existe et est une chaîne avant d'appeler split() 24790 let liDataFF = $(this).data("ff") || ""; 24791 let liFFArray = typeof liDataFF === "string" ? liDataFF.split(",").slice(0, liDataFF.split(",").length - 1) : []; 24792 let isVisible = liFFArray.filter(function (n) { 24793 return ffVisible.indexOf(n) !== -1; 24794 }); 24795 if (isVisible.length < 1) { 24796 $(this).removeClass("visible"); 24797 } else { 24798 $(this).addClass("visible"); 24799 $(this).css({ 24800 "border-color": ffData[isVisible[0]].color 24801 }); 24802 $(this).find("figcaption").css({ 24803 color: ffData[isVisible[0]].color 24804 }).text(ffData[isVisible[0]].text); 24805 } 24806 24807 // Réutiliser les variables déjà déclarées pour éviter de refaire le même traitement 24808 let isAvailable = liFFArray.filter(function (n) { 24809 return ffAvailable.indexOf(n) !== -1; 24810 }); 24811 if (isAvailable.length < 1) { 24812 $(this).removeClass("available"); 24813 } else { 24814 $(this).addClass("available"); 24815 } 24816 }); 24817 $("#archive_channel .options_list ul li").each(function () { 24818 // S'assurer que data('ff') existe et est une chaîne avant d'appeler split() 24819 let optionDataFF = $(this).data("ff") || ""; 24820 let optionFFArray = typeof optionDataFF === "string" ? optionDataFF.split(",").slice(0, optionDataFF.split(",").length - 1) : []; 24821 let isVisible = optionFFArray.filter(function (n) { 24822 return ffAvailable.indexOf(n) !== -1; 24823 }); 24824 if (isVisible.length < 1) { 24825 $(this).removeClass("visible"); 24826 } else { 24827 $(this).addClass("visible"); 24828 } 24829 }); 24830 } else { 24831 let adminBarHeight = $("body").hasClass("admin-bar") ? 32 : 0, 24832 elementOffsetTop = $(this).hasClass("all") ? $(".channel_list").offset().top : $("#archive_channel").find('.channel_list article[data-radio="true"]').offset().top - 30, 24833 theScrollTop = elementOffsetTop - $("#heading").height() - adminBarHeight; 24834 $("html, body").animate({ 24835 scrollTop: theScrollTop 24836 }, 500); 24837 } 24838 } 24839 }); 24840 //Scroll 24841 if ($("#archive_channel").length !== 0) { 24842 $("#archive_channel").find(".channel_list .go-top").unbind("click").click(function () { 24843 $("html, body").animate({ 24844 scrollTop: $(".filters").offset().top - $("#heading").height() - ($("body").hasClass("admin-bar") ? 32 : 0) 24845 }, 500); 24846 }); 24847 if ($(".filters").offset().top - $("#heading").height() - ($("body").hasClass("admin-bar") ? 32 : 0) + parseFloat($(window).height()) < $("html, body").scrollTop()) { 24848 $("#archive_channel").find(".channel_list .go-top").addClass("active"); 24849 } else { 24850 $("#archive_channel").find(".channel_list .go-top").removeClass("active"); 24851 } 24852 if (parseFloat($("#archive_channel").find(".channel_list").outerHeight(true)) + parseFloat($("#archive_channel").find(".options_list").outerHeight(true)) + parseFloat($("#archive_channel").find(".channel_list").offset().top) < $(window).scrollTop() + $(window).height() + ($("body").hasClass("admin-bar") ? 32 : 0)) { 24853 $("#archive_channel").find(".channel_list .go-top").css({ 24854 top: parseFloat($("#archive_channel").find(".channel_list").height()) + parseFloat($("#archive_channel").find(".options_list").height()) - 30 + "px", 24855 position: "absolute" 24856 }); 24857 } else { 24858 $("#archive_channel").find(".channel_list .go-top").css({ 24859 top: "", 24860 position: "" 24861 }); 24862 } 24863 } 24864 //Popin 24865 $("#archive_channel .options_list .popin_action").on("click", function () { 24866 ajaxGetPopinContent($(this).data("id")); 24867 }); 24868} 24869 24870/* JS pour le menu burger */ 24871function menuHamburger() { 24872 $("#heading .hamburger").on("click", function () { 24873 $(this).find(".icons").toggleClass("open"); 24874 $("body").toggleClass("stop_scrolling"); 24875 $("#menu_page").toggleClass("visible"); 24876 $("html, body").animate({ 24877 scrollTop: 0 24878 }, 100); 24879 }); 24880} 24881function changePhoneVariant() { 24882 var $singlePhone = $("#single-phone"); 24883 $singlePhone.find(".colors ul li").unbind().on("click", function () { 24884 if (!$(this).hasClass("active")) { 24885 $("#single-phone").find(".colors ul li").removeClass("active"); 24886 $(this).addClass("active"); 24887 ajaxSinglePhone($singlePhone, "sfr_device_color"); 24888 } 24889 }); 24890 $singlePhone.find("#phone .phone-description .capacity select").unbind().on("change", function () { 24891 ajaxSinglePhone($singlePhone, "sfr_device_capacity"); 24892 }); 24893} 24894 24895/* Permet de gérer l'ajax des fiche téléphone, en fonction de si on change de couleur ou de capacité de stockage */ 24896function ajaxSinglePhone($singlePhone, principal) { 24897 var params = {}; 24898 params["sfr_device_color"] = $singlePhone.find("#phone .phone-description .colors .active").data("c
24898olor"); /* Couleur */ 24899 params["sfr_device_capacity"] = $singlePhone.find("#phone .phone-description .capacity select option:selected").val(); /* Capacité */ 24900 params["phoneID"] = $singlePhone.find("#phone").data("id"); /* Id du téléphone */ 24901 params["posttype"] = $singlePhone.find("#phone").data("posttype"); /* posttype du material */ 24902 params["principal"] = principal; /* Savoir ou la personne à cliqué */ 24903 24904 $singlePhone.find("#phone").addClass("loading"); 24905 $.ajax({ 24906 url: sfrJSVars.ajaxurl, 24907 method: "POST", 24908 data: { 24909 action: "displaySinglePhone", 24910 params: params 24911 }, 24912 success: function (data) { 24913 $singlePhone.find("#phone").remove(); /* On vide le dom */ 24914 $(data).insertAfter($singlePhone.find(".breadcrumbs")); /* On le réinsère */ 24915 24916 $singlePhone.find("#phone").removeClass("loading"); 24917 24918 /* On rappel nos functions */ 24919 $(".carrousel_container.is_sliding").each(function () { 24920 new Carrousel($(this), { 24921 auto: false, 24922 puces: false 24923 }).init(); 24924 }); 24925 changePhoneVariant(); 24926 allDropdownSlide(); 24927 }, 24928 error: function (request, error) { 24929 console.log(error); 24930 } 24931 }); 24932} 24933 24934/* Passe le header en sticky avant qu'il ne disparaisse de l'écran */ 24935function headerSticky() { 24936 if (!$("body").hasClass("stop_listening")) { 24937 if (!$("body").hasClass("fixed_head") && $(document).scrollTop() > $("#heading").innerHeight() / 1.5) { 24938 $("main").css({ 24939 "padding-top": $("#heading").innerHeight() + "px" 24940 }); 24941 $("body").addClass("fixed_head"); 24942 } else if ($("body").hasClass("fixed_head") && $(document).scrollTop() <= parseInt($("main").css("padding-top")) - $("#heading").innerHeight()) { 24943 $("main").css({ 24944 "padding-top": "0px" 24945 }); 24946 $("body").removeClass("fixed_head"); 24947 } 24948 } 24949} 24950 24951// ********* // 24952//FORFAITS 24953// ********* // 24954
24955function ajaxPortabilite() { 24956 $("#portabilite-form input").change(function () { 24957 $("#portabilite-form").removeClass("error_numbers, error_fields"); 24958 }); 24959 $("#portabilite-form").on("submit", function (e) { 24960 e.preventDefault(); 24961 if ($("#portabilite-numero").val() != "" && $("#portabilite-rio").val() != "") { 24962 $("#portabilite-form .button").addClass("loading"); 24963 $.ajax({ 24964 url: sfrJSVars.ajaxurl, 24965 method: "POST", 24966 data: { 24967 action: "ajaxPortabilite", 24968 params: { 24969 numero: $("#portabilite-numero").val(), 24970 rio: $("#portabilite-rio").val(), 24971 type: $("#post-type").val() 24972 } 24973 }, 24974 success: function (data) { 24975 if (JSON.parse(data).message && JSON.parse(data).message.toLowerCase() == "ok") { 24976 if ($("#redirect-to").val() != "" && $("#post-type").val() != "") { 24977 window.location.href = $("#redirect-to").val() + "#ff"; 24978 } else { 24979 $("#portabilite-form").addClass("error_redirect"); 24980 $("#portabilite-form").append('<div class="error error_redirect"><p>DEV : Portability page need ?parent=[pageID]&type=[typeName] parameters to work</p></div>'); 24981 $("#portabilite-form .button").removeClass("loading"); 24982 } 24983 } else { 24984 $("#portabilite-form").addClass("error_numbers"); 24985 $("#portabilite-form .button").removeClass("loading"); 24986 } 24987 }, 24988 error: function (request, error) { 24989 $("#portabilite-form").addClass("error_numbers"); 24990 } 24991 }); 24992 } else { 24993 $("#portabilite-form").addClass("error_fields"); 24994 } 24995 }); 24996} 24997 24998// ********* // 24999// ********* // 25000// ********* // 25001 25002function pageComplement() { 25003 $("#complement form article .popin_action").click(function () { 25004 ajaxGetPopinContent($(this).data("id")); 25005 }); 25006 25007 // Handle add button clicks 25008 $("#complement form article.options .el_carr .add-button").click(function () { 25009 const $button = $(this); 25010 const $checkbox = $button.siblings('input[type="checkbox"]'); 25011 const optionId = $button.data("option-id"); 25012 25013 // Toggle the checkbox 25014 const isChecked = $checkbox.prop("checked"); 25015 $checkbox.prop("checked", !isChecked); 25016 25017 // Toggle button active state 25018 $button.toggleClass("active"); 25019 25020 // Handle exclusive selection by type 25021 if ($button.data("type") && !isChecked) { 25022 const type = $button.data("type"); 25023 const code = $button.data("code"); 25024 $("#complement form article.options .el_carr .add-button").each(function () { 25025 if ($(this).data("type") == type && $(this).data("code") != code) { 25026 $(this).parent().find('input[type="checkbox"]').prop("checked", false); 25027 } 25028 }); 25029 } 25030 }); 25031} 25032function channelGoTop() {} 25033function functions_cookies() { 25034 var $cookieConsent = $("#cookieconsent"), 25035 $cookieSettings = $("#cookiesettings"), 25036 classVisible = "visible", 25037 classHidden = "masked"; 25038 $("#cookieconsent .settings").click(function () { 25039 $cookieConsent.addClass(classHidden); 25040 $cookieSettings.addClass(classVisible); 25041 }); 25042 $("#cookieconsent .allow").click(function () { 25043 cookies.write("cookieconsent_status", JSON.stringify({ 25044 analytics: true, 25045 marketing: true, 25046 personnalisation: true 25047 }), 365); 25048 $cookieConsent.addClass(classHidden); 25049 document.location.reload(true); 25050 }); 25051 $("#cookieconsent .disallow").click(function () { 25052 cookies.write("cookieconsent_status", JSON.stringify({ 25053 analytics: false, 25054 marketing: false, 25055 personnalisation: false 25056 }), 365); 25057 $cookieConsent.addClass(classHidden); 25058 document.location.reload(true); 25059 }); 25060 $("#cookiesettings .close").click(function () { 25061 $cookieSettings.removeClass(classVisible); 25062 }); 25063 $("#cookiesettings button").click(function () { 25064 var cookie = { 25065 analytics: true, 25066 marketing: true, 25067 personnalisation: true 25068 }; 25069 $("#cookiesettings .toggle").each(function () { 25070 if ($(this).hasClass("active")) { 25071 cookie[$(this).data("cookie")] = true; 25072 } else {
25073 cookie[$(this).data("cookie")] = false; 25074 } 25075 }); 25076 cookies.write("cookieconsent_status", JSON.stringify(cookie), 365); 25077 $cookieSettings.removeClass(classVisible); 25078 document.location.reload(true); 25079 }); 25080 $("#cookiesettings .toggle").click(function () { 25081 $(this).toggleClass("active"); 25082 }); 25083 $(".cookie_config").click(function () { 25084 $cookieConsent.addClass(classHidden); 25085 $cookieSettings.addClass(classVisible); 25086 }); 25087 $("#cookie_policy .settings").click(function () { 25088 $cookieConsent.addClass(classHidden); 25089 $cookieSettings.addClass(classVisible); 25090 }); 25091} 25092function headBand() { 25093 $("#alert_headband .animation").css({ 25094 "animation-duration": $("#alert_headband .animation .content").innerWidth() / 60 / sfrJSVars.headbandSpeed.time + "s" 25095 }); 25096} 25097})(); 25098 25099SpinFunctions = __webpack_exports__; 25100/******/ })() 25101;
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.