vendor: 207,836 bytes, lines 1-6312
1/*! 2 * Bootstrap v5.3.8 (https://getbootstrap.com/) 3 * Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 */ 6(function (global, factory) { 7 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 8 typeof define === 'function' && define.amd ? define(factory) : 9 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory()); 10})(this, (function () { 'use strict'; 11 12 /** 13 * -------------------------------------------------------------------------- 14 * Bootstrap dom/data.js 15 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 16 * -------------------------------------------------------------------------- 17 */ 18 19 /** 20 * Constants 21 */ 22 23 const elementMap = new Map(); 24 const Data = { 25 set(element, key, instance) { 26 if (!elementMap.has(element)) { 27 elementMap.set(element, new Map()); 28 } 29 const instanceMap = elementMap.get(element); 30 31 // make it clear we only want one instance per element 32 // can be removed later when multiple key/instances are fine to be used 33 if (!instanceMap.has(key) && instanceMap.size !== 0) { 34 // eslint-disable-next-line no-console 35 console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`); 36 return; 37 } 38 instanceMap.set(key, instance); 39 }, 40 get(element, key) { 41 if (elementMap.has(element)) { 42 return elementMap.get(element).get(key) || null; 43 } 44 return null; 45 }, 46 remove(element, key) { 47 if (!elementMap.has(element)) { 48 return; 49 } 50 const instanceMap = elementMap.get(element); 51 instanceMap.delete(key); 52 53 // free up element references if there are no instances left for an element 54 if (instanceMap.size === 0) { 55 elementMap.delete(element); 56 } 57 } 58 }; 59 60 /** 61 * -------------------------------------------------------------------------- 62 * Bootstrap util/index.js 63 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 64 * -------------------------------------------------------------------------- 65 */ 66 67 const MAX_UID = 1000000; 68 const MILLISECONDS_MULTIPLIER = 1000; 69 const TRANSITION_END = 'transitionend'; 70 71 /** 72 * Properly escape IDs selectors to handle weird IDs 73 * @param {string} selector 74 * @returns {string} 75 */ 76 const parseSelector = selector => { 77 if (selector && window.CSS && window.CSS.escape) { 78 // document.querySelector needs escaping to handle IDs (html5+) containing for instance / 79 selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`); 80 } 81 return selector; 82 }; 83 84 // Shout-out Angus Croll (https://goo.gl/pxwQGp) 85 const toType = object => { 86 if (object === null || object === undefined) { 87 return `${object}`; 88 } 89 return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase(); 90 }; 91 92 /** 93 * Public Util API 94 */ 95 96 const getUID = prefix => { 97 do { 98 prefix += Math.floor(Math.random() * MAX_UID); 99 } while (document.getElementById(prefix)); 100 return prefix; 101 }; 102 const getTransitionDurationFromElement = element => { 103 if (!element) { 104 return 0; 105 } 106 107 // Get transition-duration of the element 108 let { 109 transitionDuration, 110 transitionDelay 111 } = window.getComputedStyle(element); 112 const floatTransitionDuration = Number.parseFloat(transitionDuration); 113 const floatTransitionDelay = Number.parseFloat(transitionDelay); 114 115 // Return 0 if element or transition duration is not found 116 if (!floatTransitionDuration && !floatTransitionDelay) { 117 return 0; 118 } 119 120 // If multiple durations are defined, take the first 121 transitionDuration = transitionDuration.split(',')[0]; 122 transitionDelay = transitionDelay.split(',')[0]; 123 return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; 124 }; 125 const triggerTransitionEnd = element => { 126 element.dispatchEvent(new Event(TRANSITION_END)); 127 }; 128 const isElement$1 = object => { 129 if (!object || typeof object !== 'object') { 130 return false; 131 } 132 if (typeof object.jquery !== 'undefined') { 133 object = object[0]; 134 } 135 return typeof object.nodeType !== 'undefined'; 136 }; 137 const getElement = object => { 138 // it's a jQuery object or a node element 139 if (isElement$1(object)) { 140 return object.jquery ? object[0] : object; 141 } 142 if (typeof object === 'string' && object.length > 0) { 143 return document.querySelector(parseSelector(object)); 144 } 145 return null; 146 }; 147 const isVisible = element => { 148 if (!isElement$1(element) || element.getClientRects().length === 0) { 149 return false; 150 } 151 const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'; 152 // Handle `details` element as its content may falsie appear visible when it is closed 153 const closedDetails = element.closest('details:not([open])'); 154 if (!closedDetails) { 155 return elementIsVisible; 156 } 157 if (closedDetails !== element) { 158 const summary = element.closest('summary'); 159 if (summary && summary.parentNode !== closedDetails) { 160 return false; 161 } 162 if (summary === null) { 163 return false; 164 } 165 } 166 return elementIsVisible; 167 }; 168 const isDisabled = element => { 169 if (!element || element.nodeType !== Node.ELEMENT_NODE) { 170 return true; 171 } 172 if (element.classList.contains('disabled')) { 173 return true; 174 } 175 if (typeof element.disabled !== 'undefined') { 176 return element.disabled; 177 } 178 return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'; 179 }; 180 const findShadowRoot = element => { 181 if (!document.documentElement.attachShadow) { 182 return null; 183 } 184 185 // Can find the shadow root otherwise it'll return the document 186 if (typeof element.getRootNode === 'function') { 187 const root = element.getRootNode(); 188 return root instanceof ShadowRoot ? root : null; 189 } 190 if (element instanceof ShadowRoot) { 191 return element; 192 } 193 194 // when we don't find a shadow root 195 if (!element.parentNode) { 196 return null; 197 } 198 return findShadowRoot(element.parentNode); 199 }; 200 const noop = () => {}; 201 202 /** 203 * Trick to restart an element's animation 204 * 205 * @param {HTMLElement} element 206 * @return void 207 * 208 * @see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation 209 */ 210 const reflow = element => { 211 element.offsetHeight; // eslint-disable-line no-unused-expressions 212 }; 213 const getjQuery = () => { 214 if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) { 215 return window.jQuery; 216 } 217 return null; 218 }; 219 const DOMContentLoadedCallbacks = []; 220 const onDOMContentLoaded = callback => { 221 if (document.readyState === 'loading') { 222 // add listener on the first call when the document is in loading state 223 if (!DOMContentLoadedCallbacks.length) { 224 document.addEventListener('DOMContentLoaded', () => { 225 for (const callback of DOMContentLoadedCallbacks) { 226 callback(); 227 } 228 }); 229 } 230 DOMContentLoadedCallbacks.push(callback); 231 } else { 232 callback(); 233 } 234 }; 235 const isRTL = () => document.documentElement.dir === 'rtl'; 236 const defineJQueryPlugin = plugin => { 237 onDOMContentLoaded(() => { 238 const $ = getjQuery(); 239 /* istanbul ignore if */ 240 if ($) { 241 const name = plugin.NAME; 242 const JQUERY_NO_CONFLICT = $.fn[name]; 243 $.fn[name] = plugin.jQueryInterface; 244 $.fn[name].Constructor = plugin; 245 $.fn[name].noConflict = () => { 246 $.fn[name] = JQUERY_NO_CONFLICT; 247 return plugin.jQueryInterface; 248 }; 249 } 250 }); 251 }; 252 const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => { 253 return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue; 254 }; 255 const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => { 256 if (!waitForTransition) { 257 execute(callback); 258 return; 259 } 260 const durationPadding = 5; 261 const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding; 262 let called = false; 263 const handler = ({ 264 target 265 }) => { 266 if (target !== transitionElement) { 267 return; 268 } 269 called = true; 270 transitionElement.removeEventListener(TRANSITION_END, handler); 271 execute(callback); 272 }; 273 transitionElement.addEventListener(TRANSITION_END, handler); 274 setTimeout(() => { 275 if (!called) { 276 triggerTransitionEnd(transitionElement); 277 } 278 }, emulatedDuration); 279 }; 280 281 /** 282 * Return the previous/next element of a list. 283 * 284 * @param {array} list The list of elements 285 * @param activeElement The active element 286 * @param shouldGetNext Choose to get next or previous element 287 * @param isCycleAllowed 288 * @return {Element|elem} The proper element 289 */ 290 const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => { 291 const listLength = list.length; 292 let index = list.indexOf(activeElement); 293 294 // if the element does not exist in the list return an element 295 // depending on the direction and if cycle is allowed 296 if (index === -1) { 297 return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]; 298 } 299 index += shouldGetNext ? 1 : -1; 300 if (isCycleAllowed) { 301 index = (index + listLength) % listLength; 302 } 303 return list[Math.max(0, Math.min(index, listLength - 1))]; 304 }; 305 306 /** 307 * -------------------------------------------------------------------------- 308 * Bootstrap dom/event-handler.js 309 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 310 * -------------------------------------------------------------------------- 311 */ 312 313 314 /** 315 * Constants 316 */ 317 318 const namespaceRegex = /[^.]*(?=\..*)\.|.*/; 319 const stripNameRegex = /\..*/; 320 const stripUidRegex = /::\d+$/; 321 const eventRegistry = {}; // Events storage 322 let uidEvent = 1; 323 const customEvents = { 324 mouseenter: 'mouseover', 325 mouseleave: 'mouseout' 326 }; 327 const nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']); 328 329 /** 330 * Private methods 331 */ 332 333 function makeEventUid(element, uid) { 334 return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++; 335 } 336 function getElementEvents(element) { 337 const uid = makeEventUid(element); 338 element.uidEvent = uid; 339 eventRegistry[uid] = eventRegistry[uid] || {}; 340 return eventRegistry[uid]; 341 } 342 function bootstrapHandler(element, fn) { 343 return function handler(event) { 344 hydrateObj(event, { 345 delegateTarget: element 346 }); 347 if (handler.oneOff) { 348 EventHandler.off(element, event.type, fn); 349 } 350 return fn.apply(element, [event]); 351 }; 352 } 353 function bootstrapDelegationHandler(element, selector, fn) { 354 return function handler(event) { 355 const domElements = element.querySelectorAll(selector); 356 for (let { 357 target 358 } = event; target && target !== this; target = target.parentNode) { 359 for (const domElement of domElements) { 360 if (domElement !== target) { 361 continue; 362 } 363 hydrateObj(event, { 364 delegateTarget: target 365 }); 366 if (handler.oneOff) { 367 EventHandler.off(element, event.type, selector, fn); 368 } 369 return fn.apply(target, [event]); 370 } 371 } 372 }; 373 } 374 function findHandler(events, callable, delegationSelector = null) { 375 return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector); 376 } 377 function normalizeParameters(originalTypeEvent, handler, delegationFunction) { 378 const isDelegated = typeof handler === 'string'; 379 // TODO: tooltip passes `false` instead of selector, so we need to check 380 const callable = isDelegated ? delegationFunction : handler || delegationFunction; 381 let typeEvent = getTypeEvent(originalTypeEvent); 382 if (!nativeEvents.has(typeEvent)) { 383 typeEvent = originalTypeEvent; 384 } 385 return [isDelegated, callable, typeEvent]; 386 } 387 function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) { 388 if (typeof originalTypeEvent !== 'string' || !element) { 389 return; 390 } 391 let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); 392 393 // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position 394 // this prevents the handler from being dispatched the same way as mouseover or mouseout does 395 if (originalTypeEvent in customEvents) { 396 const wrapFunction = fn => { 397 return function (event) { 398 if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) { 399 return fn.call(this, event); 400 } 401 }; 402 }; 403 callable = wrapFunction(callable); 404 } 405 const events = getElementEvents(element); 406 const handlers = events[typeEvent] || (events[typeEvent] = {}); 407 const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null); 408 if (previousFunction) { 409 previousFunction.oneOff = previousFunction.oneOff && oneOff; 410 return; 411 } 412 const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, '')); 413 const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable); 414 fn.delegationSelector = isDelegated ? handler : null; 415 fn.callable = callable; 416 fn.oneOff = oneOff; 417 fn.uidEvent = uid; 418 handlers[uid] = fn; 419 element.addEventListener(typeEvent, fn, isDelegated); 420 } 421 function removeHandler(element, events, typeEvent, handler, delegationSelector) { 422 const fn = findHandler(events[typeEvent], handler, delegationSelector); 423 if (!fn) { 424 return; 425 } 426 element.removeEventListener(typeEvent, fn, Boolean(delegationSelector)); 427 delete events[typeEvent][fn.uidEvent]; 428 } 429 function removeNamespacedHandlers(element, events, typeEvent, namespace) { 430 const storeElementEvent = events[typeEvent] || {}; 431 for (const [handlerKey, event] of Object.entries(storeElementEvent)) { 432 if (handlerKey.includes(namespace)) { 433 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); 434 } 435 } 436 } 437 function getTypeEvent(event) { 438 // allow to get the native events from namespaced events ('click.bs.button' --> 'click') 439 event = event.replace(stripNameRegex, ''); 440 return customEvents[event] || event; 441 } 442 const EventHandler = { 443 on(element, event, handler, delegationFunction) { 444 addHandler(element, event, handler, delegationFunction, false); 445 }, 446 one(element, event, handler, delegationFunction) { 447 addHandler(element, event, handler, delegationFunction, true); 448 }, 449 off(element, originalTypeEvent, handler, delegationFunction) { 450 if (typeof originalTypeEvent !== 'string' || !element) { 451 return; 452 } 453 const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); 454 const inNamespace = typeEvent !== originalTypeEvent; 455 const events = getElementEvents(element); 456 const storeElementEvent = events[typeEvent] || {}; 457 const isNamespace = originalTypeEvent.startsWith('.'); 458 if (typeof callable !== 'undefined') { 459 // Simplest case: handler is passed, remove that listener ONLY. 460 if (!Object.keys(storeElementEvent).length) { 461 return; 462 } 463 removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null); 464 return; 465 } 466 if (isNamespace) { 467 for (const elementEvent of Object.keys(events)) { 468 removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1)); 469 } 470 } 471 for (const [keyHandlers, event] of Object.entries(storeElementEvent)) { 472 const handlerKey = keyHandlers.replace(stripUidRegex, ''); 473 if (!inNamespace || originalTypeEvent.includes(handlerKey)) { 474 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); 475 } 476 } 477 }, 478 trigger(element, event, args) { 479 if (typeof event !== 'string' || !element) { 480 return null; 481 } 482 const $ = getjQuery(); 483 const typeEvent = getTypeEvent(event); 484 const inNamespace = event !== typeEvent; 485 let jQueryEvent = null; 486 let bubbles = true; 487 let nativeDispatch = true; 488 let defaultPrevented = false; 489 if (inNamespace && $) { 490 jQueryEvent = $.Event(event, args); 491 $(element).trigger(jQueryEvent); 492 bubbles = !jQueryEvent.isPropagationStopped(); 493 nativeDispatch = !jQueryEvent.isImmediatePropagationStopped(); 494 defaultPrevented = jQueryEvent.isDefaultPrevented(); 495 } 496 const evt = hydrateObj(new Event(event, { 497 bubbles, 498 cancelable: true 499 }), args); 500 if (defaultPrevented) { 501 evt.preventDefault(); 502 } 503 if (nativeDispatch) { 504 element.dispatchEvent(evt); 505 } 506 if (evt.defaultPrevented && jQueryEvent) { 507 jQueryEvent.preventDefault(); 508 } 509 return evt; 510 } 511 }; 512 function hydrateObj(obj, meta = {}) { 513 for (const [key, value] of Object.entries(meta)) { 514 try { 515 obj[key] = value; 516 } catch (_unused) { 517 Object.defineProperty(obj, key, { 518 configurable: true, 519 get() { 520 return value; 521 } 522 }); 523 } 524 } 525 return obj; 526 } 527 528 /** 529 * -------------------------------------------------------------------------- 530 * Bootstrap dom/manipulator.js 531 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 532 * -------------------------------------------------------------------------- 533 */ 534 535 function normalizeData(value) { 536 if (value === 'true') { 537 return true; 538 } 539 if (value === 'false') { 540 return false; 541 } 542 if (value === Number(value).toString()) { 543 return Number(value); 544 } 545 if (value === '' || value === 'null') { 546 return null; 547 } 548 if (typeof value !== 'string') { 549 return value; 550 } 551 try { 552 return JSON.parse(decodeURIComponent(value)); 553 } catch (_unused) { 554 return value; 555 } 556 } 557 function normalizeDataKey(key) { 558 return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`); 559 } 560 const Manipulator = { 561 setDataAttribute(element, key, value) { 562 element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value); 563 }, 564 removeDataAttribute(element, key) { 565 element.removeAttribute(`data-bs-${normalizeDataKey(key)}`); 566 }, 567 getDataAttributes(element) { 568 if (!element) { 569 return {}; 570 } 571 const attributes = {}; 572 const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig')); 573 for (const key of bsKeys) { 574 let pureKey = key.replace(/^bs/, ''); 575 pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1); 576 attributes[pureKey] = normalizeData(element.dataset[key]); 577 } 578 return attributes; 579 }, 580 getDataAttribute(element, key) { 581 return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`)); 582 } 583 }; 584 585 /** 586 * -------------------------------------------------------------------------- 587 * Bootstrap util/config.js 588 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 589 * -------------------------------------------------------------------------- 590 */ 591 592 593 /** 594 * Class definition 595 */ 596 597 class Config { 598 // Getters 599 static get Default() { 600 return {}; 601 } 602 static get DefaultType() { 603 return {}; 604 } 605 static get NAME() { 606 throw new Error('You have to implement the static method "NAME", for each component!'); 607 } 608 _getConfig(config) { 609 config = this._mergeConfigObj(config); 610 config = this._configAfterMerge(config); 611 this._typeCheckConfig(config); 612 return config; 613 } 614 _configAfterMerge(config) { 615 return config; 616 } 617 _mergeConfigObj(config, element) { 618 const jsonConfig = isElement$1(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse 619 620 return { 621 ...this.constructor.Default, 622 ...(typeof jsonConfig === 'object' ? jsonConfig : {}), 623 ...(isElement$1(element) ? Manipulator.getDataAttributes(element) : {}), 624 ...(typeof config === 'object' ? config : {}) 625 }; 626 } 627 _typeCheckConfig(config, configTypes = this.constructor.DefaultType) { 628 for (const [property, expectedTypes] of Object.entries(configTypes)) { 629 const value = config[property]; 630 const valueType = isElement$1(value) ? 'element' : toType(value); 631 if (!new RegExp(expectedTypes).test(valueType)) { 632 throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`); 633 } 634 } 635 } 636 } 637 638 /** 639 * -------------------------------------------------------------------------- 640 * Bootstrap base-component.js 641 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 642 * -------------------------------------------------------------------------- 643 */ 644 645 646 /** 647 * Constants 648 */ 649 650 const VERSION = '5.3.8'; 651 652 /** 653 * Class definition 654 */ 655 656 class BaseComponent extends Config { 657 constructor(element, config) { 658 super(); 659 element = getElement(element); 660 if (!element) { 661 return; 662 } 663 this._element = element; 664 this._config = this._getConfig(config); 665 Data.set(this._element, this.constructor.DATA_KEY, this); 666 } 667 668 // Public 669 dispose() { 670 Data.remove(this._element, this.constructor.DATA_KEY); 671 EventHandler.off(this._element, this.constructor.EVENT_KEY); 672 for (const propertyName of Object.getOwnPropertyNames(this)) { 673 this[propertyName] = null; 674 } 675 } 676 677 // Private 678 _queueCallback(callback, element, isAnimated = true) { 679 executeAfterTransition(callback, element, isAnimated); 680 } 681 _getConfig(config) { 682 config = this._mergeConfigObj(config, this._element); 683 config = this._configAfterMerge(config); 684 this._typeCheckConfig(config); 685 return config; 686 } 687 688 // Static 689 static getInstance(element) { 690 return Data.get(getElement(element), this.DATA_KEY); 691 } 692 static getOrCreateInstance(element, config = {}) { 693 return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null); 694 } 695 static get VERSION() { 696 return VERSION; 697 } 698 static get DATA_KEY() { 699 return `bs.${this.NAME}`; 700 } 701 static get EVENT_KEY() { 702 return `.${this.DATA_KEY}`; 703 } 704 static eventName(name) { 705 return `${name}${this.EVENT_KEY}`; 706 } 707 } 708 709 /** 710 * -------------------------------------------------------------------------- 711 * Bootstrap dom/selector-engine.js 712 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 713 * -------------------------------------------------------------------------- 714 */ 715 716 const getSelector = element => { 717 let selector = element.getAttribute('data-bs-target'); 718 if (!selector || selector === '#') { 719 let hrefAttribute = element.getAttribute('href'); 720 721 // The only valid content that could double as a selector are IDs or classes, 722 // so everything starting with `#` or `.`. If a "real" URL is used as the selector, 723 // `document.querySelector` will rightfully complain it is invalid. 724 // See https://github.com/twbs/bootstrap/issues/32273 725 if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) { 726 return null; 727 } 728 729 // Just in case some CMS puts out a full URL with the anchor appended 730 if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) { 731 hrefAttribute = `#${hrefAttribute.split('#')[1]}`; 732 } 733 selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null; 734 } 735 return selector ? selector.split(',').map(sel => parseSelector(sel)).join(',') : null; 736 }; 737 const SelectorEngine = { 738 find(selector, element = document.documentElement) { 739 return [].concat(...Element.prototype.querySelectorAll.call(element, selector)); 740 }, 741 findOne(selector, element = document.documentElement) { 742 return Element.prototype.querySelector.call(element, selector); 743 }, 744 children(element, selector) { 745 return [].concat(...element.children).filter(child => child.matches(selector)); 746 }, 747 parents(element, selector) { 748 const parents = []; 749 let ancestor = element.parentNode.closest(selector); 750 while (ancestor) { 751 parents.push(ancestor); 752 ancestor = ancestor.parentNode.closest(selector); 753 } 754 return parents; 755 }, 756 prev(element, selector) { 757 let previous = element.previousElementSibling; 758 while (previous) { 759 if (previous.matches(selector)) { 760 return [previous]; 761 } 762 previous = previous.previousElementSibling; 763 } 764 return []; 765 }, 766 // TODO: this is now unused; remove later along with prev() 767 next(element, selector) { 768 let next = element.nextElementSibling; 769 while (next) { 770 if (next.matches(selector)) { 771 return [next]; 772 } 773 next = next.nextElementSibling; 774 } 775 return []; 776 }, 777 focusableChildren(element) { 778 const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `${selector}:not([tabindex^="-"])`).join(','); 779 return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el)); 780 }, 781 getSelectorFromElement(element) { 782 const selector = getSelector(element); 783 if (selector) { 784 return SelectorEngine.findOne(selector) ? selector : null; 785 } 786 return null; 787 }, 788 getElementFromSelector(element) { 789 const selector = getSelector(element); 790 return selector ? SelectorEngine.findOne(selector) : null; 791 }, 792 getMultipleElementsFromSelector(element) { 793 const selector = getSelector(element); 794 return selector ? SelectorEngine.find(selector) : []; 795 } 796 }; 797 798 /** 799 * -------------------------------------------------------------------------- 800 * Bootstrap util/component-functions.js 801 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 802 * -------------------------------------------------------------------------- 803 */ 804 805 const enableDismissTrigger = (component, method = 'hide') => { 806 const clickEvent = `click.dismiss${component.EVENT_KEY}`; 807 const name = component.NAME; 808 EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) { 809 if (['A', 'AREA'].includes(this.tagName)) { 810 event.preventDefault(); 811 } 812 if (isDisabled(this)) { 813 return; 814 } 815 const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`); 816 const instance = component.getOrCreateInstance(target); 817 818 // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method 819 instance[method](); 820 }); 821 }; 822 823 /** 824 * -------------------------------------------------------------------------- 825 * Bootstrap alert.js 826 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 827 * -------------------------------------------------------------------------- 828 */ 829 830 831 /** 832 * Constants 833 */ 834 835 const NAME$f = 'alert'; 836 const DATA_KEY$a = 'bs.alert'; 837 const EVENT_KEY$b = `.${DATA_KEY$a}`; 838 const EVENT_CLOSE = `close${EVENT_KEY$b}`; 839 const EVENT_CLOSED = `closed${EVENT_KEY$b}`; 840 const CLASS_NAME_FADE$5 = 'fade'; 841 const CLASS_NAME_SHOW$8 = 'show'; 842 843 /** 844 * Class definition 845 */ 846 847 class Alert extends BaseComponent { 848 // Getters 849 static get NAME() { 850 return NAME$f; 851 } 852 853 // Public 854 close() { 855 const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE); 856 if (closeEvent.defaultPrevented) { 857 return; 858 } 859 this._element.classList.remove(CLASS_NAME_SHOW$8); 860 const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5); 861 this._queueCallback(() => this._destroyElement(), this._element, isAnimated); 862 } 863 864 // Private 865 _destroyElement() { 866 this._element.remove(); 867 EventHandler.trigger(this._element, EVENT_CLOSED); 868 this.dispose(); 869 } 870 871 // Static 872 static jQueryInterface(config) { 873 return this.each(function () { 874 const data = Alert.getOrCreateInstance(this); 875 if (typeof config !== 'string') { 876 return; 877 } 878 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 879 throw new TypeError(`No method named "${config}"`); 880 } 881 data[config](this); 882 }); 883 } 884 } 885 886 /** 887 * Data API implementation 888 */ 889 890 enableDismissTrigger(Alert, 'close'); 891 892 /** 893 * jQuery 894 */ 895 896 defineJQueryPlugin(Alert); 897 898 /** 899 * -------------------------------------------------------------------------- 900 * Bootstrap button.js 901 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 902 * -------------------------------------------------------------------------- 903 */ 904 905 906 /** 907 * Constants 908 */ 909 910 const NAME$e = 'button'; 911 const DATA_KEY$9 = 'bs.button'; 912 const EVENT_KEY$a = `.${DATA_KEY$9}`; 913 const DATA_API_KEY$6 = '.data-api'; 914 const CLASS_NAME_ACTIVE$3 = 'active'; 915 const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle="button"]'; 916 const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`; 917 918 /** 919 * Class definition 920 */ 921 922 class Button extends BaseComponent { 923 // Getters 924 static get NAME() { 925 return NAME$e; 926 } 927 928 // Public 929 toggle() { 930 // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method 931 this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3)); 932 } 933 934 // Static 935 static jQueryInterface(config) { 936 return this.each(function () { 937 const data = Button.getOrCreateInstance(this); 938 if (config === 'toggle') { 939 data[config](); 940 } 941 }); 942 } 943 } 944 945 /** 946 * Data API implementation 947 */ 948 949 EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => { 950 event.preventDefault(); 951 const button = event.target.closest(SELECTOR_DATA_TOGGLE$5); 952 const data = Button.getOrCreateInstance(button); 953 data.toggle(); 954 }); 955 956 /** 957 * jQuery 958 */ 959 960 defineJQueryPlugin(Button); 961 962 /** 963 * -------------------------------------------------------------------------- 964 * Bootstrap util/swipe.js 965 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 966 * -------------------------------------------------------------------------- 967 */ 968 969 970 /** 971 * Constants 972 */ 973 974 const NAME$d = 'swipe'; 975 const EVENT_KEY$9 = '.bs.swipe'; 976 const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`; 977 const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`; 978 const EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`; 979 const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`; 980 const EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`; 981 const POINTER_TYPE_TOUCH = 'touch'; 982 const POINTER_TYPE_PEN = 'pen'; 983 const CLASS_NAME_POINTER_EVENT = 'pointer-event'; 984 const SWIPE_THRESHOLD = 40; 985 const Default$c = { 986 endCallback: null, 987 leftCallback: null, 988 rightCallback: null 989 }; 990 const DefaultType$c = { 991 endCallback: '(function|null)', 992 leftCallback: '(function|null)', 993 rightCallback: '(function|null)' 994 }; 995 996 /** 997 * Class definition 998 */ 999 1000 class Swipe extends Config { 1001 constructor(element, config) { 1002 super(); 1003 this._element = element; 1004 if (!element || !Swipe.isSupported()) { 1005 return; 1006 } 1007 this._config = this._getConfig(config); 1008 this._deltaX = 0; 1009 this._supportPointerEvents = Boolean(window.PointerEvent); 1010 this._initEvents(); 1011 } 1012 1013 // Getters 1014 static get Default() { 1015 return Default$c; 1016 } 1017 static get DefaultType() { 1018 return DefaultType$c; 1019 } 1020 static get NAME() { 1021 return NAME$d; 1022 } 1023 1024 // Public 1025 dispose() { 1026 EventHandler.off(this._element, EVENT_KEY$9); 1027 } 1028 1029 // Private 1030 _start(event) { 1031 if (!this._supportPointerEvents) { 1032 this._deltaX = event.touches[0].clientX; 1033 return; 1034 } 1035 if (this._eventIsPointerPenTouch(event)) { 1036 this._deltaX = event.clientX; 1037 } 1038 } 1039 _end(event) { 1040 if (this._eventIsPointerPenTouch(event)) { 1041 this._deltaX = event.clientX - this._deltaX; 1042 } 1043 this._handleSwipe(); 1044 execute(this._config.endCallback); 1045 } 1046 _move(event) { 1047 this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX; 1048 } 1049 _handleSwipe() { 1050 const absDeltaX = Math.abs(this._deltaX); 1051 if (absDeltaX <= SWIPE_THRESHOLD) { 1052 return; 1053 } 1054 const direction = absDeltaX / this._deltaX; 1055 this._deltaX = 0; 1056 if (!direction) { 1057 return; 1058 } 1059 execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback); 1060 } 1061 _initEvents() { 1062 if (this._supportPointerEvents) { 1063 EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event)); 1064 EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event)); 1065 this._element.classList.add(CLASS_NAME_POINTER_EVENT); 1066 } else { 1067 EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event)); 1068 EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event)); 1069 EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event)); 1070 } 1071 } 1072 _eventIsPointerPenTouch(event) { 1073 return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH); 1074 } 1075 1076 // Static 1077 static isSupported() { 1078 return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0; 1079 } 1080 } 1081 1082 /** 1083 * -------------------------------------------------------------------------- 1084 * Bootstrap carousel.js 1085 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 1086 * -------------------------------------------------------------------------- 1087 */ 1088 1089 1090 /** 1091 * Constants 1092 */ 1093 1094 const NAME$c = 'carousel'; 1095 const DATA_KEY$8 = 'bs.carousel'; 1096 const EVENT_KEY$8 = `.${DATA_KEY$8}`; 1097 const DATA_API_KEY$5 = '.data-api'; 1098 const ARROW_LEFT_KEY$1 = 'ArrowLeft'; 1099 const ARROW_RIGHT_KEY$1 = 'ArrowRight'; 1100 const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch 1101 1102 const ORDER_NEXT = 'next'; 1103 const ORDER_PREV = 'prev'; 1104 const DIRECTION_LEFT = 'left'; 1105 const DIRECTION_RIGHT = 'right'; 1106 const EVENT_SLIDE = `slide${EVENT_KEY$8}`; 1107 const EVENT_SLID = `slid${EVENT_KEY$8}`; 1108 const EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`; 1109 const EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`; 1110 const EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`; 1111 const EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`; 1112 const EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`; 1113 const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`; 1114 const CLASS_NAME_CAROUSEL = 'carousel'; 1115 const CLASS_NAME_ACTIVE$2 = 'active'; 1116 const CLASS_NAME_SLIDE = 'slide'; 1117 const CLASS_NAME_END = 'carousel-item-end'; 1118 const CLASS_NAME_START = 'carousel-item-start'; 1119 const CLASS_NAME_NEXT = 'carousel-item-next'; 1120 const CLASS_NAME_PREV = 'carousel-item-prev'; 1121 const SELECTOR_ACTIVE = '.active'; 1122 const SELECTOR_ITEM = '.carousel-item'; 1123 const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM; 1124 const SELECTOR_ITEM_IMG = '.carousel-item img'; 1125 const SELECTOR_INDICATORS = '.carousel-indicators'; 1126 const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'; 1127 const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]'; 1128 const KEY_TO_DIRECTION = { 1129 [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT, 1130 [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT 1131 }; 1132 const Default$b = { 1133 interval: 5000, 1134 keyboard: true, 1135 pause: 'hover', 1136 ride: false, 1137 touch: true, 1138 wrap: true 1139 }; 1140 const DefaultType$b = { 1141 interval: '(number|boolean)', 1142 // TODO:v6 remove boolean support 1143 keyboard: 'boolean', 1144 pause: '(string|boolean)', 1145 ride: '(boolean|string)', 1146 touch: 'boolean', 1147 wrap: 'boolean' 1148 }; 1149 1150 /** 1151 * Class definition 1152 */ 1153 1154 class Carousel extends BaseComponent { 1155 constructor(element, config) { 1156 super(element, config); 1157 this._interval = null; 1158 this._activeElement = null; 1159 this._isSliding = false; 1160 this.touchTimeout = null; 1161 this._swipeHelper = null; 1162 this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element); 1163 this._addEventListeners(); 1164 if (this._config.ride === CLASS_NAME_CAROUSEL) { 1165 this.cycle(); 1166 } 1167 } 1168 1169 // Getters 1170 static get Default() { 1171 return Default$b; 1172 } 1173 static get DefaultType() { 1174 return DefaultType$b; 1175 } 1176 static get NAME() { 1177 return NAME$c; 1178 } 1179 1180 // Public 1181 next() { 1182 this._slide(ORDER_NEXT); 1183 } 1184 nextWhenVisible() { 1185 // FIXME TODO use `document.visibilityState` 1186 // Don't call next when the page isn't visible 1187 // or the carousel or its parent isn't visible 1188 if (!document.hidden && isVisible(this._element)) { 1189 this.next(); 1190 } 1191 } 1192 prev() { 1193 this._slide(ORDER_PREV); 1194 } 1195 pause() { 1196 if (this._isSliding) { 1197 triggerTransitionEnd(this._element); 1198 } 1199 this._clearInterval(); 1200 } 1201 cycle() { 1202 this._clearInterval(); 1203 this._updateInterval(); 1204 this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval); 1205 } 1206 _maybeEnableCycle() { 1207 if (!this._config.ride) { 1208 return; 1209 } 1210 if (this._isSliding) { 1211 EventHandler.one(this._element, EVENT_SLID, () => this.cycle()); 1212 return; 1213 } 1214 this.cycle(); 1215 } 1216 to(index) { 1217 const items = this._getItems(); 1218 if (index > items.length - 1 || index < 0) { 1219 return; 1220 } 1221 if (this._isSliding) { 1222 EventHandler.one(this._element, EVENT_SLID, () => this.to(index)); 1223 return; 1224 } 1225 const activeIndex = this._getItemIndex(this._getActive()); 1226 if (activeIndex === index) { 1227 return; 1228 } 1229 const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV; 1230 this._slide(order, items[index]); 1231 } 1232 dispose() { 1233 if (this._swipeHelper) { 1234 this._swipeHelper.dispose(); 1235 } 1236 super.dispose(); 1237 } 1238 1239 // Private 1240 _configAfterMerge(config) { 1241 config.defaultInterval = config.interval; 1242 return config; 1243 } 1244 _addEventListeners() { 1245 if (this._config.keyboard) { 1246 EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event)); 1247 } 1248 if (this._config.pause === 'hover') { 1249 EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause()); 1250 EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle()); 1251 } 1252 if (this._config.touch && Swipe.isSupported()) { 1253 this._addTouchEventListeners(); 1254 } 1255 } 1256 _addTouchEventListeners() { 1257 for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) { 1258 EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault()); 1259 } 1260 const endCallBack = () => { 1261 if (this._config.pause !== 'hover') { 1262 return; 1263 } 1264 1265 // If it's a touch-enabled device, mouseenter/leave are fired as 1266 // part of the mouse compatibility events on first tap - the carousel 1267 // would stop cycling until user tapped out of it; 1268 // here, we listen for touchend, explicitly pause the carousel 1269 // (as if it's the second time we tap on it, mouseenter compat event 1270 // is NOT fired) and after a timeout (to allow for mouse compatibility 1271 // events to fire) we explicitly restart cycling 1272 1273 this.pause(); 1274 if (this.touchTimeout) { 1275 clearTimeout(this.touchTimeout); 1276 } 1277 this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval); 1278 }; 1279 const swipeConfig = { 1280 leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)), 1281 rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)), 1282 endCallback: endCallBack 1283 }; 1284 this._swipeHelper = new Swipe(this._element, swipeConfig); 1285 } 1286 _keydown(event) { 1287 if (/input|textarea/i.test(event.target.tagName)) { 1288 return; 1289 } 1290 const direction = KEY_TO_DIRECTION[event.key]; 1291 if (direction) { 1292 event.preventDefault(); 1293 this._slide(this._directionToOrder(direction)); 1294 } 1295 } 1296 _getItemIndex(element) { 1297 return this._getItems().indexOf(element); 1298 } 1299 _setActiveIndicatorElement(index) { 1300 if (!this._indicatorsElement) { 1301 return; 1302 } 1303 const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement); 1304 activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2); 1305 activeIndicator.removeAttribute('aria-current'); 1306 const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement); 1307 if (newActiveIndicator) { 1308 newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2); 1309 newActiveIndicator.setAttribute('aria-current', 'true'); 1310 } 1311 } 1312 _updateInterval() { 1313 const element = this._activeElement || this._getActive(); 1314 if (!element) { 1315 return; 1316 } 1317 const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10); 1318 this._config.interval = elementInterval || this._config.defaultInterval; 1319 } 1320 _slide(order, element = null) { 1321 if (this._isSliding) { 1322 return; 1323 } 1324 const activeElement = this._getActive(); 1325 const isNext = order === ORDER_NEXT; 1326 const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap); 1327 if (nextElement === activeElement) { 1328 return; 1329 } 1330 const nextElementIndex = this._getItemIndex(nextElement); 1331 const triggerEvent = eventName => { 1332 return EventHandler.trigger(this._element, eventName, { 1333 relatedTarget: nextElement, 1334 direction: this._orderToDirection(order), 1335 from: this._getItemIndex(activeElement), 1336 to: nextElementIndex 1337 }); 1338 }; 1339 const slideEvent = triggerEvent(EVENT_SLIDE); 1340 if (slideEvent.defaultPrevented) { 1341 return; 1342 } 1343 if (!activeElement || !nextElement) { 1344 // Some weirdness is happening, so we bail 1345 // TODO: change tests that use empty divs to avoid this check 1346 return; 1347 } 1348 const isCycling = Boolean(this._interval); 1349 this.pause(); 1350 this._isSliding = true; 1351 this._setActiveIndicatorElement(nextElementIndex); 1352 this._activeElement = nextElement; 1353 const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END; 1354 const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV; 1355 nextElement.classList.add(orderClassName); 1356 reflow(nextElement); 1357 activeElement.classList.add(directionalClassName); 1358 nextElement.classList.add(directionalClassName); 1359 const completeCallBack = () => { 1360 nextElement.classList.remove(directionalClassName, orderClassName); 1361 nextElement.classList.add(CLASS_NAME_ACTIVE$2); 1362 activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName); 1363 this._isSliding = false; 1364 triggerEvent(EVENT_SLID); 1365 }; 1366 this._queueCallback(completeCallBack, activeElement, this._isAnimated()); 1367 if (isCycling) { 1368 this.cycle(); 1369 } 1370 } 1371 _isAnimated() { 1372 return this._element.classList.contains(CLASS_NAME_SLIDE); 1373 } 1374 _getActive() { 1375 return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element); 1376 } 1377 _getItems() { 1378 return SelectorEngine.find(SELECTOR_ITEM, this._element); 1379 } 1380 _clearInterval() { 1381 if (this._interval) { 1382 clearInterval(this._interval); 1383 this._interval = null; 1384 } 1385 } 1386 _directionToOrder(direction) { 1387 if (isRTL()) { 1388 return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT; 1389 } 1390 return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV; 1391 } 1392 _orderToDirection(order) { 1393 if (isRTL()) { 1394 return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT; 1395 } 1396 return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT; 1397 } 1398 1399 // Static 1400 static jQueryInterface(config) { 1401 return this.each(function () { 1402 const data = Carousel.getOrCreateInstance(this, config); 1403 if (typeof config === 'number') { 1404 data.to(config); 1405 return; 1406 } 1407 if (typeof config === 'string') { 1408 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 1409 throw new TypeError(`No method named "${config}"`); 1410 } 1411 data[config](); 1412 } 1413 }); 1414 } 1415 } 1416 1417 /** 1418 * Data API implementation 1419 */ 1420 1421 EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) { 1422 const target = SelectorEngine.getElementFromSelector(this); 1423 if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) { 1424 return; 1425 } 1426 event.preventDefault(); 1427 const carousel = Carousel.getOrCreateInstance(target); 1428 const slideIndex = this.getAttribute('data-bs-slide-to'); 1429 if (slideIndex) { 1430 carousel.to(slideIndex); 1431 carousel._maybeEnableCycle(); 1432 return; 1433 } 1434 if (Manipulator.getDataAttribute(this, 'slide') === 'next') { 1435 carousel.next(); 1436 carousel._maybeEnableCycle(); 1437 return; 1438 } 1439 carousel.prev(); 1440 carousel._maybeEnableCycle(); 1441 }); 1442 EventHandler.on(window, EVENT_LOAD_DATA_API$3, () => { 1443 const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE); 1444 for (const carousel of carousels) { 1445 Carousel.getOrCreateInstance(carousel); 1446 } 1447 }); 1448 1449 /** 1450 * jQuery 1451 */ 1452 1453 defineJQueryPlugin(Carousel); 1454 1455 /** 1456 * -------------------------------------------------------------------------- 1457 * Bootstrap collapse.js 1458 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 1459 * -------------------------------------------------------------------------- 1460 */ 1461 1462 1463 /** 1464 * Constants 1465 */ 1466 1467 const NAME$b = 'collapse'; 1468 const DATA_KEY$7 = 'bs.collapse'; 1469 const EVENT_KEY$7 = `.${DATA_KEY$7}`; 1470 const DATA_API_KEY$4 = '.data-api'; 1471 const EVENT_SHOW$6 = `show${EVENT_KEY$7}`; 1472 const EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`; 1473 const EVENT_HIDE$6 = `hide${EVENT_KEY$7}`; 1474 const EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`; 1475 const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`; 1476 const CLASS_NAME_SHOW$7 = 'show'; 1477 const CLASS_NAME_COLLAPSE = 'collapse'; 1478 const CLASS_NAME_COLLAPSING = 'collapsing'; 1479 const CLASS_NAME_COLLAPSED = 'collapsed'; 1480 const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`; 1481 const CLASS_NAME_HORIZONTAL = 'collapse-horizontal'; 1482 const WIDTH = 'width'; 1483 const HEIGHT = 'height'; 1484 const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing'; 1485 const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle="collapse"]'; 1486 const Default$a = { 1487 parent: null, 1488 toggle: true 1489 }; 1490 const DefaultType$a = { 1491 parent: '(null|element)', 1492 toggle: 'boolean' 1493 }; 1494 1495 /** 1496 * Class definition 1497 */ 1498 1499 class Collapse extends BaseComponent { 1500 constructor(element, config) { 1501 super(element, config); 1502 this._isTransitioning = false; 1503 this._triggerArray = []; 1504 const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4); 1505 for (const elem of toggleList) { 1506 const selector = SelectorEngine.getSelectorFromElement(elem); 1507 const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element); 1508 if (selector !== null && filterElement.length) { 1509 this._triggerArray.push(elem); 1510 } 1511 } 1512 this._initializeChildren(); 1513 if (!this._config.parent) { 1514 this._addAriaAndCollapsedClass(this._triggerArray, this._isShown()); 1515 } 1516 if (this._config.toggle) { 1517 this.toggle(); 1518 } 1519 } 1520 1521 // Getters 1522 static get Default() { 1523 return Default$a; 1524 } 1525 static get DefaultType() { 1526 return DefaultType$a; 1527 } 1528 static get NAME() { 1529 return NAME$b; 1530 } 1531 1532 // Public 1533 toggle() { 1534 if (this._isShown()) { 1535 this.hide(); 1536 } else { 1537 this.show(); 1538 } 1539 } 1540 show() { 1541 if (this._isTransitioning || this._isShown()) { 1542 return; 1543 } 1544 let activeChildren = []; 1545 1546 // find active children 1547 if (this._config.parent) { 1548 activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, { 1549 toggle: false 1550 })); 1551 } 1552 if (activeChildren.length && activeChildren[0]._isTransitioning) { 1553 return; 1554 } 1555 const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6); 1556 if (startEvent.defaultPrevented) { 1557 return; 1558 } 1559 for (const activeInstance of activeChildren) { 1560 activeInstance.hide(); 1561 } 1562 const dimension = this._getDimension(); 1563 this._element.classList.remove(CLASS_NAME_COLLAPSE); 1564 this._element.classList.add(CLASS_NAME_COLLAPSING); 1565 this._element.style[dimension] = 0; 1566 this._addAriaAndCollapsedClass(this._triggerArray, true); 1567 this._isTransitioning = true; 1568 const complete = () => { 1569 this._isTransitioning = false; 1570 this._element.classList.remove(CLASS_NAME_COLLAPSING); 1571 this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7); 1572 this._element.style[dimension] = ''; 1573 EventHandler.trigger(this._element, EVENT_SHOWN$6); 1574 }; 1575 const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); 1576 const scrollSize = `scroll${capitalizedDimension}`; 1577 this._queueCallback(complete, this._element, true); 1578 this._element.style[dimension] = `${this._element[scrollSize]}px`; 1579 } 1580 hide() { 1581 if (this._isTransitioning || !this._isShown()) { 1582 return; 1583 } 1584 const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6); 1585 if (startEvent.defaultPrevented) { 1586 return; 1587 } 1588 const dimension = this._getDimension(); 1589 this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`; 1590 reflow(this._element); 1591 this._element.classList.add(CLASS_NAME_COLLAPSING); 1592 this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7); 1593 for (const trigger of this._triggerArray) { 1594 const element = SelectorEngine.getElementFromSelector(trigger); 1595 if (element && !this._isShown(element)) { 1596 this._addAriaAndCollapsedClass([trigger], false); 1597 } 1598 } 1599 this._isTransitioning = true; 1600 const complete = () => { 1601 this._isTransitioning = false; 1602 this._element.classList.remove(CLASS_NAME_COLLAPSING); 1603 this._element.classList.add(CLASS_NAME_COLLAPSE); 1604 EventHandler.trigger(this._element, EVENT_HIDDEN$6); 1605 }; 1606 this._element.style[dimension] = ''; 1607 this._queueCallback(complete, this._element, true); 1608 } 1609 1610 // Private 1611 _isShown(element = this._element) { 1612 return element.classList.contains(CLASS_NAME_SHOW$7); 1613 } 1614 _configAfterMerge(config) { 1615 config.toggle = Boolean(config.toggle); // Coerce string values 1616 config.parent = getElement(config.parent); 1617 return config; 1618 } 1619 _getDimension() { 1620 return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT; 1621 } 1622 _initializeChildren() { 1623 if (!this._config.parent) { 1624 return; 1625 } 1626 const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4); 1627 for (const element of children) { 1628 const selected = SelectorEngine.getElementFromSelector(element); 1629 if (selected) { 1630 this._addAriaAndCollapsedClass([element], this._isShown(selected)); 1631 } 1632 } 1633 } 1634 _getFirstLevelChildren(selector) { 1635 const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent); 1636 // remove children if greater depth 1637 return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element)); 1638 } 1639 _addAriaAndCollapsedClass(triggerArray, isOpen) { 1640 if (!triggerArray.length) { 1641 return; 1642 } 1643 for (const element of triggerArray) { 1644 element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen); 1645 element.setAttribute('aria-expanded', isOpen); 1646 } 1647 } 1648 1649 // Static 1650 static jQueryInterface(config) { 1651 const _config = {}; 1652 if (typeof config === 'string' && /show|hide/.test(config)) { 1653 _config.toggle = false; 1654 } 1655 return this.each(function () { 1656 const data = Collapse.getOrCreateInstance(this, _config); 1657 if (typeof config === 'string') { 1658 if (typeof data[config] === 'undefined') { 1659 throw new TypeError(`No method named "${config}"`); 1660 } 1661 data[config](); 1662 } 1663 }); 1664 } 1665 } 1666 1667 /** 1668 * Data API implementation 1669 */ 1670 1671 EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) { 1672 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element 1673 if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') { 1674 event.preventDefault(); 1675 } 1676 for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) { 1677 Collapse.getOrCreateInstance(element, { 1678 toggle: false 1679 }).toggle(); 1680 } 1681 }); 1682 1683 /** 1684 * jQuery 1685 */ 1686 1687 defineJQueryPlugin(Collapse); 1688 1689 var top = 'top'; 1690 var bottom = 'bottom'; 1691 var right = 'right'; 1692 var left = 'left'; 1693 var auto = 'auto'; 1694 var basePlacements = [top, bottom, right, left]; 1695 var start = 'start'; 1696 var end = 'end'; 1697 var clippingParents = 'clippingParents'; 1698 var viewport = 'viewport'; 1699 var popper = 'popper'; 1700 var reference = 'reference'; 1701 var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) { 1702 return acc.concat([placement + "-" + start, placement + "-" + end]); 1703 }, []); 1704 var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) { 1705 return acc.concat([placement, placement + "-" + start, placement + "-" + end]); 1706 }, []); // modifiers that need to read the DOM 1707 1708 var beforeRead = 'beforeRead'; 1709 var read = 'read'; 1710 var afterRead = 'afterRead'; // pure-logic modifiers 1711 1712 var beforeMain = 'beforeMain'; 1713 var main = 'main'; 1714 var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state) 1715 1716 var beforeWrite = 'beforeWrite'; 1717 var write = 'write'; 1718 var afterWrite = 'afterWrite'; 1719 var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; 1720 1721 function getNodeName(element) { 1722 return element ? (element.nodeName || '').toLowerCase() : null; 1723 } 1724 1725 function getWindow(node) { 1726 if (node == null) { 1727 return window; 1728 } 1729 1730 if (node.toString() !== '[object Window]') { 1731 var ownerDocument = node.ownerDocument; 1732 return ownerDocument ? ownerDocument.defaultView || window : window; 1733 } 1734 1735 return node; 1736 } 1737 1738 function isElement(node) { 1739 var OwnElement = getWindow(node).Element; 1740 return node instanceof OwnElement || node instanceof Element; 1741 } 1742 1743 function isHTMLElement(node) { 1744 var OwnElement = getWindow(node).HTMLElement; 1745 return node instanceof OwnElement || node instanceof HTMLElement; 1746 } 1747 1748 function isShadowRoot(node) { 1749 // IE 11 has no ShadowRoot 1750 if (typeof ShadowRoot === 'undefined') { 1751 return false; 1752 } 1753 1754 var OwnElement = getWindow(node).ShadowRoot; 1755 return node instanceof OwnElement || node instanceof ShadowRoot; 1756 } 1757 1758 // and applies them to the HTMLElements such as popper and arrow 1759 1760 function applyStyles(_ref) { 1761 var state = _ref.state; 1762 Object.keys(state.elements).forEach(function (name) { 1763 var style = state.styles[name] || {}; 1764 var attributes = state.attributes[name] || {}; 1765 var element = state.elements[name]; // arrow is optional + virtual elements 1766 1767 if (!isHTMLElement(element) || !getNodeName(element)) { 1768 return; 1769 } // Flow doesn't support to extend this property, but it's the most 1770 // effective way to apply styles to an HTMLElement 1771 // $FlowFixMe[cannot-write] 1772 1773 1774 Object.assign(element.style, style); 1775 Object.keys(attributes).forEach(function (name) { 1776 var value = attributes[name]; 1777 1778 if (value === false) { 1779 element.removeAttribute(name); 1780 } else { 1781 element.setAttribute(name, value === true ? '' : value); 1782 } 1783 }); 1784 }); 1785 } 1786 1787 function effect$2(_ref2) { 1788 var state = _ref2.state; 1789 var initialStyles = { 1790 popper: { 1791 position: state.options.strategy, 1792 left: '0', 1793 top: '0', 1794 margin: '0' 1795 }, 1796 arrow: { 1797 position: 'absolute' 1798 }, 1799 reference: {} 1800 }; 1801 Object.assign(state.elements.popper.style, initialStyles.popper); 1802 state.styles = initialStyles; 1803 1804 if (state.elements.arrow) { 1805 Object.assign(state.elements.arrow.style, initialStyles.arrow); 1806 } 1807 1808 return function () { 1809 Object.keys(state.elements).forEach(function (name) { 1810 var element = state.elements[name]; 1811 var attributes = state.attributes[name] || {}; 1812 var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them 1813 1814 var style = styleProperties.reduce(function (style, property) { 1815 style[property] = ''; 1816 return style; 1817 }, {}); // arrow is optional + virtual elements 1818 1819 if (!isHTMLElement(element) || !getNodeName(element)) { 1820 return; 1821 } 1822 1823 Object.assign(element.style, style); 1824 Object.keys(attributes).forEach(function (attribute) { 1825 element.removeAttribute(attribute); 1826 }); 1827 }); 1828 }; 1829 } // eslint-disable-next-line import/no-unused-modules 1830 1831 1832 const applyStyles$1 = { 1833 name: 'applyStyles', 1834 enabled: true, 1835 phase: 'write', 1836 fn: applyStyles, 1837 effect: effect$2, 1838 requires: ['computeStyles'] 1839 }; 1840 1841 function getBasePlacement(placement) { 1842 return placement.split('-')[0]; 1843 } 1844 1845 var max = Math.max; 1846 var min = Math.min; 1847 var round = Math.round; 1848 1849 function getUAString() { 1850 var uaData = navigator.userAgentData; 1851 1852 if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) { 1853 return uaData.brands.map(function (item) { 1854 return item.brand + "/" + item.version; 1855 }).join(' '); 1856 } 1857 1858 return navigator.userAgent; 1859 } 1860 1861 function isLayoutViewport() { 1862 return !/^((?!chrome|android).)*safari/i.test(getUAString()); 1863 } 1864 1865 function getBoundingClientRect(element, includeScale, isFixedStrategy) { 1866 if (includeScale === void 0) { 1867 includeScale = false; 1868 } 1869 1870 if (isFixedStrategy === void 0) { 1871 isFixedStrategy = false; 1872 } 1873 1874 var clientRect = element.getBoundingClientRect(); 1875 var scaleX = 1; 1876 var scaleY = 1; 1877 1878 if (includeScale && isHTMLElement(element)) { 1879 scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1; 1880 scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1; 1881 } 1882 1883 var _ref = isElement(element) ? getWindow(element) : window, 1884 visualViewport = _ref.visualViewport; 1885 1886 var addVisualOffsets = !isLayoutViewport() && isFixedStrategy; 1887 var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX; 1888 var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY; 1889 var width = clientRect.width / scaleX; 1890 var height = clientRect.height / scaleY; 1891 return { 1892 width: width, 1893 height: height, 1894 top: y, 1895 right: x + width, 1896 bottom: y + height, 1897 left: x, 1898 x: x, 1899 y: y 1900 }; 1901 } 1902 1903 // means it doesn't take into account transforms. 1904 1905 function getLayoutRect(element) { 1906 var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed. 1907 // Fixes https://github.com/popperjs/popper-core/issues/1223 1908 1909 var width = element.offsetWidth; 1910 var height = element.offsetHeight; 1911 1912 if (Math.abs(clientRect.width - width) <= 1) { 1913 width = clientRect.width; 1914 } 1915 1916 if (Math.abs(clientRect.height - height) <= 1) { 1917 height = clientRect.height; 1918 } 1919 1920 return { 1921 x: element.offsetLeft, 1922 y: element.offsetTop, 1923 width: width, 1924 height: height 1925 }; 1926 } 1927 1928 function contains(parent, child) { 1929 var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method 1930 1931 if (parent.contains(child)) { 1932 return true; 1933 } // then fallback to custom implementation with Shadow DOM support 1934 else if (rootNode && isShadowRoot(rootNode)) { 1935 var next = child; 1936 1937 do { 1938 if (next && parent.isSameNode(next)) { 1939 return true; 1940 } // $FlowFixMe[prop-missing]: need a better way to handle this... 1941 1942 1943 next = next.parentNode || next.host; 1944 } while (next); 1945 } // Give up, the result is false 1946 1947 1948 return false; 1949 } 1950 1951 function getComputedStyle$1(element) { 1952 return getWindow(element).getComputedStyle(element); 1953 } 1954 1955 function isTableElement(element) { 1956 return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0; 1957 } 1958 1959 function getDocumentElement(element) { 1960 // $FlowFixMe[incompatible-return]: assume body is always available 1961 return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing] 1962 element.document) || window.document).documentElement; 1963 } 1964 1965 function getParentNode(element) { 1966 if (getNodeName(element) === 'html') { 1967 return element; 1968 } 1969 1970 return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle 1971 // $FlowFixMe[incompatible-return] 1972 // $FlowFixMe[prop-missing] 1973 element.assignedSlot || // step into the shadow DOM of the parent of a slotted node 1974 element.parentNode || ( // DOM Element detected 1975 isShadowRoot(element) ? element.host : null) || // ShadowRoot detected 1976 // $FlowFixMe[incompatible-call]: HTMLElement is a Node 1977 getDocumentElement(element) // fallback 1978 1979 ); 1980 } 1981 1982 function getTrueOffsetParent(element) { 1983 if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 1984 getComputedStyle$1(element).position === 'fixed') { 1985 return null; 1986 } 1987 1988 return element.offsetParent; 1989 } // `.offsetParent` reports `null` for fixed elements, while absolute elements 1990 // return the containing block 1991 1992 1993 function getContainingBlock(element) { 1994 var isFirefox = /firefox/i.test(getUAString()); 1995 var isIE = /Trident/i.test(getUAString()); 1996 1997 if (isIE && isHTMLElement(element)) { 1998 // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport 1999 var elementCss = getComputedStyle$1(element); 2000 2001 if (elementCss.position === 'fixed') { 2002 return null; 2003 } 2004 } 2005 2006 var currentNode = getParentNode(element); 2007 2008 if (isShadowRoot(currentNode)) { 2009 currentNode = currentNode.host; 2010 } 2011 2012 while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) { 2013 var css = getComputedStyle$1(currentNode); // This is non-exhaustive but covers the most common CSS properties that 2014 // create a containing block. 2015 // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block 2016 2017 if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') { 2018 return currentNode; 2019 } else { 2020 currentNode = currentNode.parentNode; 2021 } 2022 } 2023 2024 return null; 2025 } // Gets the closest ancestor positioned element. Handles some edge cases, 2026 // such as table ancestors and cross browser bugs. 2027 2028 2029 function getOffsetParent(element) { 2030 var window = getWindow(element); 2031 var offsetParent = getTrueOffsetParent(element); 2032 2033 while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') { 2034 offsetParent = getTrueOffsetParent(offsetParent); 2035 } 2036 2037 if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static')) { 2038 return window; 2039 } 2040 2041 return offsetParent || getContainingBlock(element) || window; 2042 } 2043 2044 function getMainAxisFromPlacement(placement) { 2045 return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y'; 2046 } 2047 2048 function within(min$1, value, max$1) { 2049 return max(min$1, min(value, max$1)); 2050 } 2051 function withinMaxClamp(min, value, max) { 2052 var v = within(min, value, max); 2053 return v > max ? max : v; 2054 } 2055 2056 function getFreshSideObject() { 2057 return { 2058 top: 0, 2059 right: 0, 2060 bottom: 0, 2061 left: 0 2062 }; 2063 } 2064 2065 function mergePaddingObject(paddingObject) { 2066 return Object.assign({}, getFreshSideObject(), paddingObject); 2067 } 2068 2069 function expandToHashMap(value, keys) { 2070 return keys.reduce(function (hashMap, key) { 2071 hashMap[key] = value; 2072 return hashMap; 2073 }, {}); 2074 } 2075 2076 var toPaddingObject = function toPaddingObject(padding, state) { 2077 padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, { 2078 placement: state.placement 2079 })) : padding; 2080 return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); 2081 }; 2082 2083 function arrow(_ref) { 2084 var _state$modifiersData$; 2085 2086 var state = _ref.state, 2087 name = _ref.name, 2088 options = _ref.options; 2089 var arrowElement = state.elements.arrow; 2090 var popperOffsets = state.modifiersData.popperOffsets; 2091 var basePlacement = getBasePlacement(state.placement); 2092 var axis = getMainAxisFromPlacement(basePlacement); 2093 var isVertical = [left, right].indexOf(basePlacement) >= 0; 2094 var len = isVertical ? 'height' : 'width'; 2095 2096 if (!arrowElement || !popperOffsets) { 2097 return; 2098 } 2099 2100 var paddingObject = toPaddingObject(options.padding, state); 2101 var arrowRect = getLayoutRect(arrowElement); 2102 var minProp = axis === 'y' ? top : left; 2103 var maxProp = axis === 'y' ? bottom : right; 2104 var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len]; 2105 var startDiff = popperOffsets[axis] - state.rects.reference[axis]; 2106 var arrowOffsetParent = getOffsetParent(arrowElement); 2107 var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; 2108 var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is 2109 // outside of the popper bounds 2110 2111 var min = paddingObject[minProp]; 2112 var max = clientSize - arrowRect[len] - paddingObject[maxProp]; 2113 var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; 2114 var offset = within(min, center, max); // Prevents breaking syntax highlighting... 2115 2116 var axisProp = axis; 2117 state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$); 2118 } 2119 2120 function effect$1(_ref2) { 2121 var state = _ref2.state, 2122 options = _ref2.options; 2123 var _options$element = options.element, 2124 arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element; 2125 2126 if (arrowElement == null) { 2127 return; 2128 } // CSS selector 2129 2130 2131 if (typeof arrowElement === 'string') { 2132 arrowElement = state.elements.popper.querySelector(arrowElement); 2133 2134 if (!arrowElement) { 2135 return; 2136 } 2137 } 2138 2139 if (!contains(state.elements.popper, arrowElement)) { 2140 return; 2141 } 2142 2143 state.elements.arrow = arrowElement; 2144 } // eslint-disable-next-line import/no-unused-modules 2145 2146 2147 const arrow$1 = { 2148 name: 'arrow', 2149 enabled: true, 2150 phase: 'main', 2151 fn: arrow, 2152 effect: effect$1, 2153 requires: ['popperOffsets'], 2154 requiresIfExists: ['preventOverflow'] 2155 }; 2156 2157 function getVariation(placement) { 2158 return placement.split('-')[1]; 2159 } 2160 2161 var unsetSides = { 2162 top: 'auto', 2163 right: 'auto', 2164 bottom: 'auto', 2165 left: 'auto' 2166 }; // Round the offsets to the nearest suitable subpixel based on the DPR. 2167 // Zooming can change the DPR, but it seems to report a value that will 2168 // cleanly divide the values into the appropriate subpixels. 2169 2170 function roundOffsetsByDPR(_ref, win) { 2171 var x = _ref.x, 2172 y = _ref.y; 2173 var dpr = win.devicePixelRatio || 1; 2174 return { 2175 x: round(x * dpr) / dpr || 0, 2176 y: round(y * dpr) / dpr || 0 2177 }; 2178 } 2179 2180 function mapToStyles(_ref2) { 2181 var _Object$assign2; 2182 2183 var popper = _ref2.popper, 2184 popperRect = _ref2.popperRect, 2185 placement = _ref2.placement, 2186 variation = _ref2.variation, 2187 offsets = _ref2.offsets, 2188 position = _ref2.position, 2189 gpuAcceleration = _ref2.gpuAcceleration, 2190 adaptive = _ref2.adaptive, 2191 roundOffsets = _ref2.roundOffsets, 2192 isFixed = _ref2.isFixed; 2193 var _offsets$x = offsets.x, 2194 x = _offsets$x === void 0 ? 0 : _offsets$x, 2195 _offsets$y = offsets.y, 2196 y = _offsets$y === void 0 ? 0 : _offsets$y; 2197 2198 var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({ 2199 x: x, 2200 y: y 2201 }) : { 2202 x: x, 2203 y: y 2204 }; 2205 2206 x = _ref3.x; 2207 y = _ref3.y; 2208 var hasX = offsets.hasOwnProperty('x'); 2209 var hasY = offsets.hasOwnProperty('y'); 2210 var sideX = left; 2211 var sideY = top; 2212 var win = window; 2213 2214 if (adaptive) { 2215 var offsetParent = getOffsetParent(popper); 2216 var heightProp = 'clientHeight'; 2217 var widthProp = 'clientWidth'; 2218 2219 if (offsetParent === getWindow(popper)) { 2220 offsetParent = getDocumentElement(popper); 2221 2222 if (getComputedStyle$1(offsetParent).position !== 'static' && position === 'absolute') { 2223 heightProp = 'scrollHeight'; 2224 widthProp = 'scrollWidth'; 2225 } 2226 } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it 2227 2228 2229 offsetParent = offsetParent; 2230 2231 if (placement === top || (placement === left || placement === right) && variation === end) { 2232 sideY = bottom; 2233 var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing] 2234 offsetParent[heightProp]; 2235 y -= offsetY - popperRect.height; 2236 y *= gpuAcceleration ? 1 : -1; 2237 } 2238 2239 if (placement === left || (placement === top || placement === bottom) && variation === end) { 2240 sideX = right; 2241 var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing] 2242 offsetParent[widthProp]; 2243 x -= offsetX - popperRect.width; 2244 x *= gpuAcceleration ? 1 : -1; 2245 } 2246 } 2247 2248 var commonStyles = Object.assign({ 2249 position: position 2250 }, adaptive && unsetSides); 2251 2252 var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ 2253 x: x, 2254 y: y 2255 }, getWindow(popper)) : { 2256 x: x, 2257 y: y 2258 }; 2259 2260 x = _ref4.x; 2261 y = _ref4.y; 2262 2263 if (gpuAcceleration) { 2264 var _Object$assign; 2265 2266 return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); 2267 } 2268 2269 return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2)); 2270 } 2271 2272 function computeStyles(_ref5) { 2273 var state = _ref5.state, 2274 options = _ref5.options; 2275 var _options$gpuAccelerat = options.gpuAcceleration, 2276 gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, 2277 _options$adaptive = options.adaptive, 2278 adaptive = _options$adaptive === void 0 ? true : _options$adaptive, 2279 _options$roundOffsets = options.roundOffsets, 2280 roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; 2281 var commonStyles = { 2282 placement: getBasePlacement(state.placement), 2283 variation: getVariation(state.placement), 2284 popper: state.elements.popper, 2285 popperRect: state.rects.popper, 2286 gpuAcceleration: gpuAcceleration, 2287 isFixed: state.options.strategy === 'fixed' 2288 }; 2289 2290 if (state.modifiersData.popperOffsets != null) { 2291 state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { 2292 offsets: state.modifiersData.popperOffsets, 2293 position: state.options.strategy, 2294 adaptive: adaptive, 2295 roundOffsets: roundOffsets 2296 }))); 2297 } 2298 2299 if (state.modifiersData.arrow != null) { 2300 state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { 2301 offsets: state.modifiersData.arrow, 2302 position: 'absolute', 2303 adaptive: false, 2304 roundOffsets: roundOffsets 2305 }))); 2306 } 2307 2308 state.attributes.popper = Object.assign({}, state.attributes.popper, { 2309 'data-popper-placement': state.placement 2310 }); 2311 } // eslint-disable-next-line import/no-unused-modules 2312 2313 2314 const computeStyles$1 = { 2315 name: 'computeStyles', 2316 enabled: true, 2317 phase: 'beforeWrite', 2318 fn: computeStyles, 2319 data: {} 2320 }; 2321 2322 var passive = { 2323 passive: true 2324 }; 2325 2326 function effect(_ref) { 2327 var state = _ref.state, 2328 instance = _ref.instance, 2329 options = _ref.options; 2330 var _options$scroll = options.scroll, 2331 scroll = _options$scroll === void 0 ? true : _options$scroll, 2332 _options$resize = options.resize, 2333 resize = _options$resize === void 0 ? true : _options$resize; 2334 var window = getWindow(state.elements.popper); 2335 var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); 2336 2337 if (scroll) { 2338 scrollParents.forEach(function (scrollParent) { 2339 scrollParent.addEventListener('scroll', instance.update, passive); 2340 }); 2341 } 2342 2343 if (resize) { 2344 window.addEventListener('resize', instance.update, passive); 2345 } 2346 2347 return function () { 2348 if (scroll) { 2349 scrollParents.forEach(function (scrollParent) { 2350 scrollParent.removeEventListener('scroll', instance.update, passive); 2351 }); 2352 } 2353 2354 if (resize) { 2355 window.removeEventListener('resize', instance.update, passive); 2356 } 2357 }; 2358 } // eslint-disable-next-line import/no-unused-modules 2359 2360 2361 const eventListeners = { 2362 name: 'eventListeners', 2363 enabled: true, 2364 phase: 'write', 2365 fn: function fn() {}, 2366 effect: effect, 2367 data: {} 2368 }; 2369 2370 var hash$1 = { 2371 left: 'right', 2372 right: 'left', 2373 bottom: 'top', 2374 top: 'bottom' 2375 }; 2376 function getOppositePlacement(placement) { 2377 return placement.replace(/left|right|bottom|top/g, function (matched) { 2378 return hash$1[matched]; 2379 }); 2380 } 2381 2382 var hash = { 2383 start: 'end', 2384 end: 'start' 2385 }; 2386 function getOppositeVariationPlacement(placement) { 2387 return placement.replace(/start|end/g, function (matched) { 2388 return hash[matched]; 2389 }); 2390 } 2391 2392 function getWindowScroll(node) { 2393 var win = getWindow(node); 2394 var scrollLeft = win.pageXOffset; 2395 var scrollTop = win.pageYOffset; 2396 return { 2397 scrollLeft: scrollLeft, 2398 scrollTop: scrollTop 2399 }; 2400 } 2401 2402 function getWindowScrollBarX(element) { 2403 // If <html> has a CSS width greater than the viewport, then this will be 2404 // incorrect for RTL. 2405 // Popper 1 is broken in this case and never had a bug report so let's assume 2406 // it's not an issue. I don't think anyone ever specifies width on <html> 2407 // anyway. 2408 // Browsers where the left scrollbar doesn't cause an issue report `0` for 2409 // this (e.g. Edge 2019, IE11, Safari) 2410 return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; 2411 } 2412 2413 function getViewportRect(element, strategy) { 2414 var win = getWindow(element); 2415 var html = getDocumentElement(element); 2416 var visualViewport = win.visualViewport; 2417 var width = html.clientWidth; 2418 var height = html.clientHeight; 2419 var x = 0; 2420 var y = 0; 2421 2422 if (visualViewport) { 2423 width = visualViewport.width; 2424 height = visualViewport.height; 2425 var layoutViewport = isLayoutViewport(); 2426 2427 if (layoutViewport || !layoutViewport && strategy === 'fixed') { 2428 x = visualViewport.offsetLeft; 2429 y = visualViewport.offsetTop; 2430 } 2431 } 2432 2433 return { 2434 width: width, 2435 height: height, 2436 x: x + getWindowScrollBarX(element), 2437 y: y 2438 }; 2439 } 2440 2441 // of the `<html>` and `<body>` rect bounds if horizontally scrollable 2442 2443 function getDocumentRect(element) { 2444 var _element$ownerDocumen; 2445 2446 var html = getDocumentElement(element); 2447 var winScroll = getWindowScroll(element); 2448 var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; 2449 var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); 2450 var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); 2451 var x = -winScroll.scrollLeft + getWindowScrollBarX(element); 2452 var y = -winScroll.scrollTop; 2453 2454 if (getComputedStyle$1(body || html).direction === 'rtl') { 2455 x += max(html.clientWidth, body ? body.clientWidth : 0) - width; 2456 } 2457 2458 return { 2459 width: width, 2460 height: height, 2461 x: x, 2462 y: y 2463 }; 2464 } 2465 2466 function isScrollParent(element) { 2467 // Firefox wants us to check `-x` and `-y` variations as well 2468 var _getComputedStyle = getComputedStyle$1(element), 2469 overflow = _getComputedStyle.overflow, 2470 overflowX = _getComputedStyle.overflowX, 2471 overflowY = _getComputedStyle.overflowY; 2472 2473 return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); 2474 } 2475 2476 function getScrollParent(node) { 2477 if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) { 2478 // $FlowFixMe[incompatible-return]: assume body is always available 2479 return node.ownerDocument.body; 2480 } 2481 2482 if (isHTMLElement(node) && isScrollParent(node)) { 2483 return node; 2484 } 2485 2486 return getScrollParent(getParentNode(node)); 2487 } 2488 2489 /* 2490 given a DOM element, return the list of all scroll parents, up the list of ancesors 2491 until we get to the top window object. This list is what we attach scroll listeners 2492 to, because if any of these parent elements scroll, we'll need to re-calculate the 2493 reference element's position. 2494 */ 2495 2496 function listScrollParents(element, list) { 2497 var _element$ownerDocumen; 2498 2499 if (list === void 0) { 2500 list = []; 2501 } 2502 2503 var scrollParent = getScrollParent(element); 2504 var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); 2505 var win = getWindow(scrollParent); 2506 var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; 2507 var updatedList = list.concat(target); 2508 return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here 2509 updatedList.concat(listScrollParents(getParentNode(target))); 2510 } 2511 2512 function rectToClientRect(rect) { 2513 return Object.assign({}, rect, { 2514 left: rect.x, 2515 top: rect.y, 2516 right: rect.x + rect.width, 2517 bottom: rect.y + rect.height 2518 }); 2519 } 2520 2521 function getInnerBoundingClientRect(element, strategy) { 2522 var rect = getBoundingClientRect(element, false, strategy === 'fixed'); 2523 rect.top = rect.top + element.clientTop; 2524 rect.left = rect.left + element.clientLeft; 2525 rect.bottom = rect.top + element.clientHeight; 2526 rect.right = rect.left + element.clientWidth; 2527 rect.width = element.clientWidth; 2528 rect.height = element.clientHeight; 2529 rect.x = rect.left; 2530 rect.y = rect.top; 2531 return rect; 2532 } 2533 2534 function getClientRectFromMixedType(element, clippingParent, strategy) { 2535 return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element))); 2536 } // A "clipping parent" is an overflowable container with the characteristic of 2537 // clipping (or hiding) overflowing elements with a position different from 2538 // `initial` 2539 2540 2541 function getClippingParents(element) { 2542 var clippingParents = listScrollParents(getParentNode(element)); 2543 var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle$1(element).position) >= 0; 2544 var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; 2545 2546 if (!isElement(clipperElement)) { 2547 return []; 2548 } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414 2549 2550 2551 return clippingParents.filter(function (clippingParent) { 2552 return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body'; 2553 }); 2554 } // Gets the maximum area that the element is visible in due to any number of 2555 // clipping parents 2556 2557 2558 function getClippingRect(element, boundary, rootBoundary, strategy) { 2559 var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary); 2560 var clippingParents = [].concat(mainClippingParents, [rootBoundary]); 2561 var firstClippingParent = clippingParents[0]; 2562 var clippingRect = clippingParents.reduce(function (accRect, clippingParent) { 2563 var rect = getClientRectFromMixedType(element, clippingParent, strategy); 2564 accRect.top = max(rect.top, accRect.top); 2565 accRect.right = min(rect.right, accRect.right); 2566 accRect.bottom = min(rect.bottom, accRect.bottom); 2567 accRect.left = max(rect.left, accRect.left); 2568 return accRect; 2569 }, getClientRectFromMixedType(element, firstClippingParent, strategy)); 2570 clippingRect.width = clippingRect.right - clippingRect.left; 2571 clippingRect.height = clippingRect.bottom - clippingRect.top; 2572 clippingRect.x = clippingRect.left; 2573 clippingRect.y = clippingRect.top; 2574 return clippingRect; 2575 } 2576 2577 function computeOffsets(_ref) { 2578 var reference = _ref.reference, 2579 element = _ref.element, 2580 placement = _ref.placement; 2581 var basePlacement = placement ? getBasePlacement(placement) : null; 2582 var variation = placement ? getVariation(placement) : null; 2583 var commonX = reference.x + reference.width / 2 - element.width / 2; 2584 var commonY = reference.y + reference.height / 2 - element.height / 2; 2585 var offsets; 2586 2587 switch (basePlacement) { 2588 case top: 2589 offsets = { 2590 x: commonX, 2591 y: reference.y - element.height 2592 }; 2593 break; 2594 2595 case bottom: 2596 offsets = { 2597 x: commonX, 2598 y: reference.y + reference.height 2599 }; 2600 break; 2601 2602 case right: 2603 offsets = { 2604 x: reference.x + reference.width, 2605 y: commonY 2606 }; 2607 break; 2608 2609 case left: 2610 offsets = { 2611 x: reference.x - element.width, 2612 y: commonY 2613 }; 2614 break; 2615 2616 default: 2617 offsets = { 2618 x: reference.x, 2619 y: reference.y 2620 }; 2621 } 2622 2623 var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; 2624 2625 if (mainAxis != null) { 2626 var len = mainAxis === 'y' ? 'height' : 'width'; 2627 2628 switch (variation) { 2629 case start: 2630 offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2); 2631 break; 2632 2633 case end: 2634 offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2); 2635 break; 2636 } 2637 } 2638 2639 return offsets; 2640 } 2641 2642 function detectOverflow(state, options) { 2643 if (options === void 0) { 2644 options = {}; 2645 } 2646 2647 var _options = options, 2648 _options$placement = _options.placement, 2649 placement = _options$placement === void 0 ? state.placement : _options$placement, 2650 _options$strategy = _options.strategy, 2651 strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, 2652 _options$boundary = _options.boundary, 2653 boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, 2654 _options$rootBoundary = _options.rootBoundary, 2655 rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, 2656 _options$elementConte = _options.elementContext, 2657 elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, 2658 _options$altBoundary = _options.altBoundary, 2659 altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, 2660 _options$padding = _options.padding, 2661 padding = _options$padding === void 0 ? 0 : _options$padding; 2662 var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); 2663 var altContext = elementContext === popper ? reference : popper; 2664 var popperRect = state.rects.popper; 2665 var element = state.elements[altBoundary ? altContext : elementContext]; 2666 var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy); 2667 var referenceClientRect = getBoundingClientRect(state.elements.reference); 2668 var popperOffsets = computeOffsets({ 2669 reference: referenceClientRect, 2670 element: popperRect, 2671 placement: placement 2672 }); 2673 var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets)); 2674 var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect 2675 // 0 or negative = within the clipping rect 2676 2677 var overflowOffsets = { 2678 top: clippingClientRect.top - elementClientRect.top + paddingObject.top, 2679 bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, 2680 left: clippingClientRect.left - elementClientRect.left + paddingObject.left, 2681 right: elementClientRect.right - clippingClientRect.right + paddingObject.right 2682 }; 2683 var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element 2684 2685 if (elementContext === popper && offsetData) { 2686 var offset = offsetData[placement]; 2687 Object.keys(overflowOffsets).forEach(function (key) { 2688 var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; 2689 var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x'; 2690 overflowOffsets[key] += offset[axis] * multiply; 2691 }); 2692 } 2693 2694 return overflowOffsets; 2695 } 2696 2697 function computeAutoPlacement(state, options) { 2698 if (options === void 0) { 2699 options = {}; 2700 } 2701 2702 var _options = options, 2703 placement = _options.placement, 2704 boundary = _options.boundary, 2705 rootBoundary = _options.rootBoundary, 2706 padding = _options.padding, 2707 flipVariations = _options.flipVariations, 2708 _options$allowedAutoP = _options.allowedAutoPlacements, 2709 allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; 2710 var variation = getVariation(placement); 2711 var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) { 2712 return getVariation(placement) === variation; 2713 }) : basePlacements; 2714 var allowedPlacements = placements$1.filter(function (placement) { 2715 return allowedAutoPlacements.indexOf(placement) >= 0; 2716 }); 2717 2718 if (allowedPlacements.length === 0) { 2719 allowedPlacements = placements$1; 2720 } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions... 2721 2722 2723 var overflows = allowedPlacements.reduce(function (acc, placement) { 2724 acc[placement] = detectOverflow(state, { 2725 placement: placement, 2726 boundary: boundary, 2727 rootBoundary: rootBoundary, 2728 padding: padding 2729 })[getBasePlacement(placement)]; 2730 return acc; 2731 }, {}); 2732 return Object.keys(overflows).sort(function (a, b) { 2733 return overflows[a] - overflows[b]; 2734 }); 2735 } 2736 2737 function getExpandedFallbackPlacements(placement) { 2738 if (getBasePlacement(placement) === auto) { 2739 return []; 2740 } 2741 2742 var oppositePlacement = getOppositePlacement(placement); 2743 return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; 2744 } 2745 2746 function flip(_ref) { 2747 var state = _ref.state, 2748 options = _ref.options, 2749 name = _ref.name; 2750 2751 if (state.modifiersData[name]._skip) { 2752 return; 2753 } 2754 2755 var _options$mainAxis = options.mainAxis, 2756 checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, 2757 _options$altAxis = options.altAxis, 2758 checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, 2759 specifiedFallbackPlacements = options.fallbackPlacements, 2760 padding = options.padding, 2761 boundary = options.boundary, 2762 rootBoundary = options.rootBoundary, 2763 altBoundary = options.altBoundary, 2764 _options$flipVariatio = options.flipVariations, 2765 flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, 2766 allowedAutoPlacements = options.allowedAutoPlacements; 2767 var preferredPlacement = state.options.placement; 2768 var basePlacement = getBasePlacement(preferredPlacement); 2769 var isBasePlacement = basePlacement === preferredPlacement; 2770 var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); 2771 var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) { 2772 return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, { 2773 placement: placement, 2774 boundary: boundary, 2775 rootBoundary: rootBoundary, 2776 padding: padding, 2777 flipVariations: flipVariations, 2778 allowedAutoPlacements: allowedAutoPlacements 2779 }) : placement); 2780 }, []); 2781 var referenceRect = state.rects.reference; 2782 var popperRect = state.rects.popper; 2783 var checksMap = new Map(); 2784 var makeFallbackChecks = true; 2785 var firstFittingPlacement = placements[0]; 2786 2787 for (var i = 0; i < placements.length; i++) { 2788 var placement = placements[i]; 2789 2790 var _basePlacement = getBasePlacement(placement); 2791 2792 var isStartVariation = getVariation(placement) === start; 2793 var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; 2794 var len = isVertical ? 'width' : 'height'; 2795 var overflow = detectOverflow(state, { 2796 placement: placement, 2797 boundary: boundary, 2798 rootBoundary: rootBoundary, 2799 altBoundary: altBoundary, 2800 padding: padding 2801 }); 2802 var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; 2803 2804 if (referenceRect[len] > popperRect[len]) { 2805 mainVariationSide = getOppositePlacement(mainVariationSide); 2806 } 2807 2808 var altVariationSide = getOppositePlacement(mainVariationSide); 2809 var checks = []; 2810 2811 if (checkMainAxis) { 2812 checks.push(overflow[_basePlacement] <= 0); 2813 } 2814 2815 if (checkAltAxis) { 2816 checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); 2817 } 2818 2819 if (checks.every(function (check) { 2820 return check; 2821 })) { 2822 firstFittingPlacement = placement; 2823 makeFallbackChecks = false; 2824 break; 2825 } 2826 2827 checksMap.set(placement, checks); 2828 } 2829 2830 if (makeFallbackChecks) { 2831 // `2` may be desired in some cases – research later 2832 var numberOfChecks = flipVariations ? 3 : 1; 2833 2834 var _loop = function _loop(_i) { 2835 var fittingPlacement = placements.find(function (placement) { 2836 var checks = checksMap.get(placement); 2837 2838 if (checks) { 2839 return checks.slice(0, _i).every(function (check) { 2840 return check; 2841 }); 2842 } 2843 }); 2844 2845 if (fittingPlacement) { 2846 firstFittingPlacement = fittingPlacement; 2847 return "break"; 2848 } 2849 }; 2850 2851 for (var _i = numberOfChecks; _i > 0; _i--) { 2852 var _ret = _loop(_i); 2853 2854 if (_ret === "break") break; 2855 } 2856 } 2857 2858 if (state.placement !== firstFittingPlacement) { 2859 state.modifiersData[name]._skip = true; 2860 state.placement = firstFittingPlacement; 2861 state.reset = true; 2862 } 2863 } // eslint-disable-next-line import/no-unused-modules 2864 2865 2866 const flip$1 = { 2867 name: 'flip', 2868 enabled: true, 2869 phase: 'main', 2870 fn: flip, 2871 requiresIfExists: ['offset'], 2872 data: { 2873 _skip: false 2874 } 2875 }; 2876 2877 function getSideOffsets(overflow, rect, preventedOffsets) { 2878 if (preventedOffsets === void 0) { 2879 preventedOffsets = { 2880 x: 0, 2881 y: 0 2882 }; 2883 } 2884 2885 return { 2886 top: overflow.top - rect.height - preventedOffsets.y, 2887 right: overflow.right - rect.width + preventedOffsets.x, 2888 bottom: overflow.bottom - rect.height + preventedOffsets.y, 2889 left: overflow.left - rect.width - preventedOffsets.x 2890 }; 2891 } 2892 2893 function isAnySideFullyClipped(overflow) { 2894 return [top, right, bottom, left].some(function (side) { 2895 return overflow[side] >= 0; 2896 }); 2897 } 2898 2899 function hide(_ref) { 2900 var state = _ref.state, 2901 name = _ref.name; 2902 var referenceRect = state.rects.reference; 2903 var popperRect = state.rects.popper; 2904 var preventedOffsets = state.modifiersData.preventOverflow; 2905 var referenceOverflow = detectOverflow(state, { 2906 elementContext: 'reference' 2907 }); 2908 var popperAltOverflow = detectOverflow(state, { 2909 altBoundary: true 2910 }); 2911 var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); 2912 var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); 2913 var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); 2914 var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); 2915 state.modifiersData[name] = { 2916 referenceClippingOffsets: referenceClippingOffsets, 2917 popperEscapeOffsets: popperEscapeOffsets, 2918 isReferenceHidden: isReferenceHidden, 2919 hasPopperEscaped: hasPopperEscaped 2920 }; 2921 state.attributes.popper = Object.assign({}, state.attributes.popper, { 2922 'data-popper-reference-hidden': isReferenceHidden, 2923 'data-popper-escaped': hasPopperEscaped 2924 }); 2925 } // eslint-disable-next-line import/no-unused-modules 2926 2927 2928 const hide$1 = { 2929 name: 'hide', 2930 enabled: true, 2931 phase: 'main', 2932 requiresIfExists: ['preventOverflow'], 2933 fn: hide 2934 }; 2935 2936 function distanceAndSkiddingToXY(placement, rects, offset) { 2937 var basePlacement = getBasePlacement(placement); 2938 var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; 2939 2940 var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, { 2941 placement: placement 2942 })) : offset, 2943 skidding = _ref[0], 2944 distance = _ref[1]; 2945 2946 skidding = skidding || 0; 2947 distance = (distance || 0) * invertDistance; 2948 return [left, right].indexOf(basePlacement) >= 0 ? { 2949 x: distance, 2950 y: skidding 2951 } : { 2952 x: skidding, 2953 y: distance 2954 }; 2955 } 2956 2957 function offset(_ref2) { 2958 var state = _ref2.state, 2959 options = _ref2.options, 2960 name = _ref2.name; 2961 var _options$offset = options.offset, 2962 offset = _options$offset === void 0 ? [0, 0] : _options$offset; 2963 var data = placements.reduce(function (acc, placement) { 2964 acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset); 2965 return acc; 2966 }, {}); 2967 var _data$state$placement = data[state.placement], 2968 x = _data$state$placement.x, 2969 y = _data$state$placement.y; 2970 2971 if (state.modifiersData.popperOffsets != null) { 2972 state.modifiersData.popperOffsets.x += x; 2973 state.modifiersData.popperOffsets.y += y; 2974 } 2975 2976 state.modifiersData[name] = data; 2977 } // eslint-disable-next-line import/no-unused-modules 2978 2979 2980 const offset$1 = { 2981 name: 'offset', 2982 enabled: true, 2983 phase: 'main', 2984 requires: ['popperOffsets'], 2985 fn: offset 2986 }; 2987 2988 function popperOffsets(_ref) { 2989 var state = _ref.state, 2990 name = _ref.name; 2991 // Offsets are the actual position the popper needs to have to be 2992 // properly positioned near its reference element 2993 // This is the most basic placement, and will be adjusted by 2994 // the modifiers in the next step 2995 state.modifiersData[name] = computeOffsets({ 2996 reference: state.rects.reference, 2997 element: state.rects.popper, 2998 placement: state.placement 2999 }); 3000 } // eslint-disable-next-line import/no-unused-modules 3001 3002 3003 const popperOffsets$1 = { 3004 name: 'popperOffsets', 3005 enabled: true, 3006 phase: 'read', 3007 fn: popperOffsets, 3008 data: {} 3009 }; 3010 3011 function getAltAxis(axis) { 3012 return axis === 'x' ? 'y' : 'x'; 3013 } 3014 3015 function preventOverflow(_ref) { 3016 var state = _ref.state, 3017 options = _ref.options, 3018 name = _ref.name; 3019 var _options$mainAxis = options.mainAxis, 3020 checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, 3021 _options$altAxis = options.altAxis, 3022 checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, 3023 boundary = options.boundary, 3024 rootBoundary = options.rootBoundary, 3025 altBoundary = options.altBoundary, 3026 padding = options.padding, 3027 _options$tether = options.tether, 3028 tether = _options$tether === void 0 ? true : _options$tether, 3029 _options$tetherOffset = options.tetherOffset, 3030 tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; 3031 var overflow = detectOverflow(state, { 3032 boundary: boundary, 3033 rootBoundary: rootBoundary, 3034 padding: padding, 3035 altBoundary: altBoundary 3036 }); 3037 var basePlacement = getBasePlacement(state.placement); 3038 var variation = getVariation(state.placement); 3039 var isBasePlacement = !variation; 3040 var mainAxis = getMainAxisFromPlacement(basePlacement); 3041 var altAxis = getAltAxis(mainAxis); 3042 var popperOffsets = state.modifiersData.popperOffsets; 3043 var referenceRect = state.rects.reference; 3044 var popperRect = state.rects.popper; 3045 var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, { 3046 placement: state.placement 3047 })) : tetherOffset; 3048 var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? { 3049 mainAxis: tetherOffsetValue, 3050 altAxis: tetherOffsetValue 3051 } : Object.assign({ 3052 mainAxis: 0, 3053 altAxis: 0 3054 }, tetherOffsetValue); 3055 var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; 3056 var data = { 3057 x: 0, 3058 y: 0 3059 }; 3060 3061 if (!popperOffsets) { 3062 return; 3063 } 3064 3065 if (checkMainAxis) { 3066 var _offsetModifierState$; 3067 3068 var mainSide = mainAxis === 'y' ? top : left; 3069 var altSide = mainAxis === 'y' ? bottom : right; 3070 var len = mainAxis === 'y' ? 'height' : 'width'; 3071 var offset = popperOffsets[mainAxis]; 3072 var min$1 = offset + overflow[mainSide]; 3073 var max$1 = offset - overflow[altSide]; 3074 var additive = tether ? -popperRect[len] / 2 : 0; 3075 var minLen = variation === start ? referenceRect[len] : popperRect[len]; 3076 var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go 3077 // outside the reference bounds 3078 3079 var arrowElement = state.elements.arrow; 3080 var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { 3081 width: 0, 3082 height: 0 3083 }; 3084 var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject(); 3085 var arrowPaddingMin = arrowPaddingObject[mainSide]; 3086 var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want 3087 // to include its full size in the calculation. If the reference is small 3088 // and near the edge of a boundary, the popper can overflow even if the 3089 // reference is not overflowing as well (e.g. virtual elements with no 3090 // width or height) 3091 3092 var arrowLen = within(0, referenceRect[len], arrowRect[len]); 3093 var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; 3094 var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; 3095 var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); 3096 var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; 3097 var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; 3098 var tetherMin = offset + minOffset - offsetModifierValue - clientOffset; 3099 var tetherMax = offset + maxOffset - offsetModifierValue; 3100 var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1); 3101 popperOffsets[mainAxis] = preventedOffset; 3102 data[mainAxis] = preventedOffset - offset; 3103 } 3104 3105 if (checkAltAxis) { 3106 var _offsetModifierState$2; 3107 3108 var _mainSide = mainAxis === 'x' ? top : left; 3109 3110 var _altSide = mainAxis === 'x' ? bottom : right; 3111 3112 var _offset = popperOffsets[altAxis]; 3113 3114 var _len = altAxis === 'y' ? 'height' : 'width'; 3115 3116 var _min = _offset + overflow[_mainSide]; 3117 3118 var _max = _offset - overflow[_altSide]; 3119 3120 var isOriginSide = [top, left].indexOf(basePlacement) !== -1; 3121 3122 var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; 3123 3124 var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; 3125 3126 var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; 3127 3128 var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); 3129 3130 popperOffsets[altAxis] = _preventedOffset; 3131 data[altAxis] = _preventedOffset - _offset; 3132 } 3133 3134 state.modifiersData[name] = data; 3135 } // eslint-disable-next-line import/no-unused-modules 3136 3137 3138 const preventOverflow$1 = { 3139 name: 'preventOverflow', 3140 enabled: true, 3141 phase: 'main', 3142 fn: preventOverflow, 3143 requiresIfExists: ['offset'] 3144 }; 3145 3146 function getHTMLElementScroll(element) { 3147 return { 3148 scrollLeft: element.scrollLeft, 3149 scrollTop: element.scrollTop 3150 }; 3151 } 3152 3153 function getNodeScroll(node) { 3154 if (node === getWindow(node) || !isHTMLElement(node)) { 3155 return getWindowScroll(node); 3156 } else { 3157 return getHTMLElementScroll(node); 3158 } 3159 } 3160 3161 function isElementScaled(element) { 3162 var rect = element.getBoundingClientRect(); 3163 var scaleX = round(rect.width) / element.offsetWidth || 1; 3164 var scaleY = round(rect.height) / element.offsetHeight || 1; 3165 return scaleX !== 1 || scaleY !== 1; 3166 } // Returns the composite rect of an element relative to its offsetParent. 3167 // Composite means it takes into account transforms as well as layout. 3168 3169 3170 function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { 3171 if (isFixed === void 0) { 3172 isFixed = false; 3173 } 3174 3175 var isOffsetParentAnElement = isHTMLElement(offsetParent); 3176 var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent); 3177 var documentElement = getDocumentElement(offsetParent); 3178 var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed); 3179 var scroll = { 3180 scrollLeft: 0, 3181 scrollTop: 0 3182 }; 3183 var offsets = { 3184 x: 0, 3185 y: 0 3186 }; 3187 3188 if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { 3189 if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078 3190 isScrollParent(documentElement)) { 3191 scroll = getNodeScroll(offsetParent); 3192 } 3193 3194 if (isHTMLElement(offsetParent)) { 3195 offsets = getBoundingClientRect(offsetParent, true); 3196 offsets.x += offsetParent.clientLeft; 3197 offsets.y += offsetParent.clientTop; 3198 } else if (documentElement) { 3199 offsets.x = getWindowScrollBarX(documentElement); 3200 } 3201 } 3202 3203 return { 3204 x: rect.left + scroll.scrollLeft - offsets.x, 3205 y: rect.top + scroll.scrollTop - offsets.y, 3206 width: rect.width, 3207 height: rect.height 3208 }; 3209 } 3210 3211 function order(modifiers) { 3212 var map = new Map(); 3213 var visited = new Set(); 3214 var result = []; 3215 modifiers.forEach(function (modifier) { 3216 map.set(modifier.name, modifier); 3217 }); // On visiting object, check for its dependencies and visit them recursively 3218 3219 function sort(modifier) { 3220 visited.add(modifier.name); 3221 var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); 3222 requires.forEach(function (dep) { 3223 if (!visited.has(dep)) { 3224 var depModifier = map.get(dep); 3225 3226 if (depModifier) { 3227 sort(depModifier); 3228 } 3229 } 3230 }); 3231 result.push(modifier); 3232 } 3233 3234 modifiers.forEach(function (modifier) { 3235 if (!visited.has(modifier.name)) { 3236 // check for visited object 3237 sort(modifier); 3238 } 3239 }); 3240 return result; 3241 } 3242 3243 function orderModifiers(modifiers) { 3244 // order based on dependencies 3245 var orderedModifiers = order(modifiers); // order based on phase 3246 3247 return modifierPhases.reduce(function (acc, phase) { 3248 return acc.concat(orderedModifiers.filter(function (modifier) { 3249 return modifier.phase === phase; 3250 })); 3251 }, []); 3252 } 3253 3254 function debounce(fn) { 3255 var pending; 3256 return function () { 3257 if (!pending) { 3258 pending = new Promise(function (resolve) { 3259 Promise.resolve().then(function () { 3260 pending = undefined; 3261 resolve(fn()); 3262 }); 3263 }); 3264 } 3265 3266 return pending; 3267 }; 3268 } 3269 3270 function mergeByName(modifiers) { 3271 var merged = modifiers.reduce(function (merged, current) { 3272 var existing = merged[current.name]; 3273 merged[current.name] = existing ? Object.assign({}, existing, current, { 3274 options: Object.assign({}, existing.options, current.options), 3275 data: Object.assign({}, existing.data, current.data) 3276 }) : current; 3277 return merged; 3278 }, {}); // IE11 does not support Object.values 3279 3280 return Object.keys(merged).map(function (key) { 3281 return merged[key]; 3282 }); 3283 } 3284 3285 var DEFAULT_OPTIONS = { 3286 placement: 'bottom', 3287 modifiers: [], 3288 strategy: 'absolute' 3289 }; 3290 3291 function areValidElements() { 3292 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 3293 args[_key] = arguments[_key]; 3294 } 3295 3296 return !args.some(function (element) { 3297 return !(element && typeof element.getBoundingClientRect === 'function'); 3298 }); 3299 } 3300 3301 function popperGenerator(generatorOptions) { 3302 if (generatorOptions === void 0) { 3303 generatorOptions = {}; 3304 } 3305 3306 var _generatorOptions = generatorOptions, 3307 _generatorOptions$def = _generatorOptions.defaultModifiers, 3308 defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, 3309 _generatorOptions$def2 = _generatorOptions.defaultOptions, 3310 defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; 3311 return function createPopper(reference, popper, options) { 3312 if (options === void 0) { 3313 options = defaultOptions; 3314 } 3315 3316 var state = { 3317 placement: 'bottom', 3318 orderedModifiers: [], 3319 options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), 3320 modifiersData: {}, 3321 elements: { 3322 reference: reference, 3323 popper: popper 3324 }, 3325 attributes: {}, 3326 styles: {} 3327 }; 3328 var effectCleanupFns = []; 3329 var isDestroyed = false; 3330 var instance = { 3331 state: state, 3332 setOptions: function setOptions(setOptionsAction) { 3333 var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction; 3334 cleanupModifierEffects(); 3335 state.options = Object.assign({}, defaultOptions, state.options, options); 3336 state.scrollParents = { 3337 reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [], 3338 popper: listScrollParents(popper) 3339 }; // Orders the modifiers based on their dependencies and `phase` 3340 // properties 3341 3342 var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers 3343 3344 state.orderedModifiers = orderedModifiers.filter(function (m) { 3345 return m.enabled; 3346 }); 3347 runModifierEffects(); 3348 return instance.update(); 3349 }, 3350 // Sync update – it will always be executed, even if not necessary. This 3351 // is useful for low frequency updates where sync behavior simplifies the 3352 // logic. 3353 // For high frequency updates (e.g. `resize` and `scroll` events), always 3354 // prefer the async Popper#update method 3355 forceUpdate: function forceUpdate() { 3356 if (isDestroyed) { 3357 return; 3358 } 3359 3360 var _state$elements = state.elements, 3361 reference = _state$elements.reference, 3362 popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements 3363 // anymore 3364 3365 if (!areValidElements(reference, popper)) { 3366 return; 3367 } // Store the reference and popper rects to be read by modifiers 3368 3369 3370 state.rects = { 3371 reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'), 3372 popper: getLayoutRect(popper) 3373 }; // Modifiers have the ability to reset the current update cycle. The 3374 // most common use case for this is the `flip` modifier changing the 3375 // placement, which then needs to re-run all the modifiers, because the 3376 // logic was previously ran for the previous placement and is therefore 3377 // stale/incorrect 3378 3379 state.reset = false; 3380 state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier 3381 // is filled with the initial data specified by the modifier. This means 3382 // it doesn't persist and is fresh on each update. 3383 // To ensure persistent data, use `${name}#persistent` 3384 3385 state.orderedModifiers.forEach(function (modifier) { 3386 return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); 3387 }); 3388 3389 for (var index = 0; index < state.orderedModifiers.length; index++) { 3390 if (state.reset === true) { 3391 state.reset = false; 3392 index = -1; 3393 continue; 3394 } 3395 3396 var _state$orderedModifie = state.orderedModifiers[index], 3397 fn = _state$orderedModifie.fn, 3398 _state$orderedModifie2 = _state$orderedModifie.options, 3399 _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, 3400 name = _state$orderedModifie.name; 3401 3402 if (typeof fn === 'function') { 3403 state = fn({ 3404 state: state, 3405 options: _options, 3406 name: name, 3407 instance: instance 3408 }) || state; 3409 } 3410 } 3411 }, 3412 // Async and optimistically optimized update – it will not be executed if 3413 // not necessary (debounced to run at most once-per-tick) 3414 update: debounce(function () { 3415 return new Promise(function (resolve) { 3416 instance.forceUpdate(); 3417 resolve(state); 3418 }); 3419 }), 3420 destroy: function destroy() { 3421 cleanupModifierEffects(); 3422 isDestroyed = true; 3423 } 3424 }; 3425 3426 if (!areValidElements(reference, popper)) { 3427 return instance; 3428 } 3429 3430 instance.setOptions(options).then(function (state) { 3431 if (!isDestroyed && options.onFirstUpdate) { 3432 options.onFirstUpdate(state); 3433 } 3434 }); // Modifiers have the ability to execute arbitrary code before the first 3435 // update cycle runs. They will be executed in the same order as the update 3436 // cycle. This is useful when a modifier adds some persistent data that 3437 // other modifiers need to use, but the modifier is run after the dependent 3438 // one. 3439 3440 function runModifierEffects() { 3441 state.orderedModifiers.forEach(function (_ref) { 3442 var name = _ref.name, 3443 _ref$options = _ref.options, 3444 options = _ref$options === void 0 ? {} : _ref$options, 3445 effect = _ref.effect; 3446 3447 if (typeof effect === 'function') { 3448 var cleanupFn = effect({ 3449 state: state, 3450 name: name, 3451 instance: instance, 3452 options: options 3453 }); 3454 3455 var noopFn = function noopFn() {}; 3456 3457 effectCleanupFns.push(cleanupFn || noopFn); 3458 } 3459 }); 3460 } 3461 3462 function cleanupModifierEffects() { 3463 effectCleanupFns.forEach(function (fn) { 3464 return fn(); 3465 }); 3466 effectCleanupFns = []; 3467 } 3468 3469 return instance; 3470 }; 3471 } 3472 var createPopper$2 = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules 3473 3474 var defaultModifiers$1 = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1]; 3475 var createPopper$1 = /*#__PURE__*/popperGenerator({ 3476 defaultModifiers: defaultModifiers$1 3477 }); // eslint-disable-next-line import/no-unused-modules 3478 3479 var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1]; 3480 var createPopper = /*#__PURE__*/popperGenerator({ 3481 defaultModifiers: defaultModifiers 3482 }); // eslint-disable-next-line import/no-unused-modules 3483 3484 const Popper = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ 3485 __proto__: null, 3486 afterMain, 3487 afterRead, 3488 afterWrite, 3489 applyStyles: applyStyles$1, 3490 arrow: arrow$1, 3491 auto, 3492 basePlacements, 3493 beforeMain, 3494 beforeRead, 3495 beforeWrite, 3496 bottom, 3497 clippingParents, 3498 computeStyles: computeStyles$1, 3499 createPopper, 3500 createPopperBase: createPopper$2, 3501 createPopperLite: createPopper$1, 3502 detectOverflow, 3503 end, 3504 eventListeners, 3505 flip: flip$1, 3506 hide: hide$1, 3507 left, 3508 main, 3509 modifierPhases, 3510 offset: offset$1, 3511 placements, 3512 popper, 3513 popperGenerator, 3514 popperOffsets: popperOffsets$1, 3515 preventOverflow: preventOverflow$1, 3516 read, 3517 reference, 3518 right, 3519 start, 3520 top, 3521 variationPlacements, 3522 viewport, 3523 write 3524 }, Symbol.toStringTag, { value: 'Module' })); 3525 3526 /** 3527 * -------------------------------------------------------------------------- 3528 * Bootstrap dropdown.js 3529 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 3530 * -------------------------------------------------------------------------- 3531 */ 3532 3533 3534 /** 3535 * Constants 3536 */ 3537 3538 const NAME$a = 'dropdown'; 3539 const DATA_KEY$6 = 'bs.dropdown'; 3540 const EVENT_KEY$6 = `.${DATA_KEY$6}`; 3541 const DATA_API_KEY$3 = '.data-api'; 3542 const ESCAPE_KEY$2 = 'Escape'; 3543 const TAB_KEY$1 = 'Tab'; 3544 const ARROW_UP_KEY$1 = 'ArrowUp'; 3545 const ARROW_DOWN_KEY$1 = 'ArrowDown'; 3546 const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button 3547 3548 const EVENT_HIDE$5 = `hide${EVENT_KEY$6}`; 3549 const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`; 3550 const EVENT_SHOW$5 = `show${EVENT_KEY$6}`; 3551 const EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`; 3552 const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`; 3553 const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`; 3554 const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`; 3555 const CLASS_NAME_SHOW$6 = 'show'; 3556 const CLASS_NAME_DROPUP = 'dropup'; 3557 const CLASS_NAME_DROPEND = 'dropend'; 3558 const CLASS_NAME_DROPSTART = 'dropstart'; 3559 const CLASS_NAME_DROPUP_CENTER = 'dropup-center'; 3560 const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center'; 3561 const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)'; 3562 const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`; 3563 const SELECTOR_MENU = '.dropdown-menu'; 3564 const SELECTOR_NAVBAR = '.navbar'; 3565 const SELECTOR_NAVBAR_NAV = '.navbar-nav'; 3566 const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'; 3567 const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start'; 3568 const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end'; 3569 const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start'; 3570 const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end'; 3571 const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start'; 3572 const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start'; 3573 const PLACEMENT_TOPCENTER = 'top'; 3574 const PLACEMENT_BOTTOMCENTER = 'bottom'; 3575 const Default$9 = { 3576 autoClose: true, 3577 boundary: 'clippingParents', 3578 display: 'dynamic', 3579 offset: [0, 2], 3580 popperConfig: null, 3581 reference: 'toggle' 3582 }; 3583 const DefaultType$9 = { 3584 autoClose: '(boolean|string)', 3585 boundary: '(string|element)', 3586 display: 'string', 3587 offset: '(array|string|function)', 3588 popperConfig: '(null|object|function)', 3589 reference: '(string|element|object)' 3590 }; 3591 3592 /** 3593 * Class definition 3594 */ 3595 3596 class Dropdown extends BaseComponent { 3597 constructor(element, config) { 3598 super(element, config); 3599 this._popper = null; 3600 this._parent = this._element.parentNode; // dropdown wrapper 3601 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/ 3602 this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent); 3603 this._inNavbar = this._detectNavbar(); 3604 } 3605 3606 // Getters 3607 static get Default() { 3608 return Default$9; 3609 } 3610 static get DefaultType() { 3611 return DefaultType$9; 3612 } 3613 static get NAME() { 3614 return NAME$a; 3615 } 3616 3617 // Public 3618 toggle() { 3619 return this._isShown() ? this.hide() : this.show(); 3620 } 3621 show() { 3622 if (isDisabled(this._element) || this._isShown()) { 3623 return; 3624 } 3625 const relatedTarget = { 3626 relatedTarget: this._element 3627 }; 3628 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget); 3629 if (showEvent.defaultPrevented) { 3630 return; 3631 } 3632 this._createPopper(); 3633 3634 // If this is a touch-enabled device we add extra 3635 // empty mouseover listeners to the body's immediate children; 3636 // only needed because of broken event delegation on iOS 3637 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 3638 if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) { 3639 for (const element of [].concat(...document.body.children)) { 3640 EventHandler.on(element, 'mouseover', noop); 3641 } 3642 } 3643 this._element.focus(); 3644 this._element.setAttribute('aria-expanded', true); 3645 this._menu.classList.add(CLASS_NAME_SHOW$6); 3646 this._element.classList.add(CLASS_NAME_SHOW$6); 3647 EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget); 3648 } 3649 hide() { 3650 if (isDisabled(this._element) || !this._isShown()) { 3651 return; 3652 } 3653 const relatedTarget = { 3654 relatedTarget: this._element 3655 }; 3656 this._completeHide(relatedTarget); 3657 } 3658 dispose() { 3659 if (this._popper) { 3660 this._popper.destroy(); 3661 } 3662 super.dispose(); 3663 } 3664 update() { 3665 this._inNavbar = this._detectNavbar(); 3666 if (this._popper) { 3667 this._popper.update(); 3668 } 3669 } 3670 3671 // Private 3672 _completeHide(relatedTarget) { 3673 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget); 3674 if (hideEvent.defaultPrevented) { 3675 return; 3676 } 3677 3678 // If this is a touch-enabled device we remove the extra 3679 // empty mouseover listeners we added for iOS support 3680 if ('ontouchstart' in document.documentElement) { 3681 for (const element of [].concat(...document.body.children)) { 3682 EventHandler.off(element, 'mouseover', noop); 3683 } 3684 } 3685 if (this._popper) { 3686 this._popper.destroy(); 3687 } 3688 this._menu.classList.remove(CLASS_NAME_SHOW$6); 3689 this._element.classList.remove(CLASS_NAME_SHOW$6); 3690 this._element.setAttribute('aria-expanded', 'false'); 3691 Manipulator.removeDataAttribute(this._menu, 'popper'); 3692 EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget); 3693 } 3694 _getConfig(config) { 3695 config = super._getConfig(config); 3696 if (typeof config.reference === 'object' && !isElement$1(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') { 3697 // Popper virtual elements require a getBoundingClientRect method 3698 throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`); 3699 } 3700 return config; 3701 } 3702 _createPopper() { 3703 if (typeof Popper === 'undefined') { 3704 throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org/docs/v2/)'); 3705 } 3706 let referenceElement = this._element; 3707 if (this._config.reference === 'parent') { 3708 referenceElement = this._parent; 3709 } else if (isElement$1(this._config.reference)) { 3710 referenceElement = getElement(this._config.reference); 3711 } else if (typeof this._config.reference === 'object') { 3712 referenceElement = this._config.reference; 3713 } 3714 const popperConfig = this._getPopperConfig(); 3715 this._popper = createPopper(referenceElement, this._menu, popperConfig); 3716 } 3717 _isShown() { 3718 return this._menu.classList.contains(CLASS_NAME_SHOW$6); 3719 } 3720 _getPlacement() { 3721 const parentDropdown = this._parent; 3722 if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) { 3723 return PLACEMENT_RIGHT; 3724 } 3725 if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) { 3726 return PLACEMENT_LEFT; 3727 } 3728 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) { 3729 return PLACEMENT_TOPCENTER; 3730 } 3731 if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) { 3732 return PLACEMENT_BOTTOMCENTER; 3733 } 3734 3735 // We need to trim the value because custom properties can also include spaces 3736 const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'; 3737 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) { 3738 return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP; 3739 } 3740 return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM; 3741 } 3742 _detectNavbar() { 3743 return this._element.closest(SELECTOR_NAVBAR) !== null; 3744 } 3745 _getOffset() { 3746 const { 3747 offset 3748 } = this._config; 3749 if (typeof offset === 'string') { 3750 return offset.split(',').map(value => Number.parseInt(value, 10)); 3751 } 3752 if (typeof offset === 'function') { 3753 return popperData => offset(popperData, this._element); 3754 } 3755 return offset; 3756 } 3757 _getPopperConfig() { 3758 const defaultBsPopperConfig = { 3759 placement: this._getPlacement(), 3760 modifiers: [{ 3761 name: 'preventOverflow', 3762 options: { 3763 boundary: this._config.boundary 3764 } 3765 }, { 3766 name: 'offset', 3767 options: { 3768 offset: this._getOffset() 3769 } 3770 }] 3771 }; 3772 3773 // Disable Popper if we have a static display or Dropdown is in Navbar 3774 if (this._inNavbar || this._config.display === 'static') { 3775 Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove 3776 defaultBsPopperConfig.modifiers = [{ 3777 name: 'applyStyles', 3778 enabled: false 3779 }]; 3780 } 3781 return { 3782 ...defaultBsPopperConfig, 3783 ...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig]) 3784 }; 3785 } 3786 _selectMenuItem({ 3787 key, 3788 target 3789 }) { 3790 const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element)); 3791 if (!items.length) { 3792 return; 3793 } 3794 3795 // if target isn't included in items (e.g. when expanding the dropdown) 3796 // allow cycling to get the last item in case key equals ARROW_UP_KEY 3797 getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus(); 3798 } 3799 3800 // Static 3801 static jQueryInterface(config) { 3802 return this.each(function () { 3803 const data = Dropdown.getOrCreateInstance(this, config); 3804 if (typeof config !== 'string') { 3805 return; 3806 } 3807 if (typeof data[config] === 'undefined') { 3808 throw new TypeError(`No method named "${config}"`); 3809 } 3810 data[config](); 3811 }); 3812 } 3813 static clearMenus(event) { 3814 if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) { 3815 return; 3816 } 3817 const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN); 3818 for (const toggle of openToggles) { 3819 const context = Dropdown.getInstance(toggle); 3820 if (!context || context._config.autoClose === false) { 3821 continue; 3822 } 3823 const composedPath = event.composedPath(); 3824 const isMenuTarget = composedPath.includes(context._menu); 3825 if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) { 3826 continue; 3827 } 3828 3829 // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu 3830 if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) { 3831 continue; 3832 } 3833 const relatedTarget = { 3834 relatedTarget: context._element 3835 }; 3836 if (event.type === 'click') { 3837 relatedTarget.clickEvent = event; 3838 } 3839 context._completeHide(relatedTarget); 3840 } 3841 } 3842 static dataApiKeydownHandler(event) { 3843 // If not an UP | DOWN | ESCAPE key => not a dropdown command 3844 // If input/textarea && if key is other than ESCAPE => not a dropdown command 3845 3846 const isInput = /input|textarea/i.test(event.target.tagName); 3847 const isEscapeEvent = event.key === ESCAPE_KEY$2; 3848 const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key); 3849 if (!isUpOrDownEvent && !isEscapeEvent) { 3850 return; 3851 } 3852 if (isInput && !isEscapeEvent) { 3853 return; 3854 } 3855 event.preventDefault(); 3856 3857 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/ 3858 const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3, event.delegateTarget.parentNode); 3859 const instance = Dropdown.getOrCreateInstance(getToggleButton); 3860 if (isUpOrDownEvent) { 3861 event.stopPropagation(); 3862 instance.show(); 3863 instance._selectMenuItem(event); 3864 return; 3865 } 3866 if (instance._isShown()) { 3867 // else is escape and we check if it is shown 3868 event.stopPropagation(); 3869 instance.hide(); 3870 getToggleButton.focus(); 3871 } 3872 } 3873 } 3874 3875 /** 3876 * Data API implementation 3877 */ 3878 3879 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler); 3880 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler); 3881 EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus); 3882 EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus); 3883 EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) { 3884 event.preventDefault(); 3885 Dropdown.getOrCreateInstance(this).toggle(); 3886 }); 3887 3888 /** 3889 * jQuery 3890 */ 3891 3892 defineJQueryPlugin(Dropdown); 3893 3894 /** 3895 * -------------------------------------------------------------------------- 3896 * Bootstrap util/backdrop.js 3897 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 3898 * -------------------------------------------------------------------------- 3899 */ 3900 3901 3902 /** 3903 * Constants 3904 */ 3905 3906 const NAME$9 = 'backdrop'; 3907 const CLASS_NAME_FADE$4 = 'fade'; 3908 const CLASS_NAME_SHOW$5 = 'show'; 3909 const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`; 3910 const Default$8 = { 3911 className: 'modal-backdrop', 3912 clickCallback: null, 3913 isAnimated: false, 3914 isVisible: true, 3915 // if false, we use the backdrop helper without adding any element to the dom 3916 rootElement: 'body' // give the choice to place backdrop under different elements 3917 }; 3918 const DefaultType$8 = { 3919 className: 'string', 3920 clickCallback: '(function|null)', 3921 isAnimated: 'boolean', 3922 isVisible: 'boolean', 3923 rootElement: '(element|string)' 3924 }; 3925 3926 /** 3927 * Class definition 3928 */ 3929 3930 class Backdrop extends Config { 3931 constructor(config) { 3932 super(); 3933 this._config = this._getConfig(config); 3934 this._isAppended = false; 3935 this._element = null; 3936 } 3937 3938 // Getters 3939 static get Default() { 3940 return Default$8; 3941 } 3942 static get DefaultType() { 3943 return DefaultType$8; 3944 } 3945 static get NAME() { 3946 return NAME$9; 3947 } 3948 3949 // Public 3950 show(callback) { 3951 if (!this._config.isVisible) { 3952 execute(callback); 3953 return; 3954 } 3955 this._append(); 3956 const element = this._getElement(); 3957 if (this._config.isAnimated) { 3958 reflow(element); 3959 } 3960 element.classList.add(CLASS_NAME_SHOW$5); 3961 this._emulateAnimation(() => { 3962 execute(callback); 3963 }); 3964 } 3965 hide(callback) { 3966 if (!this._config.isVisible) { 3967 execute(callback); 3968 return; 3969 } 3970 this._getElement().classList.remove(CLASS_NAME_SHOW$5); 3971 this._emulateAnimation(() => { 3972 this.dispose(); 3973 execute(callback); 3974 }); 3975 } 3976 dispose() { 3977 if (!this._isAppended) { 3978 return; 3979 } 3980 EventHandler.off(this._element, EVENT_MOUSEDOWN); 3981 this._element.remove(); 3982 this._isAppended = false; 3983 } 3984 3985 // Private 3986 _getElement() { 3987 if (!this._element) { 3988 const backdrop = document.createElement('div'); 3989 backdrop.className = this._config.className; 3990 if (this._config.isAnimated) { 3991 backdrop.classList.add(CLASS_NAME_FADE$4); 3992 } 3993 this._element = backdrop; 3994 } 3995 return this._element; 3996 } 3997 _configAfterMerge(config) { 3998 // use getElement() with the default "body" to get a fresh Element on each instantiation 3999 config.rootElement = getElement(config.rootElement); 4000 return config; 4001 } 4002 _append() { 4003 if (this._isAppended) { 4004 return; 4005 } 4006 const element = this._getElement(); 4007 this._config.rootElement.append(element); 4008 EventHandler.on(element, EVENT_MOUSEDOWN, () => { 4009 execute(this._config.clickCallback); 4010 }); 4011 this._isAppended = true; 4012 } 4013 _emulateAnimation(callback) { 4014 executeAfterTransition(callback, this._getElement(), this._config.isAnimated); 4015 } 4016 } 4017 4018 /** 4019 * -------------------------------------------------------------------------- 4020 * Bootstrap util/focustrap.js 4021 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4022 * -------------------------------------------------------------------------- 4023 */ 4024 4025 4026 /** 4027 * Constants 4028 */ 4029 4030 const NAME$8 = 'focustrap'; 4031 const DATA_KEY$5 = 'bs.focustrap'; 4032 const EVENT_KEY$5 = `.${DATA_KEY$5}`; 4033 const EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`; 4034 const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`; 4035 const TAB_KEY = 'Tab'; 4036 const TAB_NAV_FORWARD = 'forward'; 4037 const TAB_NAV_BACKWARD = 'backward'; 4038 const Default$7 = { 4039 autofocus: true, 4040 trapElement: null // The element to trap focus inside of 4041 }; 4042 const DefaultType$7 = { 4043 autofocus: 'boolean', 4044 trapElement: 'element' 4045 }; 4046 4047 /** 4048 * Class definition 4049 */ 4050 4051 class FocusTrap extends Config { 4052 constructor(config) { 4053 super(); 4054 this._config = this._getConfig(config); 4055 this._isActive = false; 4056 this._lastTabNavDirection = null; 4057 } 4058 4059 // Getters 4060 static get Default() { 4061 return Default$7; 4062 } 4063 static get DefaultType() { 4064 return DefaultType$7; 4065 } 4066 static get NAME() { 4067 return NAME$8; 4068 } 4069 4070 // Public 4071 activate() { 4072 if (this._isActive) { 4073 return; 4074 } 4075 if (this._config.autofocus) { 4076 this._config.trapElement.focus(); 4077 } 4078 EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop 4079 EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event)); 4080 EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event)); 4081 this._isActive = true; 4082 } 4083 deactivate() { 4084 if (!this._isActive) { 4085 return; 4086 } 4087 this._isActive = false; 4088 EventHandler.off(document, EVENT_KEY$5); 4089 } 4090 4091 // Private 4092 _handleFocusin(event) { 4093 const { 4094 trapElement 4095 } = this._config; 4096 if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) { 4097 return; 4098 } 4099 const elements = SelectorEngine.focusableChildren(trapElement); 4100 if (elements.length === 0) { 4101 trapElement.focus(); 4102 } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) { 4103 elements[elements.length - 1].focus(); 4104 } else { 4105 elements[0].focus(); 4106 } 4107 } 4108 _handleKeydown(event) { 4109 if (event.key !== TAB_KEY) { 4110 return; 4111 } 4112 this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD; 4113 } 4114 } 4115 4116 /** 4117 * -------------------------------------------------------------------------- 4118 * Bootstrap util/scrollBar.js 4119 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4120 * -------------------------------------------------------------------------- 4121 */ 4122 4123 4124 /** 4125 * Constants 4126 */ 4127 4128 const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'; 4129 const SELECTOR_STICKY_CONTENT = '.sticky-top'; 4130 const PROPERTY_PADDING = 'padding-right'; 4131 const PROPERTY_MARGIN = 'margin-right'; 4132 4133 /** 4134 * Class definition 4135 */ 4136 4137 class ScrollBarHelper { 4138 constructor() { 4139 this._element = document.body; 4140 } 4141 4142 // Public 4143 getWidth() { 4144 // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes 4145 const documentWidth = document.documentElement.clientWidth; 4146 return Math.abs(window.innerWidth - documentWidth); 4147 } 4148 hide() { 4149 const width = this.getWidth(); 4150 this._disableOverFlow(); 4151 // give padding to element to balance the hidden scrollbar width 4152 this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width); 4153 // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth 4154 this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width); 4155 this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width); 4156 } 4157 reset() { 4158 this._resetElementAttributes(this._element, 'overflow'); 4159 this._resetElementAttributes(this._element, PROPERTY_PADDING); 4160 this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING); 4161 this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN); 4162 } 4163 isOverflowing() { 4164 return this.getWidth() > 0; 4165 } 4166 4167 // Private 4168 _disableOverFlow() { 4169 this._saveInitialAttribute(this._element, 'overflow'); 4170 this._element.style.overflow = 'hidden'; 4171 } 4172 _setElementAttributes(selector, styleProperty, callback) { 4173 const scrollbarWidth = this.getWidth(); 4174 const manipulationCallBack = element => { 4175 if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) { 4176 return; 4177 } 4178 this._saveInitialAttribute(element, styleProperty); 4179 const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty); 4180 element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`); 4181 }; 4182 this._applyManipulationCallback(selector, manipulationCallBack); 4183 } 4184 _saveInitialAttribute(element, styleProperty) { 4185 const actualValue = element.style.getPropertyValue(styleProperty); 4186 if (actualValue) { 4187 Manipulator.setDataAttribute(element, styleProperty, actualValue); 4188 } 4189 } 4190 _resetElementAttributes(selector, styleProperty) { 4191 const manipulationCallBack = element => { 4192 const value = Manipulator.getDataAttribute(element, styleProperty); 4193 // We only want to remove the property if the value is `null`; the value can also be zero 4194 if (value === null) { 4195 element.style.removeProperty(styleProperty); 4196 return; 4197 } 4198 Manipulator.removeDataAttribute(element, styleProperty); 4199 element.style.setProperty(styleProperty, value); 4200 }; 4201 this._applyManipulationCallback(selector, manipulationCallBack); 4202 } 4203 _applyManipulationCallback(selector, callBack) { 4204 if (isElement$1(selector)) { 4205 callBack(selector); 4206 return; 4207 } 4208 for (const sel of SelectorEngine.find(selector, this._element)) { 4209 callBack(sel); 4210 } 4211 } 4212 } 4213 4214 /** 4215 * -------------------------------------------------------------------------- 4216 * Bootstrap modal.js 4217 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4218 * -------------------------------------------------------------------------- 4219 */ 4220 4221 4222 /** 4223 * Constants 4224 */ 4225 4226 const NAME$7 = 'modal'; 4227 const DATA_KEY$4 = 'bs.modal'; 4228 const EVENT_KEY$4 = `.${DATA_KEY$4}`; 4229 const DATA_API_KEY$2 = '.data-api'; 4230 const ESCAPE_KEY$1 = 'Escape'; 4231 const EVENT_HIDE$4 = `hide${EVENT_KEY$4}`; 4232 const EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`; 4233 const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`; 4234 const EVENT_SHOW$4 = `show${EVENT_KEY$4}`; 4235 const EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`; 4236 const EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`; 4237 const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`; 4238 const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`; 4239 const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`; 4240 const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`; 4241 const CLASS_NAME_OPEN = 'modal-open'; 4242 const CLASS_NAME_FADE$3 = 'fade'; 4243 const CLASS_NAME_SHOW$4 = 'show'; 4244 const CLASS_NAME_STATIC = 'modal-static'; 4245 const OPEN_SELECTOR$1 = '.modal.show'; 4246 const SELECTOR_DIALOG = '.modal-dialog'; 4247 const SELECTOR_MODAL_BODY = '.modal-body'; 4248 const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle="modal"]'; 4249 const Default$6 = { 4250 backdrop: true, 4251 focus: true, 4252 keyboard: true 4253 }; 4254 const DefaultType$6 = { 4255 backdrop: '(boolean|string)', 4256 focus: 'boolean', 4257 keyboard: 'boolean' 4258 }; 4259 4260 /** 4261 * Class definition 4262 */ 4263 4264 class Modal extends BaseComponent { 4265 constructor(element, config) { 4266 super(element, config); 4267 this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element); 4268 this._backdrop = this._initializeBackDrop(); 4269 this._focustrap = this._initializeFocusTrap(); 4270 this._isShown = false; 4271 this._isTransitioning = false; 4272 this._scrollBar = new ScrollBarHelper(); 4273 this._addEventListeners(); 4274 } 4275 4276 // Getters 4277 static get Default() { 4278 return Default$6; 4279 } 4280 static get DefaultType() { 4281 return DefaultType$6; 4282 } 4283 static get NAME() { 4284 return NAME$7; 4285 } 4286 4287 // Public 4288 toggle(relatedTarget) { 4289 return this._isShown ? this.hide() : this.show(relatedTarget); 4290 } 4291 show(relatedTarget) { 4292 if (this._isShown || this._isTransitioning) { 4293 return; 4294 } 4295 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, { 4296 relatedTarget 4297 }); 4298 if (showEvent.defaultPrevented) { 4299 return; 4300 } 4301 this._isShown = true; 4302 this._isTransitioning = true; 4303 this._scrollBar.hide(); 4304 document.body.classList.add(CLASS_NAME_OPEN); 4305 this._adjustDialog(); 4306 this._backdrop.show(() => this._showElement(relatedTarget)); 4307 } 4308 hide() { 4309 if (!this._isShown || this._isTransitioning) { 4310 return; 4311 } 4312 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4); 4313 if (hideEvent.defaultPrevented) { 4314 return; 4315 } 4316 this._isShown = false; 4317 this._isTransitioning = true; 4318 this._focustrap.deactivate(); 4319 this._element.classList.remove(CLASS_NAME_SHOW$4); 4320 this._queueCallback(() => this._hideModal(), this._element, this._isAnimated()); 4321 } 4322 dispose() { 4323 EventHandler.off(window, EVENT_KEY$4); 4324 EventHandler.off(this._dialog, EVENT_KEY$4); 4325 this._backdrop.dispose(); 4326 this._focustrap.deactivate(); 4327 super.dispose(); 4328 } 4329 handleUpdate() { 4330 this._adjustDialog(); 4331 } 4332 4333 // Private 4334 _initializeBackDrop() { 4335 return new Backdrop({ 4336 isVisible: Boolean(this._config.backdrop), 4337 // 'static' option will be translated to true, and booleans will keep their value, 4338 isAnimated: this._isAnimated() 4339 }); 4340 } 4341 _initializeFocusTrap() { 4342 return new FocusTrap({ 4343 trapElement: this._element 4344 }); 4345 } 4346 _showElement(relatedTarget) { 4347 // try to append dynamic modal 4348 if (!document.body.contains(this._element)) { 4349 document.body.append(this._element); 4350 } 4351 this._element.style.display = 'block'; 4352 this._element.removeAttribute('aria-hidden'); 4353 this._element.setAttribute('aria-modal', true); 4354 this._element.setAttribute('role', 'dialog'); 4355 this._element.scrollTop = 0; 4356 const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog); 4357 if (modalBody) { 4358 modalBody.scrollTop = 0; 4359 } 4360 reflow(this._element); 4361 this._element.classList.add(CLASS_NAME_SHOW$4); 4362 const transitionComplete = () => { 4363 if (this._config.focus) { 4364 this._focustrap.activate(); 4365 } 4366 this._isTransitioning = false; 4367 EventHandler.trigger(this._element, EVENT_SHOWN$4, { 4368 relatedTarget 4369 }); 4370 }; 4371 this._queueCallback(transitionComplete, this._dialog, this._isAnimated()); 4372 } 4373 _addEventListeners() { 4374 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => { 4375 if (event.key !== ESCAPE_KEY$1) { 4376 return; 4377 } 4378 if (this._config.keyboard) { 4379 this.hide(); 4380 return; 4381 } 4382 this._triggerBackdropTransition(); 4383 }); 4384 EventHandler.on(window, EVENT_RESIZE$1, () => { 4385 if (this._isShown && !this._isTransitioning) { 4386 this._adjustDialog(); 4387 } 4388 }); 4389 EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => { 4390 // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks 4391 EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => { 4392 if (this._element !== event.target || this._element !== event2.target) { 4393 return; 4394 } 4395 if (this._config.backdrop === 'static') { 4396 this._triggerBackdropTransition(); 4397 return; 4398 } 4399 if (this._config.backdrop) { 4400 this.hide(); 4401 } 4402 }); 4403 }); 4404 } 4405 _hideModal() { 4406 this._element.style.display = 'none'; 4407 this._element.setAttribute('aria-hidden', true); 4408 this._element.removeAttribute('aria-modal'); 4409 this._element.removeAttribute('role'); 4410 this._isTransitioning = false; 4411 this._backdrop.hide(() => { 4412 document.body.classList.remove(CLASS_NAME_OPEN); 4413 this._resetAdjustments(); 4414 this._scrollBar.reset(); 4415 EventHandler.trigger(this._element, EVENT_HIDDEN$4); 4416 }); 4417 } 4418 _isAnimated() { 4419 return this._element.classList.contains(CLASS_NAME_FADE$3); 4420 } 4421 _triggerBackdropTransition() { 4422 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1); 4423 if (hideEvent.defaultPrevented) { 4424 return; 4425 } 4426 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 4427 const initialOverflowY = this._element.style.overflowY; 4428 // return if the following background transition hasn't yet completed 4429 if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) { 4430 return; 4431 } 4432 if (!isModalOverflowing) { 4433 this._element.style.overflowY = 'hidden'; 4434 } 4435 this._element.classList.add(CLASS_NAME_STATIC); 4436 this._queueCallback(() => { 4437 this._element.classList.remove(CLASS_NAME_STATIC); 4438 this._queueCallback(() => { 4439 this._element.style.overflowY = initialOverflowY; 4440 }, this._dialog); 4441 }, this._dialog); 4442 this._element.focus(); 4443 } 4444 4445 /** 4446 * The following methods are used to handle overflowing modals 4447 */ 4448 4449 _adjustDialog() { 4450 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 4451 const scrollbarWidth = this._scrollBar.getWidth(); 4452 const isBodyOverflowing = scrollbarWidth > 0; 4453 if (isBodyOverflowing && !isModalOverflowing) { 4454 const property = isRTL() ? 'paddingLeft' : 'paddingRight'; 4455 this._element.style[property] = `${scrollbarWidth}px`; 4456 } 4457 if (!isBodyOverflowing && isModalOverflowing) { 4458 const property = isRTL() ? 'paddingRight' : 'paddingLeft'; 4459 this._element.style[property] = `${scrollbarWidth}px`; 4460 } 4461 } 4462 _resetAdjustments() { 4463 this._element.style.paddingLeft = ''; 4464 this._element.style.paddingRight = ''; 4465 } 4466 4467 // Static 4468 static jQueryInterface(config, relatedTarget) { 4469 return this.each(function () { 4470 const data = Modal.getOrCreateInstance(this, config); 4471 if (typeof config !== 'string') { 4472 return; 4473 } 4474 if (typeof data[config] === 'undefined') { 4475 throw new TypeError(`No method named "${config}"`); 4476 } 4477 data[config](relatedTarget); 4478 }); 4479 } 4480 } 4481 4482 /** 4483 * Data API implementation 4484 */ 4485 4486 EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) { 4487 const target = SelectorEngine.getElementFromSelector(this); 4488 if (['A', 'AREA'].includes(this.tagName)) { 4489 event.preventDefault(); 4490 } 4491 EventHandler.one(target, EVENT_SHOW$4, showEvent => { 4492 if (showEvent.defaultPrevented) { 4493 // only register focus restorer if modal will actually get shown 4494 return; 4495 } 4496 EventHandler.one(target, EVENT_HIDDEN$4, () => { 4497 if (isVisible(this)) { 4498 this.focus(); 4499 } 4500 }); 4501 }); 4502 4503 // avoid conflict when clicking modal toggler while another one is open 4504 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1); 4505 if (alreadyOpen) { 4506 Modal.getInstance(alreadyOpen).hide(); 4507 } 4508 const data = Modal.getOrCreateInstance(target); 4509 data.toggle(this); 4510 }); 4511 enableDismissTrigger(Modal); 4512 4513 /** 4514 * jQuery 4515 */ 4516 4517 defineJQueryPlugin(Modal); 4518 4519 /** 4520 * -------------------------------------------------------------------------- 4521 * Bootstrap offcanvas.js 4522 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4523 * -------------------------------------------------------------------------- 4524 */ 4525 4526 4527 /** 4528 * Constants 4529 */ 4530 4531 const NAME$6 = 'offcanvas'; 4532 const DATA_KEY$3 = 'bs.offcanvas'; 4533 const EVENT_KEY$3 = `.${DATA_KEY$3}`; 4534 const DATA_API_KEY$1 = '.data-api'; 4535 const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`; 4536 const ESCAPE_KEY = 'Escape'; 4537 const CLASS_NAME_SHOW$3 = 'show'; 4538 const CLASS_NAME_SHOWING$1 = 'showing'; 4539 const CLASS_NAME_HIDING = 'hiding'; 4540 const CLASS_NAME_BACKDROP = 'offcanvas-backdrop'; 4541 const OPEN_SELECTOR = '.offcanvas.show'; 4542 const EVENT_SHOW$3 = `show${EVENT_KEY$3}`; 4543 const EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`; 4544 const EVENT_HIDE$3 = `hide${EVENT_KEY$3}`; 4545 const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`; 4546 const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`; 4547 const EVENT_RESIZE = `resize${EVENT_KEY$3}`; 4548 const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`; 4549 const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`; 4550 const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="offcanvas"]'; 4551 const Default$5 = { 4552 backdrop: true, 4553 keyboard: true, 4554 scroll: false 4555 }; 4556 const DefaultType$5 = { 4557 backdrop: '(boolean|string)', 4558 keyboard: 'boolean', 4559 scroll: 'boolean' 4560 }; 4561 4562 /** 4563 * Class definition 4564 */ 4565 4566 class Offcanvas extends BaseComponent { 4567 constructor(element, config) { 4568 super(element, config); 4569 this._isShown = false; 4570 this._backdrop = this._initializeBackDrop(); 4571 this._focustrap = this._initializeFocusTrap(); 4572 this._addEventListeners(); 4573 } 4574 4575 // Getters 4576 static get Default() { 4577 return Default$5; 4578 } 4579 static get DefaultType() { 4580 return DefaultType$5; 4581 } 4582 static get NAME() { 4583 return NAME$6; 4584 } 4585 4586 // Public 4587 toggle(relatedTarget) { 4588 return this._isShown ? this.hide() : this.show(relatedTarget); 4589 } 4590 show(relatedTarget) { 4591 if (this._isShown) { 4592 return; 4593 } 4594 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, { 4595 relatedTarget 4596 }); 4597 if (showEvent.defaultPrevented) { 4598 return; 4599 } 4600 this._isShown = true; 4601 this._backdrop.show(); 4602 if (!this._config.scroll) { 4603 new ScrollBarHelper().hide(); 4604 } 4605 this._element.setAttribute('aria-modal', true); 4606 this._element.setAttribute('role', 'dialog'); 4607 this._element.classList.add(CLASS_NAME_SHOWING$1); 4608 const completeCallBack = () => { 4609 if (!this._config.scroll || this._config.backdrop) { 4610 this._focustrap.activate(); 4611 } 4612 this._element.classList.add(CLASS_NAME_SHOW$3); 4613 this._element.classList.remove(CLASS_NAME_SHOWING$1); 4614 EventHandler.trigger(this._element, EVENT_SHOWN$3, { 4615 relatedTarget 4616 }); 4617 }; 4618 this._queueCallback(completeCallBack, this._element, true); 4619 } 4620 hide() { 4621 if (!this._isShown) { 4622 return; 4623 } 4624 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3); 4625 if (hideEvent.defaultPrevented) { 4626 return; 4627 } 4628 this._focustrap.deactivate(); 4629 this._element.blur(); 4630 this._isShown = false; 4631 this._element.classList.add(CLASS_NAME_HIDING); 4632 this._backdrop.hide(); 4633 const completeCallback = () => { 4634 this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING); 4635 this._element.removeAttribute('aria-modal'); 4636 this._element.removeAttribute('role'); 4637 if (!this._config.scroll) { 4638 new ScrollBarHelper().reset(); 4639 } 4640 EventHandler.trigger(this._element, EVENT_HIDDEN$3); 4641 }; 4642 this._queueCallback(completeCallback, this._element, true); 4643 } 4644 dispose() { 4645 this._backdrop.dispose(); 4646 this._focustrap.deactivate(); 4647 super.dispose(); 4648 } 4649 4650 // Private 4651 _initializeBackDrop() { 4652 const clickCallback = () => { 4653 if (this._config.backdrop === 'static') { 4654 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); 4655 return; 4656 } 4657 this.hide(); 4658 }; 4659 4660 // 'static' option will be translated to true, and booleans will keep their value 4661 const isVisible = Boolean(this._config.backdrop); 4662 return new Backdrop({ 4663 className: CLASS_NAME_BACKDROP, 4664 isVisible, 4665 isAnimated: true, 4666 rootElement: this._element.parentNode, 4667 clickCallback: isVisible ? clickCallback : null 4668 }); 4669 } 4670 _initializeFocusTrap() { 4671 return new FocusTrap({ 4672 trapElement: this._element 4673 }); 4674 } 4675 _addEventListeners() { 4676 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => { 4677 if (event.key !== ESCAPE_KEY) { 4678 return; 4679 } 4680 if (this._config.keyboard) { 4681 this.hide(); 4682 return; 4683 } 4684 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); 4685 }); 4686 } 4687 4688 // Static 4689 static jQueryInterface(config) { 4690 return this.each(function () { 4691 const data = Offcanvas.getOrCreateInstance(this, config); 4692 if (typeof config !== 'string') { 4693 return; 4694 } 4695 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 4696 throw new TypeError(`No method named "${config}"`); 4697 } 4698 data[config](this); 4699 }); 4700 } 4701 } 4702 4703 /** 4704 * Data API implementation 4705 */ 4706 4707 EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) { 4708 const target = SelectorEngine.getElementFromSelector(this); 4709 if (['A', 'AREA'].includes(this.tagName)) { 4710 event.preventDefault(); 4711 } 4712 if (isDisabled(this)) { 4713 return; 4714 } 4715 EventHandler.one(target, EVENT_HIDDEN$3, () => { 4716 // focus on trigger when it is closed 4717 if (isVisible(this)) { 4718 this.focus(); 4719 } 4720 }); 4721 4722 // avoid conflict when clicking a toggler of an offcanvas, while another is open 4723 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR); 4724 if (alreadyOpen && alreadyOpen !== target) { 4725 Offcanvas.getInstance(alreadyOpen).hide(); 4726 } 4727 const data = Offcanvas.getOrCreateInstance(target); 4728 data.toggle(this); 4729 }); 4730 EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => { 4731 for (const selector of SelectorEngine.find(OPEN_SELECTOR)) { 4732 Offcanvas.getOrCreateInstance(selector).show(); 4733 } 4734 }); 4735 EventHandler.on(window, EVENT_RESIZE, () => { 4736 for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) { 4737 if (getComputedStyle(element).position !== 'fixed') { 4738 Offcanvas.getOrCreateInstance(element).hide(); 4739 } 4740 } 4741 }); 4742 enableDismissTrigger(Offcanvas); 4743 4744 /** 4745 * jQuery 4746 */ 4747 4748 defineJQueryPlugin(Offcanvas); 4749 4750 /** 4751 * -------------------------------------------------------------------------- 4752 * Bootstrap util/sanitizer.js 4753 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4754 * -------------------------------------------------------------------------- 4755 */ 4756 4757 // js-docs-start allow-list 4758 const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; 4759 const DefaultAllowlist = { 4760 // Global attributes allowed on any supplied element below. 4761 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], 4762 a: ['target', 'href', 'title', 'rel'], 4763 area: [], 4764 b: [], 4765 br: [], 4766 col: [], 4767 code: [], 4768 dd: [], 4769 div: [], 4770 dl: [], 4771 dt: [], 4772 em: [], 4773 hr: [], 4774 h1: [], 4775 h2: [], 4776 h3: [], 4777 h4: [], 4778 h5: [], 4779 h6: [], 4780 i: [], 4781 img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], 4782 li: [], 4783 ol: [], 4784 p: [], 4785 pre: [], 4786 s: [], 4787 small: [], 4788 span: [], 4789 sub: [], 4790 sup: [], 4791 strong: [], 4792 u: [], 4793 ul: [] 4794 }; 4795 // js-docs-end allow-list 4796 4797 const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']); 4798 4799 /** 4800 * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation 4801 * contexts. 4802 * 4803 * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38 4804 */ 4805 const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i; 4806 const allowedAttribute = (attribute, allowedAttributeList) => { 4807 const attributeName = attribute.nodeName.toLowerCase(); 4808 if (allowedAttributeList.includes(attributeName)) { 4809 if (uriAttributes.has(attributeName)) { 4810 return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue)); 4811 } 4812 return true; 4813 } 4814 4815 // Check if a regular expression validates the attribute. 4816 return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName)); 4817 }; 4818 function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) { 4819 if (!unsafeHtml.length) { 4820 return unsafeHtml; 4821 } 4822 if (sanitizeFunction && typeof sanitizeFunction === 'function') { 4823 return sanitizeFunction(unsafeHtml); 4824 } 4825 const domParser = new window.DOMParser(); 4826 const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); 4827 const elements = [].concat(...createdDocument.body.querySelectorAll('*')); 4828 for (const element of elements) { 4829 const elementName = element.nodeName.toLowerCase(); 4830 if (!Object.keys(allowList).includes(elementName)) { 4831 element.remove(); 4832 continue; 4833 } 4834 const attributeList = [].concat(...element.attributes); 4835 const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []); 4836 for (const attribute of attributeList) { 4837 if (!allowedAttribute(attribute, allowedAttributes)) { 4838 element.removeAttribute(attribute.nodeName); 4839 } 4840 } 4841 } 4842 return createdDocument.body.innerHTML; 4843 } 4844 4845 /** 4846 * -------------------------------------------------------------------------- 4847 * Bootstrap util/template-factory.js 4848 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4849 * -------------------------------------------------------------------------- 4850 */ 4851 4852 4853 /** 4854 * Constants 4855 */ 4856 4857 const NAME$5 = 'TemplateFactory'; 4858 const Default$4 = { 4859 allowList: DefaultAllowlist, 4860 content: {}, 4861 // { selector : text , selector2 : text2 , } 4862 extraClass: '', 4863 html: false, 4864 sanitize: true, 4865 sanitizeFn: null, 4866 template: '<div></div>' 4867 }; 4868 const DefaultType$4 = { 4869 allowList: 'object', 4870 content: 'object', 4871 extraClass: '(string|function)', 4872 html: 'boolean', 4873 sanitize: 'boolean', 4874 sanitizeFn: '(null|function)', 4875 template: 'string' 4876 }; 4877 const DefaultContentType = { 4878 entry: '(string|element|function|null)', 4879 selector: '(string|element)' 4880 }; 4881 4882 /** 4883 * Class definition 4884 */ 4885 4886 class TemplateFactory extends Config { 4887 constructor(config) { 4888 super(); 4889 this._config = this._getConfig(config); 4890 } 4891 4892 // Getters 4893 static get Default() { 4894 return Default$4; 4895 } 4896 static get DefaultType() { 4897 return DefaultType$4; 4898 } 4899 static get NAME() { 4900 return NAME$5; 4901 } 4902 4903 // Public 4904 getContent() { 4905 return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean); 4906 } 4907 hasContent() { 4908 return this.getContent().length > 0; 4909 } 4910 changeContent(content) { 4911 this._checkContent(content); 4912 this._config.content = { 4913 ...this._config.content, 4914 ...content 4915 }; 4916 return this; 4917 } 4918 toHtml() { 4919 const templateWrapper = document.createElement('div'); 4920 templateWrapper.innerHTML = this._maybeSanitize(this._config.template); 4921 for (const [selector, text] of Object.entries(this._config.content)) { 4922 this._setContent(templateWrapper, text, selector); 4923 } 4924 const template = templateWrapper.children[0]; 4925 const extraClass = this._resolvePossibleFunction(this._config.extraClass); 4926 if (extraClass) { 4927 template.classList.add(...extraClass.split(' ')); 4928 } 4929 return template; 4930 } 4931 4932 // Private 4933 _typeCheckConfig(config) { 4934 super._typeCheckConfig(config); 4935 this._checkContent(config.content); 4936 } 4937 _checkContent(arg) { 4938 for (const [selector, content] of Object.entries(arg)) { 4939 super._typeCheckConfig({ 4940 selector, 4941 entry: content 4942 }, DefaultContentType); 4943 } 4944 } 4945 _setContent(template, content, selector) { 4946 const templateElement = SelectorEngine.findOne(selector, template); 4947 if (!templateElement) { 4948 return; 4949 } 4950 content = this._resolvePossibleFunction(content); 4951 if (!content) { 4952 templateElement.remove(); 4953 return; 4954 } 4955 if (isElement$1(content)) { 4956 this._putElementInTemplate(getElement(content), templateElement); 4957 return; 4958 } 4959 if (this._config.html) { 4960 templateElement.innerHTML = this._maybeSanitize(content); 4961 return; 4962 } 4963 templateElement.textContent = content; 4964 } 4965 _maybeSanitize(arg) { 4966 return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg; 4967 } 4968 _resolvePossibleFunction(arg) { 4969 return execute(arg, [undefined, this]); 4970 } 4971 _putElementInTemplate(element, templateElement) { 4972 if (this._config.html) { 4973 templateElement.innerHTML = ''; 4974 templateElement.append(element); 4975 return; 4976 } 4977 templateElement.textContent = element.textContent; 4978 } 4979 } 4980 4981 /** 4982 * -------------------------------------------------------------------------- 4983 * Bootstrap tooltip.js 4984 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4985 * -------------------------------------------------------------------------- 4986 */ 4987 4988 4989 /** 4990 * Constants 4991 */ 4992 4993 const NAME$4 = 'tooltip'; 4994 const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']); 4995 const CLASS_NAME_FADE$2 = 'fade'; 4996 const CLASS_NAME_MODAL = 'modal'; 4997 const CLASS_NAME_SHOW$2 = 'show'; 4998 const SELECTOR_TOOLTIP_INNER = '.tooltip-inner'; 4999 const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`; 5000 const EVENT_MODAL_HIDE = 'hide.bs.modal'; 5001 const TRIGGER_HOVER = 'hover'; 5002 const TRIGGER_FOCUS = 'focus'; 5003 const TRIGGER_CLICK = 'click'; 5004 const TRIGGER_MANUAL = 'manual'; 5005 const EVENT_HIDE$2 = 'hide'; 5006 const EVENT_HIDDEN$2 = 'hidden'; 5007 const EVENT_SHOW$2 = 'show'; 5008 const EVENT_SHOWN$2 = 'shown'; 5009 const EVENT_INSERTED = 'inserted'; 5010 const EVENT_CLICK$1 = 'click'; 5011 const EVENT_FOCUSIN$1 = 'focusin'; 5012 const EVENT_FOCUSOUT$1 = 'focusout'; 5013 const EVENT_MOUSEENTER = 'mouseenter'; 5014 const EVENT_MOUSELEAVE = 'mouseleave'; 5015 const AttachmentMap = { 5016 AUTO: 'auto', 5017 TOP: 'top', 5018 RIGHT: isRTL() ? 'left' : 'right', 5019 BOTTOM: 'bottom', 5020 LEFT: isRTL() ? 'right' : 'left' 5021 }; 5022 const Default$3 = { 5023 allowList: DefaultAllowlist, 5024 animation: true, 5025 boundary: 'clippingParents', 5026 container: false, 5027 customClass: '', 5028 delay: 0, 5029 fallbackPlacements: ['top', 'right', 'bottom', 'left'], 5030 html: false, 5031 offset: [0, 6], 5032 placement: 'top', 5033 popperConfig: null, 5034 sanitize: true, 5035 sanitizeFn: null, 5036 selector: false, 5037 template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>', 5038 title: '', 5039 trigger: 'hover focus' 5040 }; 5041 const DefaultType$3 = { 5042 allowList: 'object', 5043 animation: 'boolean', 5044 boundary: '(string|element)', 5045 container: '(string|element|boolean)', 5046 customClass: '(string|function)', 5047 delay: '(number|object)', 5048 fallbackPlacements: 'array', 5049 html: 'boolean', 5050 offset: '(array|string|function)', 5051 placement: '(string|function)', 5052 popperConfig: '(null|object|function)', 5053 sanitize: 'boolean', 5054 sanitizeFn: '(null|function)', 5055 selector: '(string|boolean)', 5056 template: 'string', 5057 title: '(string|element|function)', 5058 trigger: 'string' 5059 }; 5060 5061 /** 5062 * Class definition 5063 */ 5064 5065 class Tooltip extends BaseComponent { 5066 constructor(element, config) { 5067 if (typeof Popper === 'undefined') { 5068 throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org/docs/v2/)'); 5069 } 5070 super(element, config); 5071 5072 // Private 5073 this._isEnabled = true; 5074 this._timeout = 0; 5075 this._isHovered = null; 5076 this._activeTrigger = {}; 5077 this._popper = null; 5078 this._templateFactory = null; 5079 this._newContent = null; 5080 5081 // Protected 5082 this.tip = null; 5083 this._setListeners(); 5084 if (!this._config.selector) { 5085 this._fixTitle(); 5086 } 5087 } 5088 5089 // Getters 5090 static get Default() { 5091 return Default$3; 5092 } 5093 static get DefaultType() { 5094 return DefaultType$3; 5095 } 5096 static get NAME() { 5097 return NAME$4; 5098 } 5099 5100 // Public 5101 enable() { 5102 this._isEnabled = true; 5103 } 5104 disable() { 5105 this._isEnabled = false; 5106 } 5107 toggleEnabled() { 5108 this._isEnabled = !this._isEnabled; 5109 } 5110 toggle() { 5111 if (!this._isEnabled) { 5112 return; 5113 } 5114 if (this._isShown()) { 5115 this._leave(); 5116 return; 5117 } 5118 this._enter(); 5119 } 5120 dispose() { 5121 clearTimeout(this._timeout); 5122 EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); 5123 if (this._element.getAttribute('data-bs-original-title')) { 5124 this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title')); 5125 } 5126 this._disposePopper(); 5127 super.dispose(); 5128 } 5129 show() { 5130 if (this._element.style.display === 'none') { 5131 throw new Error('Please use show on visible elements'); 5132 } 5133 if (!(this._isWithContent() && this._isEnabled)) { 5134 return; 5135 } 5136 const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2)); 5137 const shadowRoot = findShadowRoot(this._element); 5138 const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element); 5139 if (showEvent.defaultPrevented || !isInTheDom) { 5140 return; 5141 } 5142 5143 // TODO: v6 remove this or make it optional 5144 this._disposePopper(); 5145 const tip = this._getTipElement(); 5146 this._element.setAttribute('aria-describedby', tip.getAttribute('id')); 5147 const { 5148 container 5149 } = this._config; 5150 if (!this._element.ownerDocument.documentElement.contains(this.tip)) { 5151 container.append(tip); 5152 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED)); 5153 } 5154 this._popper = this._createPopper(tip); 5155 tip.classList.add(CLASS_NAME_SHOW$2); 5156 5157 // If this is a touch-enabled device we add extra 5158 // empty mouseover listeners to the body's immediate children; 5159 // only needed because of broken event delegation on iOS 5160 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 5161 if ('ontouchstart' in document.documentElement) { 5162 for (const element of [].concat(...document.body.children)) { 5163 EventHandler.on(element, 'mouseover', noop); 5164 } 5165 } 5166 const complete = () => { 5167 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2)); 5168 if (this._isHovered === false) { 5169 this._leave(); 5170 } 5171 this._isHovered = false; 5172 }; 5173 this._queueCallback(complete, this.tip, this._isAnimated()); 5174 } 5175 hide() { 5176 if (!this._isShown()) { 5177 return; 5178 } 5179 const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2)); 5180 if (hideEvent.defaultPrevented) { 5181 return; 5182 } 5183 const tip = this._getTipElement(); 5184 tip.classList.remove(CLASS_NAME_SHOW$2); 5185 5186 // If this is a touch-enabled device we remove the extra 5187 // empty mouseover listeners we added for iOS support 5188 if ('ontouchstart' in document.documentElement) { 5189 for (const element of [].concat(...document.body.children)) { 5190 EventHandler.off(element, 'mouseover', noop); 5191 } 5192 } 5193 this._activeTrigger[TRIGGER_CLICK] = false; 5194 this._activeTrigger[TRIGGER_FOCUS] = false; 5195 this._activeTrigger[TRIGGER_HOVER] = false; 5196 this._isHovered = null; // it is a trick to support manual triggering 5197 5198 const complete = () => { 5199 if (this._isWithActiveTrigger()) { 5200 return; 5201 } 5202 if (!this._isHovered) { 5203 this._disposePopper(); 5204 } 5205 this._element.removeAttribute('aria-describedby'); 5206 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2)); 5207 }; 5208 this._queueCallback(complete, this.tip, this._isAnimated()); 5209 } 5210 update() { 5211 if (this._popper) { 5212 this._popper.update(); 5213 } 5214 } 5215 5216 // Protected 5217 _isWithContent() { 5218 return Boolean(this._getTitle()); 5219 } 5220 _getTipElement() { 5221 if (!this.tip) { 5222 this.tip = this._createTipElement(this._newContent || this._getContentForTemplate()); 5223 } 5224 return this.tip; 5225 } 5226 _createTipElement(content) { 5227 const tip = this._getTemplateFactory(content).toHtml(); 5228 5229 // TODO: remove this check in v6 5230 if (!tip) { 5231 return null; 5232 } 5233 tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2); 5234 // TODO: v6 the following can be achieved with CSS only 5235 tip.classList.add(`bs-${this.constructor.NAME}-auto`); 5236 const tipId = getUID(this.constructor.NAME).toString(); 5237 tip.setAttribute('id', tipId); 5238 if (this._isAnimated()) { 5239 tip.classList.add(CLASS_NAME_FADE$2); 5240 } 5241 return tip; 5242 } 5243 setContent(content) { 5244 this._newContent = content; 5245 if (this._isShown()) { 5246 this._disposePopper(); 5247 this.show(); 5248 } 5249 } 5250 _getTemplateFactory(content) { 5251 if (this._templateFactory) { 5252 this._templateFactory.changeContent(content); 5253 } else { 5254 this._templateFactory = new TemplateFactory({ 5255 ...this._config, 5256 // the `content` var has to be after `this._config` 5257 // to override config.content in case of popover 5258 content, 5259 extraClass: this._resolvePossibleFunction(this._config.customClass) 5260 }); 5261 } 5262 return this._templateFactory; 5263 } 5264 _getContentForTemplate() { 5265 return { 5266 [SELECTOR_TOOLTIP_INNER]: this._getTitle() 5267 }; 5268 } 5269 _getTitle() { 5270 return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title'); 5271 } 5272 5273 // Private 5274 _initializeOnDelegatedTarget(event) { 5275 return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig()); 5276 } 5277 _isAnimated() { 5278 return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2); 5279 } 5280 _isShown() { 5281 return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2); 5282 } 5283 _createPopper(tip) { 5284 const placement = execute(this._config.placement, [this, tip, this._element]); 5285 const attachment = AttachmentMap[placement.toUpperCase()]; 5286 return createPopper(this._element, tip, this._getPopperConfig(attachment)); 5287 } 5288 _getOffset() { 5289 const { 5290 offset 5291 } = this._config; 5292 if (typeof offset === 'string') { 5293 return offset.split(',').map(value => Number.parseInt(value, 10)); 5294 } 5295 if (typeof offset === 'function') { 5296 return popperData => offset(popperData, this._element); 5297 } 5298 return offset; 5299 } 5300 _resolvePossibleFunction(arg) { 5301 return execute(arg, [this._element, this._element]); 5302 } 5303 _getPopperConfig(attachment) { 5304 const defaultBsPopperConfig = { 5305 placement: attachment, 5306 modifiers: [{ 5307 name: 'flip', 5308 options: { 5309 fallbackPlacements: this._config.fallbackPlacements 5310 } 5311 }, { 5312 name: 'offset', 5313 options: { 5314 offset: this._getOffset() 5315 } 5316 }, { 5317 name: 'preventOverflow', 5318 options: { 5319 boundary: this._config.boundary 5320 } 5321 }, { 5322 name: 'arrow', 5323 options: { 5324 element: `.${this.constructor.NAME}-arrow` 5325 } 5326 }, { 5327 name: 'preSetPlacement', 5328 enabled: true, 5329 phase: 'beforeMain', 5330 fn: data => { 5331 // Pre-set Popper's placement attribute in order to read the arrow sizes properly. 5332 // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement 5333 this._getTipElement().setAttribute('data-popper-placement', data.state.placement); 5334 } 5335 }] 5336 }; 5337 return { 5338 ...defaultBsPopperConfig, 5339 ...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig]) 5340 }; 5341 } 5342 _setListeners() { 5343 const triggers = this._config.trigger.split(' '); 5344 for (const trigger of triggers) { 5345 if (trigger === 'click') { 5346 EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => { 5347 const context = this._initializeOnDelegatedTarget(event); 5348 context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK]); 5349 context.toggle(); 5350 }); 5351 } else if (trigger !== TRIGGER_MANUAL) { 5352 const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1); 5353 const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1); 5354 EventHandler.on(this._element, eventIn, this._config.selector, event => { 5355 const context = this._initializeOnDelegatedTarget(event); 5356 context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; 5357 context._enter(); 5358 }); 5359 EventHandler.on(this._element, eventOut, this._config.selector, event => { 5360 const context = this._initializeOnDelegatedTarget(event); 5361 context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget); 5362 context._leave(); 5363 }); 5364 } 5365 } 5366 this._hideModalHandler = () => { 5367 if (this._element) { 5368 this.hide(); 5369 } 5370 }; 5371 EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); 5372 } 5373 _fixTitle() { 5374 const title = this._element.getAttribute('title'); 5375 if (!title) { 5376 return; 5377 } 5378 if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) { 5379 this._element.setAttribute('aria-label', title); 5380 } 5381 this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility 5382 this._element.removeAttribute('title'); 5383 } 5384 _enter() { 5385 if (this._isShown() || this._isHovered) { 5386 this._isHovered = true; 5387 return; 5388 } 5389 this._isHovered = true; 5390 this._setTimeout(() => { 5391 if (this._isHovered) { 5392 this.show(); 5393 } 5394 }, this._config.delay.show); 5395 } 5396 _leave() { 5397 if (this._isWithActiveTrigger()) { 5398 return; 5399 } 5400 this._isHovered = false; 5401 this._setTimeout(() => { 5402 if (!this._isHovered) { 5403 this.hide(); 5404 } 5405 }, this._config.delay.hide); 5406 } 5407 _setTimeout(handler, timeout) { 5408 clearTimeout(this._timeout); 5409 this._timeout = setTimeout(handler, timeout); 5410 } 5411 _isWithActiveTrigger() { 5412 return Object.values(this._activeTrigger).includes(true); 5413 } 5414 _getConfig(config) { 5415 const dataAttributes = Manipulator.getDataAttributes(this._element); 5416 for (const dataAttribute of Object.keys(dataAttributes)) { 5417 if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) { 5418 delete dataAttributes[dataAttribute]; 5419 } 5420 } 5421 config = { 5422 ...dataAttributes, 5423 ...(typeof config === 'object' && config ? config : {}) 5424 }; 5425 config = this._mergeConfigObj(config); 5426 config = this._configAfterMerge(config); 5427 this._typeCheckConfig(config); 5428 return config; 5429 } 5430 _configAfterMerge(config) { 5431 config.container = config.container === false ? document.body : getElement(config.container); 5432 if (typeof config.delay === 'number') { 5433 config.delay = { 5434 show: config.delay, 5435 hide: config.delay 5436 }; 5437 } 5438 if (typeof config.title === 'number') { 5439 config.title = config.title.toString(); 5440 } 5441 if (typeof config.content === 'number') { 5442 config.content = config.content.toString(); 5443 } 5444 return config; 5445 } 5446 _getDelegateConfig() { 5447 const config = {}; 5448 for (const [key, value] of Object.entries(this._config)) { 5449 if (this.constructor.Default[key] !== value) { 5450 config[key] = value; 5451 } 5452 } 5453 config.selector = false; 5454 config.trigger = 'manual'; 5455 5456 // In the future can be replaced with: 5457 // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]]) 5458 // `Object.fromEntries(keysWithDifferentValues)` 5459 return config; 5460 } 5461 _disposePopper() { 5462 if (this._popper) { 5463 this._popper.destroy(); 5464 this._popper = null; 5465 } 5466 if (this.tip) { 5467 this.tip.remove(); 5468 this.tip = null; 5469 } 5470 } 5471 5472 // Static 5473 static jQueryInterface(config) { 5474 return this.each(function () { 5475 const data = Tooltip.getOrCreateInstance(this, config); 5476 if (typeof config !== 'string') { 5477 return; 5478 } 5479 if (typeof data[config] === 'undefined') { 5480 throw new TypeError(`No method named "${config}"`); 5481 } 5482 data[config](); 5483 }); 5484 } 5485 } 5486 5487 /** 5488 * jQuery 5489 */ 5490 5491 defineJQueryPlugin(Tooltip); 5492 5493 /** 5494 * -------------------------------------------------------------------------- 5495 * Bootstrap popover.js 5496 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5497 * -------------------------------------------------------------------------- 5498 */ 5499 5500 5501 /** 5502 * Constants 5503 */ 5504 5505 const NAME$3 = 'popover'; 5506 const SELECTOR_TITLE = '.popover-header'; 5507 const SELECTOR_CONTENT = '.popover-body'; 5508 const Default$2 = { 5509 ...Tooltip.Default, 5510 content: '', 5511 offset: [0, 8], 5512 placement: 'right', 5513 template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div>' + '</div>', 5514 trigger: 'click' 5515 }; 5516 const DefaultType$2 = { 5517 ...Tooltip.DefaultType, 5518 content: '(null|string|element|function)' 5519 }; 5520 5521 /** 5522 * Class definition 5523 */ 5524 5525 class Popover extends Tooltip { 5526 // Getters 5527 static get Default() { 5528 return Default$2; 5529 } 5530 static get DefaultType() { 5531 return DefaultType$2; 5532 } 5533 static get NAME() { 5534 return NAME$3; 5535 } 5536 5537 // Overrides 5538 _isWithContent() { 5539 return this._getTitle() || this._getContent(); 5540 } 5541 5542 // Private 5543 _getContentForTemplate() { 5544 return { 5545 [SELECTOR_TITLE]: this._getTitle(), 5546 [SELECTOR_CONTENT]: this._getContent() 5547 }; 5548 } 5549 _getContent() { 5550 return this._resolvePossibleFunction(this._config.content); 5551 } 5552 5553 // Static 5554 static jQueryInterface(config) { 5555 return this.each(function () { 5556 const data = Popover.getOrCreateInstance(this, config); 5557 if (typeof config !== 'string') { 5558 return; 5559 } 5560 if (typeof data[config] === 'undefined') { 5561 throw new TypeError(`No method named "${config}"`); 5562 } 5563 data[config](); 5564 }); 5565 } 5566 } 5567 5568 /** 5569 * jQuery 5570 */ 5571 5572 defineJQueryPlugin(Popover); 5573 5574 /** 5575 * -------------------------------------------------------------------------- 5576 * Bootstrap scrollspy.js 5577 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5578 * -------------------------------------------------------------------------- 5579 */ 5580 5581 5582 /** 5583 * Constants 5584 */ 5585 5586 const NAME$2 = 'scrollspy'; 5587 const DATA_KEY$2 = 'bs.scrollspy'; 5588 const EVENT_KEY$2 = `.${DATA_KEY$2}`; 5589 const DATA_API_KEY = '.data-api'; 5590 const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`; 5591 const EVENT_CLICK = `click${EVENT_KEY$2}`; 5592 const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`; 5593 const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'; 5594 const CLASS_NAME_ACTIVE$1 = 'active'; 5595 const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]'; 5596 const SELECTOR_TARGET_LINKS = '[href]'; 5597 const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'; 5598 const SELECTOR_NAV_LINKS = '.nav-link'; 5599 const SELECTOR_NAV_ITEMS = '.nav-item'; 5600 const SELECTOR_LIST_ITEMS = '.list-group-item'; 5601 const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`; 5602 const SELECTOR_DROPDOWN = '.dropdown'; 5603 const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle'; 5604 const Default$1 = { 5605 offset: null, 5606 // TODO: v6 @deprecated, keep it for backwards compatibility reasons 5607 rootMargin: '0px 0px -25%', 5608 smoothScroll: false, 5609 target: null, 5610 threshold: [0.1, 0.5, 1] 5611 }; 5612 const DefaultType$1 = { 5613 offset: '(number|null)', 5614 // TODO v6 @deprecated, keep it for backwards compatibility reasons 5615 rootMargin: 'string', 5616 smoothScroll: 'boolean', 5617 target: 'element', 5618 threshold: 'array' 5619 }; 5620 5621 /** 5622 * Class definition 5623 */ 5624 5625 class ScrollSpy extends BaseComponent { 5626 constructor(element, config) { 5627 super(element, config); 5628 5629 // this._element is the observablesContainer and config.target the menu links wrapper 5630 this._targetLinks = new Map(); 5631 this._observableSections = new Map(); 5632 this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element; 5633 this._activeTarget = null; 5634 this._observer = null; 5635 this._previousScrollData = { 5636 visibleEntryTop: 0, 5637 parentScrollTop: 0 5638 }; 5639 this.refresh(); // initialize 5640 } 5641 5642 // Getters 5643 static get Default() { 5644 return Default$1; 5645 } 5646 static get DefaultType() { 5647 return DefaultType$1; 5648 } 5649 static get NAME() { 5650 return NAME$2; 5651 } 5652 5653 // Public 5654 refresh() { 5655 this._initializeTargetsAndObservables(); 5656 this._maybeEnableSmoothScroll(); 5657 if (this._observer) { 5658 this._observer.disconnect(); 5659 } else { 5660 this._observer = this._getNewObserver(); 5661 } 5662 for (const section of this._observableSections.values()) { 5663 this._observer.observe(section); 5664 } 5665 } 5666 dispose() { 5667 this._observer.disconnect(); 5668 super.dispose(); 5669 } 5670 5671 // Private 5672 _configAfterMerge(config) { 5673 // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case 5674 config.target = getElement(config.target) || document.body; 5675 5676 // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only 5677 config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin; 5678 if (typeof config.threshold === 'string') { 5679 config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value)); 5680 } 5681 return config; 5682 } 5683 _maybeEnableSmoothScroll() { 5684 if (!this._config.smoothScroll) { 5685 return; 5686 } 5687 5688 // unregister any previous listeners 5689 EventHandler.off(this._config.target, EVENT_CLICK); 5690 EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => { 5691 const observableSection = this._observableSections.get(event.target.hash); 5692 if (observableSection) { 5693 event.preventDefault(); 5694 const root = this._rootElement || window; 5695 const height = observableSection.offsetTop - this._element.offsetTop; 5696 if (root.scrollTo) { 5697 root.scrollTo({ 5698 top: height, 5699 behavior: 'smooth' 5700 }); 5701 return; 5702 } 5703 5704 // Chrome 60 doesn't support `scrollTo` 5705 root.scrollTop = height; 5706 } 5707 }); 5708 } 5709 _getNewObserver() { 5710 const options = { 5711 root: this._rootElement, 5712 threshold: this._config.threshold, 5713 rootMargin: this._config.rootMargin 5714 }; 5715 return new IntersectionObserver(entries => this._observerCallback(entries), options); 5716 } 5717 5718 // The logic of selection 5719 _observerCallback(entries) { 5720 const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`); 5721 const activate = entry => { 5722 this._previousScrollData.visibleEntryTop = entry.target.offsetTop; 5723 this._process(targetElement(entry)); 5724 }; 5725 const parentScrollTop = (this._rootElement || document.documentElement).scrollTop; 5726 const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop; 5727 this._previousScrollData.parentScrollTop = parentScrollTop; 5728 for (const entry of entries) { 5729 if (!entry.isIntersecting) { 5730 this._activeTarget = null; 5731 this._clearActiveClass(targetElement(entry)); 5732 continue; 5733 } 5734 const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; 5735 // if we are scrolling down, pick the bigger offsetTop 5736 if (userScrollsDown && entryIsLowerThanPrevious) { 5737 activate(entry); 5738 // if parent isn't scrolled, let's keep the first visible item, breaking the iteration 5739 if (!parentScrollTop) { 5740 return; 5741 } 5742 continue; 5743 } 5744 5745 // if we are scrolling up, pick the smallest offsetTop 5746 if (!userScrollsDown && !entryIsLowerThanPrevious) { 5747 activate(entry); 5748 } 5749 } 5750 } 5751 _initializeTargetsAndObservables() { 5752 this._targetLinks = new Map(); 5753 this._observableSections = new Map(); 5754 const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target); 5755 for (const anchor of targetLinks) { 5756 // ensure that the anchor has an id and is not disabled 5757 if (!anchor.hash || isDisabled(anchor)) { 5758 continue; 5759 } 5760 const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element); 5761 5762 // ensure that the observableSection exists & is visible 5763 if (isVisible(observableSection)) { 5764 this._targetLinks.set(decodeURI(anchor.hash), anchor); 5765 this._observableSections.set(anchor.hash, observableSection); 5766 } 5767 } 5768 } 5769 _process(target) { 5770 if (this._activeTarget === target) { 5771 return; 5772 } 5773 this._clearActiveClass(this._config.target); 5774 this._activeTarget = target; 5775 target.classList.add(CLASS_NAME_ACTIVE$1); 5776 this._activateParents(target); 5777 EventHandler.trigger(this._element, EVENT_ACTIVATE, { 5778 relatedTarget: target 5779 }); 5780 } 5781 _activateParents(target) { 5782 // Activate dropdown parents 5783 if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) { 5784 SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1); 5785 return; 5786 } 5787 for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) { 5788 // Set triggered links parents as active 5789 // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor 5790 for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) { 5791 item.classList.add(CLASS_NAME_ACTIVE$1); 5792 } 5793 } 5794 } 5795 _clearActiveClass(parent) { 5796 parent.classList.remove(CLASS_NAME_ACTIVE$1); 5797 const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE$1}`, parent); 5798 for (const node of activeNodes) { 5799 node.classList.remove(CLASS_NAME_ACTIVE$1); 5800 } 5801 } 5802 5803 // Static 5804 static jQueryInterface(config) { 5805 return this.each(function () { 5806 const data = ScrollSpy.getOrCreateInstance(this, config); 5807 if (typeof config !== 'string') { 5808 return; 5809 } 5810 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 5811 throw new TypeError(`No method named "${config}"`); 5812 } 5813 data[config](); 5814 }); 5815 } 5816 } 5817 5818 /** 5819 * Data API implementation 5820 */ 5821 5822 EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => { 5823 for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) { 5824 ScrollSpy.getOrCreateInstance(spy); 5825 } 5826 }); 5827 5828 /** 5829 * jQuery 5830 */ 5831 5832 defineJQueryPlugin(ScrollSpy); 5833 5834 /** 5835 * -------------------------------------------------------------------------- 5836 * Bootstrap tab.js 5837 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5838 * -------------------------------------------------------------------------- 5839 */ 5840 5841 5842 /** 5843 * Constants 5844 */ 5845 5846 const NAME$1 = 'tab'; 5847 const DATA_KEY$1 = 'bs.tab'; 5848 const EVENT_KEY$1 = `.${DATA_KEY$1}`; 5849 const EVENT_HIDE$1 = `hide${EVENT_KEY$1}`; 5850 const EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`; 5851 const EVENT_SHOW$1 = `show${EVENT_KEY$1}`; 5852 const EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`; 5853 const EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}`; 5854 const EVENT_KEYDOWN = `keydown${EVENT_KEY$1}`; 5855 const EVENT_LOAD_DATA_API = `load${EVENT_KEY$1}`; 5856 const ARROW_LEFT_KEY = 'ArrowLeft'; 5857 const ARROW_RIGHT_KEY = 'ArrowRight'; 5858 const ARROW_UP_KEY = 'ArrowUp'; 5859 const ARROW_DOWN_KEY = 'ArrowDown'; 5860 const HOME_KEY = 'Home'; 5861 const END_KEY = 'End'; 5862 const CLASS_NAME_ACTIVE = 'active'; 5863 const CLASS_NAME_FADE$1 = 'fade'; 5864 const CLASS_NAME_SHOW$1 = 'show'; 5865 const CLASS_DROPDOWN = 'dropdown'; 5866 const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'; 5867 const SELECTOR_DROPDOWN_MENU = '.dropdown-menu'; 5868 const NOT_SELECTOR_DROPDOWN_TOGGLE = `:not(${SELECTOR_DROPDOWN_TOGGLE})`; 5869 const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]'; 5870 const SELECTOR_OUTER = '.nav-item, .list-group-item'; 5871 const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`; 5872 const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // TODO: could only be `tab` in v6 5873 const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`; 5874 const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`; 5875 5876 /** 5877 * Class definition 5878 */ 5879 5880 class Tab extends BaseComponent { 5881 constructor(element) { 5882 super(element); 5883 this._parent = this._element.closest(SELECTOR_TAB_PANEL); 5884 if (!this._parent) { 5885 return; 5886 // TODO: should throw exception in v6 5887 // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`) 5888 } 5889 5890 // Set up initial aria attributes 5891 this._setInitialAttributes(this._parent, this._getChildren()); 5892 EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event)); 5893 } 5894 5895 // Getters 5896 static get NAME() { 5897 return NAME$1; 5898 } 5899 5900 // Public 5901 show() { 5902 // Shows this elem and deactivate the active sibling if exists 5903 const innerElem = this._element; 5904 if (this._elemIsActive(innerElem)) { 5905 return; 5906 } 5907 5908 // Search for active tab on same parent to deactivate it 5909 const active = this._getActiveElem(); 5910 const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE$1, { 5911 relatedTarget: innerElem 5912 }) : null; 5913 const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW$1, { 5914 relatedTarget: active 5915 }); 5916 if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) { 5917 return; 5918 } 5919 this._deactivate(active, innerElem); 5920 this._activate(innerElem, active); 5921 } 5922 5923 // Private 5924 _activate(element, relatedElem) { 5925 if (!element) { 5926 return; 5927 } 5928 element.classList.add(CLASS_NAME_ACTIVE); 5929 this._activate(SelectorEngine.getElementFromSelector(element)); // Search and activate/show the proper section 5930 5931 const complete = () => { 5932 if (element.getAttribute('role') !== 'tab') { 5933 element.classList.add(CLASS_NAME_SHOW$1); 5934 return; 5935 } 5936 element.removeAttribute('tabindex'); 5937 element.setAttribute('aria-selected', true); 5938 this._toggleDropDown(element, true); 5939 EventHandler.trigger(element, EVENT_SHOWN$1, { 5940 relatedTarget: relatedElem 5941 }); 5942 }; 5943 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1)); 5944 } 5945 _deactivate(element, relatedElem) { 5946 if (!element) { 5947 return; 5948 } 5949 element.classList.remove(CLASS_NAME_ACTIVE); 5950 element.blur(); 5951 this._deactivate(SelectorEngine.getElementFromSelector(element)); // Search and deactivate the shown section too 5952 5953 const complete = () => { 5954 if (element.getAttribute('role') !== 'tab') { 5955 element.classList.remove(CLASS_NAME_SHOW$1); 5956 return; 5957 } 5958 element.setAttribute('aria-selected', false); 5959 element.setAttribute('tabindex', '-1'); 5960 this._toggleDropDown(element, false); 5961 EventHandler.trigger(element, EVENT_HIDDEN$1, { 5962 relatedTarget: relatedElem 5963 }); 5964 }; 5965 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1)); 5966 } 5967 _keydown(event) { 5968 if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) { 5969 return; 5970 } 5971 event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page 5972 event.preventDefault(); 5973 const children = this._getChildren().filter(element => !isDisabled(element)); 5974 let nextActiveElement; 5975 if ([HOME_KEY, END_KEY].includes(event.key)) { 5976 nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1]; 5977 } else { 5978 const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key); 5979 nextActiveElement = getNextActiveElement(children, event.target, isNext, true); 5980 } 5981 if (nextActiveElement) { 5982 nextActiveElement.focus({ 5983 preventScroll: true 5984 }); 5985 Tab.getOrCreateInstance(nextActiveElement).show(); 5986 } 5987 } 5988 _getChildren() { 5989 // collection of inner elements 5990 return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent); 5991 } 5992 _getActiveElem() { 5993 return this._getChildren().find(child => this._elemIsActive(child)) || null; 5994 } 5995 _setInitialAttributes(parent, children) { 5996 this._setAttributeIfNotExists(parent, 'role', 'tablist'); 5997 for (const child of children) { 5998 this._setInitialAttributesOnChild(child); 5999 } 6000 } 6001 _setInitialAttributesOnChild(child) { 6002 child = this._getInnerElement(child); 6003 const isActive = this._elemIsActive(child); 6004 const outerElem = this._getOuterElement(child); 6005 child.setAttribute('aria-selected', isActive); 6006 if (outerElem !== child) { 6007 this._setAttributeIfNotExists(outerElem, 'role', 'presentation'); 6008 } 6009 if (!isActive) { 6010 child.setAttribute('tabindex', '-1'); 6011 } 6012 this._setAttributeIfNotExists(child, 'role', 'tab'); 6013 6014 // set attributes to the related panel too 6015 this._setInitialAttributesOnTargetPanel(child); 6016 } 6017 _setInitialAttributesOnTargetPanel(child) { 6018 const target = SelectorEngine.getElementFromSelector(child); 6019 if (!target) { 6020 return; 6021 } 6022 this._setAttributeIfNotExists(target, 'role', 'tabpanel'); 6023 if (child.id) { 6024 this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`); 6025 } 6026 } 6027 _toggleDropDown(element, open) { 6028 const outerElem = this._getOuterElement(element); 6029 if (!outerElem.classList.contains(CLASS_DROPDOWN)) { 6030 return; 6031 } 6032 const toggle = (selector, className) => { 6033 const element = SelectorEngine.findOne(selector, outerElem); 6034 if (element) { 6035 element.classList.toggle(className, open); 6036 } 6037 }; 6038 toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE); 6039 toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW$1); 6040 outerElem.setAttribute('aria-expanded', open); 6041 } 6042 _setAttributeIfNotExists(element, attribute, value) { 6043 if (!element.hasAttribute(attribute)) { 6044 element.setAttribute(attribute, value); 6045 } 6046 } 6047 _elemIsActive(elem) { 6048 return elem.classList.contains(CLASS_NAME_ACTIVE); 6049 } 6050 6051 // Try to get the inner element (usually the .nav-link) 6052 _getInnerElement(elem) { 6053 return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem); 6054 } 6055 6056 // Try to get the outer element (usually the .nav-item) 6057 _getOuterElement(elem) { 6058 return elem.closest(SELECTOR_OUTER) || elem; 6059 } 6060 6061 // Static 6062 static jQueryInterface(config) { 6063 return this.each(function () { 6064 const data = Tab.getOrCreateInstance(this); 6065 if (typeof config !== 'string') { 6066 return; 6067 } 6068 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 6069 throw new TypeError(`No method named "${config}"`); 6070 } 6071 data[config](); 6072 }); 6073 } 6074 } 6075 6076 /** 6077 * Data API implementation 6078 */ 6079 6080 EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { 6081 if (['A', 'AREA'].includes(this.tagName)) { 6082 event.preventDefault(); 6083 } 6084 if (isDisabled(this)) { 6085 return; 6086 } 6087 Tab.getOrCreateInstance(this).show(); 6088 }); 6089 6090 /** 6091 * Initialize on focus 6092 */ 6093 EventHandler.on(window, EVENT_LOAD_DATA_API, () => { 6094 for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) { 6095 Tab.getOrCreateInstance(element); 6096 } 6097 }); 6098 /** 6099 * jQuery 6100 */ 6101 6102 defineJQueryPlugin(Tab); 6103 6104 /** 6105 * -------------------------------------------------------------------------- 6106 * Bootstrap toast.js 6107 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6108 * -------------------------------------------------------------------------- 6109 */ 6110 6111 6112 /** 6113 * Constants 6114 */ 6115 6116 const NAME = 'toast'; 6117 const DATA_KEY = 'bs.toast'; 6118 const EVENT_KEY = `.${DATA_KEY}`; 6119 const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`; 6120 const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`; 6121 const EVENT_FOCUSIN = `focusin${EVENT_KEY}`; 6122 const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`; 6123 const EVENT_HIDE = `hide${EVENT_KEY}`; 6124 const EVENT_HIDDEN = `hidden${EVENT_KEY}`; 6125 const EVENT_SHOW = `show${EVENT_KEY}`; 6126 const EVENT_SHOWN = `shown${EVENT_KEY}`; 6127 const CLASS_NAME_FADE = 'fade'; 6128 const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility 6129 const CLASS_NAME_SHOW = 'show'; 6130 const CLASS_NAME_SHOWING = 'showing'; 6131 const DefaultType = { 6132 animation: 'boolean', 6133 autohide: 'boolean', 6134 delay: 'number' 6135 }; 6136 const Default = { 6137 animation: true, 6138 autohide: true, 6139 delay: 5000 6140 }; 6141 6142 /** 6143 * Class definition 6144 */ 6145 6146 class Toast extends BaseComponent { 6147 constructor(element, config) { 6148 super(element, config); 6149 this._timeout = null; 6150 this._hasMouseInteraction = false; 6151 this._hasKeyboardInteraction = false; 6152 this._setListeners(); 6153 } 6154 6155 // Getters 6156 static get Default() { 6157 return Default; 6158 } 6159 static get DefaultType() { 6160 return DefaultType; 6161 } 6162 static get NAME() { 6163 return NAME; 6164 } 6165 6166 // Public 6167 show() { 6168 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW); 6169 if (showEvent.defaultPrevented) { 6170 return; 6171 } 6172 this._clearTimeout(); 6173 if (this._config.animation) { 6174 this._element.classList.add(CLASS_NAME_FADE); 6175 } 6176 const complete = () => { 6177 this._element.classList.remove(CLASS_NAME_SHOWING); 6178 EventHandler.trigger(this._element, EVENT_SHOWN); 6179 this._maybeScheduleHide(); 6180 }; 6181 this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated 6182 reflow(this._element); 6183 this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING); 6184 this._queueCallback(complete, this._element, this._config.animation); 6185 } 6186 hide() { 6187 if (!this.isShown()) { 6188 return; 6189 } 6190 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE); 6191 if (hideEvent.defaultPrevented) { 6192 return; 6193 } 6194 const complete = () => { 6195 this._element.classList.add(CLASS_NAME_HIDE); // @deprecated 6196 this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW); 6197 EventHandler.trigger(this._element, EVENT_HIDDEN); 6198 }; 6199 this._element.classList.add(CLASS_NAME_SHOWING); 6200 this._queueCallback(complete, this._element, this._config.animation); 6201 } 6202 dispose() { 6203 this._clearTimeout(); 6204 if (this.isShown()) { 6205 this._element.classList.remove(CLASS_NAME_SHOW); 6206 } 6207 super.dispose(); 6208 } 6209 isShown() { 6210 return this._element.classList.contains(CLASS_NAME_SHOW); 6211 } 6212 6213 // Private 6214 _maybeScheduleHide() { 6215 if (!this._config.autohide) { 6216 return; 6217 } 6218 if (this._hasMouseInteraction || this._hasKeyboardInteraction) { 6219 return; 6220 } 6221 this._timeout = setTimeout(() => { 6222 this.hide(); 6223 }, this._config.delay); 6224 } 6225 _onInteraction(event, isInteracting) { 6226 switch (event.type) { 6227 case 'mouseover': 6228 case 'mouseout': 6229 { 6230 this._hasMouseInteraction = isInteracting; 6231 break; 6232 } 6233 case 'focusin': 6234 case 'focusout': 6235 { 6236 this._hasKeyboardInteraction = isInteracting; 6237 break; 6238 } 6239 } 6240 if (isInteracting) { 6241 this._clearTimeout(); 6242 return; 6243 } 6244 const nextElement = event.relatedTarget; 6245 if (this._element === nextElement || this._element.contains(nextElement)) { 6246 return; 6247 } 6248 this._maybeScheduleHide(); 6249 } 6250 _setListeners() { 6251 EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true)); 6252 EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false)); 6253 EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true)); 6254 EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false)); 6255 } 6256 _clearTimeout() { 6257 clearTimeout(this._timeout); 6258 this._timeout = null; 6259 } 6260 6261 // Static 6262 static jQueryInterface(config) { 6263 return this.each(function () { 6264 const data = Toast.getOrCreateInstance(this, config); 6265 if (typeof config === 'string') { 6266 if (typeof data[config] === 'undefined') { 6267 throw new TypeError(`No method named "${config}"`); 6268 } 6269 data[config](this); 6270 } 6271 }); 6272 } 6273 } 6274 6275 /** 6276 * Data API implementation 6277 */ 6278 6279 enableDismissTrigger(Toast); 6280 6281 /** 6282 * jQuery 6283 */ 6284 6285 defineJQueryPlugin(Toast); 6286 6287 /** 6288 * -------------------------------------------------------------------------- 6289 * Bootstrap index.umd.js 6290 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6291 * -------------------------------------------------------------------------- 6292 */ 6293 6294 const index_umd = { 6295 Alert, 6296 Button, 6297 Carousel, 6298 Collapse, 6299 Dropdown, 6300 Modal, 6301 Offcanvas, 6302 Popover, 6303 ScrollSpy, 6304 Tab, 6305 Toast, 6306 Tooltip 6307 }; 6308 6309 return index_umd; 6310 6311})); 6312//# sourceMappingURL=bootstrap.bundle.js.map
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.