vendor: 3,086 bytes, lines 1-87
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(require('@popperjs/core')) : 8 typeof define === 'function' && define.amd ? define(['@popperjs/core'], factory) : 9 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory(global.Popper)); 10})(this, (function (Popper) { 'use strict'; 11 12 function _interopNamespaceDefault(e) { 13 const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } }); 14 if (e) { 15 for (const k in e) { 16 if (k !== 'default') { 17 const d = Object.getOwnPropertyDescriptor(e, k); 18 Object.defineProperty(n, k, d.get ? d : { 19 enumerable: true, 20 get: () => e[k] 21 }); 22 } 23 } 24 } 25 n.default = e; 26 return Object.freeze(n); 27 } 28 29 const Popper__namespace = /*#__PURE__*/_interopNamespaceDefault(Popper); 30 31 /** 32 * -------------------------------------------------------------------------- 33 * Bootstrap dom/data.js 34 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 35 * -------------------------------------------------------------------------- 36 */ 37 38 /** 39 * Constants 40 */ 41 42 const elementMap = new Map(); 43 const Data = { 44 set(element, key, instance) { 45 if (!elementMap.has(element)) { 46 elementMap.set(element, new Map()); 47 } 48 const instanceMap = elementMap.get(element); 49 50 // make it clear we only want one instance per element 51 // can be removed later when multiple key/instances are fine to be used 52 if (!instanceMap.has(key) && instanceMap.size !== 0) { 53 // eslint-disable-next-line no-console 54 console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`); 55 return; 56 } 57 instanceMap.set(key, instance); 58 }, 59 get(element, key) { 60 if (elementMap.has(element)) { 61 return elementMap.get(element).get(key) || null; 62 } 63 return null; 64 }, 65 remove(element, key) { 66 if (!elementMap.has(element)) { 67 return; 68 } 69 const instanceMap = elementMap.get(element); 70 instanceMap.delete(key); 71 72 // free up element references if there are no instances left for an element 73 if (instanceMap.size === 0) { 74 elementMap.delete(element); 75 } 76 } 77 }; 78 79 /** 80 * -------------------------------------------------------------------------- 81 * Bootstrap util/index.js 82 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 83 * -------------------------------------------------------------------------- 84 */ 85 86 const MAX_UID = 1000000; 87 const MILLISECONDS_MULTIPLIER = 1000;
vendor: 56,087 bytes, lines 88-1741
88 const TRANSITION_END = 'transitionend'; 89 90 /** 91 * Properly escape IDs selectors to handle weird IDs 92 * @param {string} selector 93 * @returns {string} 94 */ 95 const parseSelector = selector => { 96 if (selector && window.CSS && window.CSS.escape) { 97 // document.querySelector needs escaping to handle IDs (html5+) containing for instance / 98 selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`); 99 } 100 return selector; 101 }; 102 103 // Shout-out Angus Croll (https://goo.gl/pxwQGp) 104 const toType = object => { 105 if (object === null || object === undefined) { 106 return `${object}`; 107 } 108 return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase(); 109 }; 110 111 /** 112 * Public Util API 113 */ 114 115 const getUID = prefix => { 116 do { 117 prefix += Math.floor(Math.random() * MAX_UID); 118 } while (document.getElementById(prefix)); 119 return prefix; 120 }; 121 const getTransitionDurationFromElement = element => { 122 if (!element) { 123 return 0; 124 } 125 126 // Get transition-duration of the element 127 let { 128 transitionDuration, 129 transitionDelay 130 } = window.getComputedStyle(element); 131 const floatTransitionDuration = Number.parseFloat(transitionDuration); 132 const floatTransitionDelay = Number.parseFloat(transitionDelay); 133 134 // Return 0 if element or transition duration is not found 135 if (!floatTransitionDuration && !floatTransitionDelay) { 136 return 0; 137 } 138 139 // If multiple durations are defined, take the first 140 transitionDuration = transitionDuration.split(',')[0]; 141 transitionDelay = transitionDelay.split(',')[0]; 142 return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; 143 }; 144 const triggerTransitionEnd = element => { 145 element.dispatchEvent(new Event(TRANSITION_END)); 146 }; 147 const isElement = object => { 148 if (!object || typeof object !== 'object') { 149 return false; 150 } 151 if (typeof object.jquery !== 'undefined') { 152 object = object[0]; 153 } 154 return typeof object.nodeType !== 'undefined'; 155 }; 156 const getElement = object => { 157 // it's a jQuery object or a node element 158 if (isElement(object)) { 159 return object.jquery ? object[0] : object; 160 } 161 if (typeof object === 'string' && object.length > 0) { 162 return document.querySelector(parseSelector(object)); 163 } 164 return null; 165 }; 166 const isVisible = element => { 167 if (!isElement(element) || element.getClientRects().length === 0) { 168 return false; 169 } 170 const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'; 171 // Handle `details` element as its content may falsie appear visible when it is closed 172 const closedDetails = element.closest('details:not([open])'); 173 if (!closedDetails) { 174 return elementIsVisible; 175 } 176 if (closedDetails !== element) { 177 const summary = element.closest('summary'); 178 if (summary && summary.parentNode !== closedDetails) { 179 return false; 180 } 181 if (summary === null) { 182 return false; 183 } 184 } 185 return elementIsVisible; 186 }; 187 const isDisabled = element => { 188 if (!element || element.nodeType !== Node.ELEMENT_NODE) { 189 return true; 190 } 191 if (element.classList.contains('disabled')) { 192 return true; 193 } 194 if (typeof element.disabled !== 'undefined') { 195 return element.disabled; 196 } 197 return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'; 198 }; 199 const findShadowRoot = element => { 200 if (!document.documentElement.attachShadow) { 201 return null; 202 } 203 204 // Can find the shadow root otherwise it'll return the document 205 if (typeof element.getRootNode === 'function') { 206 const root = element.getRootNode(); 207 return root instanceof ShadowRoot ? root : null; 208 } 209 if (element instanceof ShadowRoot) { 210 return element; 211 } 212 213 // when we don't find a shadow root 214 if (!element.parentNode) { 215 return null; 216 } 217 return findShadowRoot(element.parentNode); 218 }; 219 const noop = () => {}; 220 221 /** 222 * Trick to restart an element's animation 223 * 224 * @param {HTMLElement} element 225 * @return void 226 * 227 * @see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation 228 */ 229 const reflow = element => { 230 element.offsetHeight; // eslint-disable-line no-unused-expressions 231 }; 232 const getjQuery = () => { 233 if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) { 234 return window.jQuery; 235 } 236 return null; 237 }; 238 const DOMContentLoadedCallbacks = []; 239 const onDOMContentLoaded = callback => { 240 if (document.readyState === 'loading') { 241 // add listener on the first call when the document is in loading state 242 if (!DOMContentLoadedCallbacks.length) { 243 document.addEventListener('DOMContentLoaded', () => { 244 for (const callback of DOMContentLoadedCallbacks) { 245 callback(); 246 } 247 }); 248 } 249 DOMContentLoadedCallbacks.push(callback); 250 } else { 251 callback(); 252 } 253 }; 254 const isRTL = () => document.documentElement.dir === 'rtl'; 255 const defineJQueryPlugin = plugin => { 256 onDOMContentLoaded(() => { 257 const $ = getjQuery(); 258 /* istanbul ignore if */ 259 if ($) { 260 const name = plugin.NAME; 261 const JQUERY_NO_CONFLICT = $.fn[name]; 262 $.fn[name] = plugin.jQueryInterface; 263 $.fn[name].Constructor = plugin; 264 $.fn[name].noConflict = () => { 265 $.fn[name] = JQUERY_NO_CONFLICT; 266 return plugin.jQueryInterface; 267 }; 268 } 269 }); 270 }; 271 const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => { 272 return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue; 273 }; 274 const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => { 275 if (!waitForTransition) { 276 execute(callback); 277 return; 278 } 279 const durationPadding = 5; 280 const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding; 281 let called = false; 282 const handler = ({ 283 target 284 }) => { 285 if (target !== transitionElement) { 286 return; 287 } 288 called = true; 289 transitionElement.removeEventListener(TRANSITION_END, handler); 290 execute(callback); 291 }; 292 transitionElement.addEventListener(TRANSITION_END, handler); 293 setTimeout(() => { 294 if (!called) { 295 triggerTransitionEnd(transitionElement); 296 } 297 }, emulatedDuration); 298 }; 299 300 /** 301 * Return the previous/next element of a list. 302 * 303 * @param {array} list The list of elements 304 * @param activeElement The active element 305 * @param shouldGetNext Choose to get next or previous element 306 * @param isCycleAllowed 307 * @return {Element|elem} The proper element 308 */ 309 const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => { 310 const listLength = list.length; 311 let index = list.indexOf(activeElement); 312 313 // if the element does not exist in the list return an element 314 // depending on the direction and if cycle is allowed 315 if (index === -1) { 316 return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]; 317 } 318 index += shouldGetNext ? 1 : -1; 319 if (isCycleAllowed) { 320 index = (index + listLength) % listLength; 321 } 322 return list[Math.max(0, Math.min(index, listLength - 1))]; 323 }; 324 325 /** 326 * -------------------------------------------------------------------------- 327 * Bootstrap dom/event-handler.js 328 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 329 * -------------------------------------------------------------------------- 330 */ 331 332 333 /** 334 * Constants 335 */ 336 337 const namespaceRegex = /[^.]*(?=\..*)\.|.*/; 338 const stripNameRegex = /\..*/; 339 const stripUidRegex = /::\d+$/; 340 const eventRegistry = {}; // Events storage 341 let uidEvent = 1; 342 const customEvents = { 343 mouseenter: 'mouseover', 344 mouseleave: 'mouseout' 345 }; 346 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']); 347 348 /** 349 * Private methods 350 */ 351 352 function makeEventUid(element, uid) { 353 return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++; 354 } 355 function getElementEvents(element) { 356 const uid = makeEventUid(element); 357 element.uidEvent = uid; 358 eventRegistry[uid] = eventRegistry[uid] || {}; 359 return eventRegistry[uid]; 360 } 361 function bootstrapHandler(element, fn) { 362 return function handler(event) { 363 hydrateObj(event, { 364 delegateTarget: element 365 }); 366 if (handler.oneOff) { 367 EventHandler.off(element, event.type, fn); 368 } 369 return fn.apply(element, [event]); 370 }; 371 } 372 function bootstrapDelegationHandler(element, selector, fn) { 373 return function handler(event) { 374 const domElements = element.querySelectorAll(selector); 375 for (let { 376 target 377 } = event; target && target !== this; target = target.parentNode) { 378 for (const domElement of domElements) { 379 if (domElement !== target) { 380 continue; 381 } 382 hydrateObj(event, { 383 delegateTarget: target 384 }); 385 if (handler.oneOff) { 386 EventHandler.off(element, event.type, selector, fn); 387 } 388 return fn.apply(target, [event]); 389 } 390 } 391 }; 392 } 393 function findHandler(events, callable, delegationSelector = null) { 394 return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector); 395 } 396 function normalizeParameters(originalTypeEvent, handler, delegationFunction) { 397 const isDelegated = typeof handler === 'string'; 398 // TODO: tooltip passes `false` instead of selector, so we need to check 399 const callable = isDelegated ? delegationFunction : handler || delegationFunction; 400 let typeEvent = getTypeEvent(originalTypeEvent); 401 if (!nativeEvents.has(typeEvent)) { 402 typeEvent = originalTypeEvent; 403 } 404 return [isDelegated, callable, typeEvent]; 405 } 406 function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) { 407 if (typeof originalTypeEvent !== 'string' || !element) { 408 return; 409 } 410 let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); 411 412 // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position 413 // this prevents the handler from being dispatched the same way as mouseover or mouseout does 414 if (originalTypeEvent in customEvents) { 415 const wrapFunction = fn => { 416 return function (event) { 417 if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) { 418 return fn.call(this, event); 419 } 420 }; 421 }; 422 callable = wrapFunction(callable); 423 } 424 const events = getElementEvents(element); 425 const handlers = events[typeEvent] || (events[typeEvent] = {}); 426 const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null); 427 if (previousFunction) { 428 previousFunction.oneOff = previousFunction.oneOff && oneOff; 429 return; 430 } 431 const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, '')); 432 const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable); 433 fn.delegationSelector = isDelegated ? handler : null; 434 fn.callable = callable; 435 fn.oneOff = oneOff; 436 fn.uidEvent = uid; 437 handlers[uid] = fn; 438 element.addEventListener(typeEvent, fn, isDelegated); 439 } 440 function removeHandler(element, events, typeEvent, handler, delegationSelector) { 441 const fn = findHandler(events[typeEvent], handler, delegationSelector); 442 if (!fn) { 443 return; 444 } 445 element.removeEventListener(typeEvent, fn, Boolean(delegationSelector)); 446 delete events[typeEvent][fn.uidEvent]; 447 } 448 function removeNamespacedHandlers(element, events, typeEvent, namespace) { 449 const storeElementEvent = events[typeEvent] || {}; 450 for (const [handlerKey, event] of Object.entries(storeElementEvent)) { 451 if (handlerKey.includes(namespace)) { 452 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); 453 } 454 } 455 } 456 function getTypeEvent(event) { 457 // allow to get the native events from namespaced events ('click.bs.button' --> 'click') 458 event = event.replace(stripNameRegex, ''); 459 return customEvents[event] || event; 460 } 461 const EventHandler = { 462 on(element, event, handler, delegationFunction) { 463 addHandler(element, event, handler, delegationFunction, false); 464 }, 465 one(element, event, handler, delegationFunction) { 466 addHandler(element, event, handler, delegationFunction, true); 467 }, 468 off(element, originalTypeEvent, handler, delegationFunction) { 469 if (typeof originalTypeEvent !== 'string' || !element) { 470 return; 471 } 472 const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); 473 const inNamespace = typeEvent !== originalTypeEvent; 474 const events = getElementEvents(element); 475 const storeElementEvent = events[typeEvent] || {}; 476 const isNamespace = originalTypeEvent.startsWith('.'); 477 if (typeof callable !== 'undefined') { 478 // Simplest case: handler is passed, remove that listener ONLY. 479 if (!Object.keys(storeElementEvent).length) { 480 return; 481 } 482 removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null); 483 return; 484 } 485 if (isNamespace) { 486 for (const elementEvent of Object.keys(events)) { 487 removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1)); 488 } 489 } 490 for (const [keyHandlers, event] of Object.entries(storeElementEvent)) { 491 const handlerKey = keyHandlers.replace(stripUidRegex, ''); 492 if (!inNamespace || originalTypeEvent.includes(handlerKey)) { 493 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); 494 } 495 } 496 }, 497 trigger(element, event, args) { 498 if (typeof event !== 'string' || !element) { 499 return null; 500 } 501 const $ = getjQuery(); 502 const typeEvent = getTypeEvent(event); 503 const inNamespace = event !== typeEvent; 504 let jQueryEvent = null; 505 let bubbles = true; 506 let nativeDispatch = true; 507 let defaultPrevented = false; 508 if (inNamespace && $) { 509 jQueryEvent = $.Event(event, args); 510 $(element).trigger(jQueryEvent); 511 bubbles = !jQueryEvent.isPropagationStopped(); 512 nativeDispatch = !jQueryEvent.isImmediatePropagationStopped(); 513 defaultPrevented = jQueryEvent.isDefaultPrevented(); 514 } 515 const evt = hydrateObj(new Event(event, { 516 bubbles, 517 cancelable: true 518 }), args); 519 if (defaultPrevented) { 520 evt.preventDefault(); 521 } 522 if (nativeDispatch) { 523 element.dispatchEvent(evt); 524 } 525 if (evt.defaultPrevented && jQueryEvent) { 526 jQueryEvent.preventDefault(); 527 } 528 return evt; 529 } 530 }; 531 function hydrateObj(obj, meta = {}) { 532 for (const [key, value] of Object.entries(meta)) { 533 try { 534 obj[key] = value; 535 } catch (_unused) { 536 Object.defineProperty(obj, key, { 537 configurable: true, 538 get() { 539 return value; 540 } 541 }); 542 } 543 } 544 return obj; 545 } 546 547 /** 548 * -------------------------------------------------------------------------- 549 * Bootstrap dom/manipulator.js 550 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 551 * -------------------------------------------------------------------------- 552 */ 553 554 function normalizeData(value) { 555 if (value === 'true') { 556 return true; 557 } 558 if (value === 'false') { 559 return false; 560 } 561 if (value === Number(value).toString()) { 562 return Number(value); 563 } 564 if (value === '' || value === 'null') { 565 return null; 566 } 567 if (typeof value !== 'string') { 568 return value; 569 } 570 try { 571 return JSON.parse(decodeURIComponent(value)); 572 } catch (_unused) { 573 return value; 574 } 575 } 576 function normalizeDataKey(key) { 577 return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`); 578 } 579 const Manipulator = { 580 setDataAttribute(element, key, value) { 581 element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value); 582 }, 583 removeDataAttribute(element, key) { 584 element.removeAttribute(`data-bs-${normalizeDataKey(key)}`); 585 }, 586 getDataAttributes(element) { 587 if (!element) { 588 return {}; 589 } 590 const attributes = {}; 591 const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig')); 592 for (const key of bsKeys) { 593 let pureKey = key.replace(/^bs/, ''); 594 pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1); 595 attributes[pureKey] = normalizeData(element.dataset[key]); 596 } 597 return attributes; 598 }, 599 getDataAttribute(element, key) { 600 return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`)); 601 } 602 }; 603 604 /** 605 * -------------------------------------------------------------------------- 606 * Bootstrap util/config.js 607 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 608 * -------------------------------------------------------------------------- 609 */ 610 611 612 /** 613 * Class definition 614 */ 615 616 class Config { 617 // Getters 618 static get Default() { 619 return {}; 620 } 621 static get DefaultType() { 622 return {}; 623 } 624 static get NAME() { 625 throw new Error('You have to implement the static method "NAME", for each component!'); 626 } 627 _getConfig(config) { 628 config = this._mergeConfigObj(config); 629 config = this._configAfterMerge(config); 630 this._typeCheckConfig(config); 631 return config; 632 } 633 _configAfterMerge(config) { 634 return config; 635 } 636 _mergeConfigObj(config, element) { 637 const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse 638 639 return { 640 ...this.constructor.Default, 641 ...(typeof jsonConfig === 'object' ? jsonConfig : {}), 642 ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}), 643 ...(typeof config === 'object' ? config : {}) 644 }; 645 } 646 _typeCheckConfig(config, configTypes = this.constructor.DefaultType) { 647 for (const [property, expectedTypes] of Object.entries(configTypes)) { 648 const value = config[property]; 649 const valueType = isElement(value) ? 'element' : toType(value); 650 if (!new RegExp(expectedTypes).test(valueType)) { 651 throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`); 652 } 653 } 654 } 655 } 656 657 /** 658 * -------------------------------------------------------------------------- 659 * Bootstrap base-component.js 660 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 661 * -------------------------------------------------------------------------- 662 */ 663 664 665 /** 666 * Constants 667 */ 668 669 const VERSION = '5.3.8'; 670 671 /** 672 * Class definition 673 */ 674 675 class BaseComponent extends Config { 676 constructor(element, config) { 677 super(); 678 element = getElement(element); 679 if (!element) { 680 return; 681 } 682 this._element = element; 683 this._config = this._getConfig(config); 684 Data.set(this._element, this.constructor.DATA_KEY, this); 685 } 686 687 // Public 688 dispose() { 689 Data.remove(this._element, this.constructor.DATA_KEY); 690 EventHandler.off(this._element, this.constructor.EVENT_KEY); 691 for (const propertyName of Object.getOwnPropertyNames(this)) { 692 this[propertyName] = null; 693 } 694 } 695 696 // Private 697 _queueCallback(callback, element, isAnimated = true) { 698 executeAfterTransition(callback, element, isAnimated); 699 } 700 _getConfig(config) { 701 config = this._mergeConfigObj(config, this._element); 702 config = this._configAfterMerge(config); 703 this._typeCheckConfig(config); 704 return config; 705 } 706 707 // Static 708 static getInstance(element) { 709 return Data.get(getElement(element), this.DATA_KEY); 710 } 711 static getOrCreateInstance(element, config = {}) { 712 return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null); 713 } 714 static get VERSION() { 715 return VERSION; 716 } 717 static get DATA_KEY() { 718 return `bs.${this.NAME}`; 719 } 720 static get EVENT_KEY() { 721 return `.${this.DATA_KEY}`; 722 } 723 static eventName(name) { 724 return `${name}${this.EVENT_KEY}`; 725 } 726 } 727 728 /** 729 * -------------------------------------------------------------------------- 730 * Bootstrap dom/selector-engine.js 731 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 732 * -------------------------------------------------------------------------- 733 */ 734 735 const getSelector = element => { 736 let selector = element.getAttribute('data-bs-target'); 737 if (!selector || selector === '#') { 738 let hrefAttribute = element.getAttribute('href'); 739 740 // The only valid content that could double as a selector are IDs or classes, 741 // so everything starting with `#` or `.`. If a "real" URL is used as the selector, 742 // `document.querySelector` will rightfully complain it is invalid. 743 // See https://github.com/twbs/bootstrap/issues/32273 744 if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) { 745 return null; 746 } 747 748 // Just in case some CMS puts out a full URL with the anchor appended 749 if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) { 750 hrefAttribute = `#${hrefAttribute.split('#')[1]}`; 751 } 752 selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null; 753 } 754 return selector ? selector.split(',').map(sel => parseSelector(sel)).join(',') : null; 755 }; 756 const SelectorEngine = { 757 find(selector, element = document.documentElement) { 758 return [].concat(...Element.prototype.querySelectorAll.call(element, selector)); 759 }, 760 findOne(selector, element = document.documentElement) { 761 return Element.prototype.querySelector.call(element, selector); 762 }, 763 children(element, selector) { 764 return [].concat(...element.children).filter(child => child.matches(selector)); 765 }, 766 parents(element, selector) { 767 const parents = []; 768 let ancestor = element.parentNode.closest(selector); 769 while (ancestor) { 770 parents.push(ancestor); 771 ancestor = ancestor.parentNode.closest(selector); 772 } 773 return parents; 774 }, 775 prev(element, selector) { 776 let previous = element.previousElementSibling; 777 while (previous) { 778 if (previous.matches(selector)) { 779 return [previous]; 780 } 781 previous = previous.previousElementSibling; 782 } 783 return []; 784 }, 785 // TODO: this is now unused; remove later along with prev() 786 next(element, selector) { 787 let next = element.nextElementSibling; 788 while (next) { 789 if (next.matches(selector)) { 790 return [next]; 791 } 792 next = next.nextElementSibling; 793 } 794 return []; 795 }, 796 focusableChildren(element) { 797 const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `${selector}:not([tabindex^="-"])`).join(','); 798 return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el)); 799 }, 800 getSelectorFromElement(element) { 801 const selector = getSelector(element); 802 if (selector) { 803 return SelectorEngine.findOne(selector) ? selector : null; 804 } 805 return null; 806 }, 807 getElementFromSelector(element) { 808 const selector = getSelector(element); 809 return selector ? SelectorEngine.findOne(selector) : null; 810 }, 811 getMultipleElementsFromSelector(element) { 812 const selector = getSelector(element); 813 return selector ? SelectorEngine.find(selector) : []; 814 } 815 }; 816 817 /** 818 * -------------------------------------------------------------------------- 819 * Bootstrap util/component-functions.js 820 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 821 * -------------------------------------------------------------------------- 822 */ 823 824 const enableDismissTrigger = (component, method = 'hide') => { 825 const clickEvent = `click.dismiss${component.EVENT_KEY}`; 826 const name = component.NAME; 827 EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) { 828 if (['A', 'AREA'].includes(this.tagName)) { 829 event.preventDefault(); 830 } 831 if (isDisabled(this)) { 832 return; 833 } 834 const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`); 835 const instance = component.getOrCreateInstance(target); 836 837 // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method 838 instance[method](); 839 }); 840 }; 841 842 /** 843 * -------------------------------------------------------------------------- 844 * Bootstrap alert.js 845 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 846 * -------------------------------------------------------------------------- 847 */ 848 849 850 /** 851 * Constants 852 */ 853 854 const NAME$f = 'alert'; 855 const DATA_KEY$a = 'bs.alert'; 856 const EVENT_KEY$b = `.${DATA_KEY$a}`; 857 const EVENT_CLOSE = `close${EVENT_KEY$b}`; 858 const EVENT_CLOSED = `closed${EVENT_KEY$b}`; 859 const CLASS_NAME_FADE$5 = 'fade'; 860 const CLASS_NAME_SHOW$8 = 'show'; 861 862 /** 863 * Class definition 864 */ 865 866 class Alert extends BaseComponent { 867 // Getters 868 static get NAME() { 869 return NAME$f; 870 } 871 872 // Public 873 close() { 874 const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE); 875 if (closeEvent.defaultPrevented) { 876 return; 877 } 878 this._element.classList.remove(CLASS_NAME_SHOW$8); 879 const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5); 880 this._queueCallback(() => this._destroyElement(), this._element, isAnimated); 881 } 882 883 // Private 884 _destroyElement() { 885 this._element.remove(); 886 EventHandler.trigger(this._element, EVENT_CLOSED); 887 this.dispose(); 888 } 889 890 // Static 891 static jQueryInterface(config) { 892 return this.each(function () { 893 const data = Alert.getOrCreateInstance(this); 894 if (typeof config !== 'string') { 895 return; 896 } 897 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 898 throw new TypeError(`No method named "${config}"`); 899 } 900 data[config](this); 901 }); 902 } 903 } 904 905 /** 906 * Data API implementation 907 */ 908 909 enableDismissTrigger(Alert, 'close'); 910 911 /** 912 * jQuery 913 */ 914 915 defineJQueryPlugin(Alert); 916 917 /** 918 * -------------------------------------------------------------------------- 919 * Bootstrap button.js 920 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 921 * -------------------------------------------------------------------------- 922 */ 923 924 925 /** 926 * Constants 927 */ 928 929 const NAME$e = 'button'; 930 const DATA_KEY$9 = 'bs.button'; 931 const EVENT_KEY$a = `.${DATA_KEY$9}`; 932 const DATA_API_KEY$6 = '.data-api'; 933 const CLASS_NAME_ACTIVE$3 = 'active'; 934 const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle="button"]'; 935 const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`; 936 937 /** 938 * Class definition 939 */ 940 941 class Button extends BaseComponent { 942 // Getters 943 static get NAME() { 944 return NAME$e; 945 } 946 947 // Public 948 toggle() { 949 // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method 950 this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3)); 951 } 952 953 // Static 954 static jQueryInterface(config) { 955 return this.each(function () { 956 const data = Button.getOrCreateInstance(this); 957 if (config === 'toggle') { 958 data[config](); 959 } 960 }); 961 } 962 } 963 964 /** 965 * Data API implementation 966 */ 967 968 EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => { 969 event.preventDefault(); 970 const button = event.target.closest(SELECTOR_DATA_TOGGLE$5); 971 const data = Button.getOrCreateInstance(button); 972 data.toggle(); 973 }); 974 975 /** 976 * jQuery 977 */ 978 979 defineJQueryPlugin(Button); 980 981 /** 982 * -------------------------------------------------------------------------- 983 * Bootstrap util/swipe.js 984 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 985 * -------------------------------------------------------------------------- 986 */ 987 988 989 /** 990 * Constants 991 */ 992 993 const NAME$d = 'swipe'; 994 const EVENT_KEY$9 = '.bs.swipe'; 995 const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`; 996 const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`; 997 const EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`; 998 const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`; 999 const EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`; 1000 const POINTER_TYPE_TOUCH = 'touch'; 1001 const POINTER_TYPE_PEN = 'pen'; 1002 const CLASS_NAME_POINTER_EVENT = 'pointer-event'; 1003 const SWIPE_THRESHOLD = 40; 1004 const Default$c = { 1005 endCallback: null, 1006 leftCallback: null, 1007 rightCallback: null 1008 }; 1009 const DefaultType$c = { 1010 endCallback: '(function|null)', 1011 leftCallback: '(function|null)', 1012 rightCallback: '(function|null)' 1013 }; 1014 1015 /** 1016 * Class definition 1017 */ 1018 1019 class Swipe extends Config { 1020 constructor(element, config) { 1021 super(); 1022 this._element = element; 1023 if (!element || !Swipe.isSupported()) { 1024 return; 1025 } 1026 this._config = this._getConfig(config); 1027 this._deltaX = 0; 1028 this._supportPointerEvents = Boolean(window.PointerEvent); 1029 this._initEvents(); 1030 } 1031 1032 // Getters 1033 static get Default() { 1034 return Default$c; 1035 } 1036 static get DefaultType() { 1037 return DefaultType$c; 1038 } 1039 static get NAME() { 1040 return NAME$d; 1041 } 1042 1043 // Public 1044 dispose() { 1045 EventHandler.off(this._element, EVENT_KEY$9); 1046 } 1047 1048 // Private 1049 _start(event) { 1050 if (!this._supportPointerEvents) { 1051 this._deltaX = event.touches[0].clientX; 1052 return; 1053 } 1054 if (this._eventIsPointerPenTouch(event)) { 1055 this._deltaX = event.clientX; 1056 } 1057 } 1058 _end(event) { 1059 if (this._eventIsPointerPenTouch(event)) { 1060 this._deltaX = event.clientX - this._deltaX; 1061 } 1062 this._handleSwipe(); 1063 execute(this._config.endCallback); 1064 } 1065 _move(event) { 1066 this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX; 1067 } 1068 _handleSwipe() { 1069 const absDeltaX = Math.abs(this._deltaX); 1070 if (absDeltaX <= SWIPE_THRESHOLD) { 1071 return; 1072 } 1073 const direction = absDeltaX / this._deltaX; 1074 this._deltaX = 0; 1075 if (!direction) { 1076 return; 1077 } 1078 execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback); 1079 } 1080 _initEvents() { 1081 if (this._supportPointerEvents) { 1082 EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event)); 1083 EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event)); 1084 this._element.classList.add(CLASS_NAME_POINTER_EVENT); 1085 } else { 1086 EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event)); 1087 EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event)); 1088 EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event)); 1089 } 1090 } 1091 _eventIsPointerPenTouch(event) { 1092 return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH); 1093 } 1094 1095 // Static 1096 static isSupported() { 1097 return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0; 1098 } 1099 } 1100 1101 /** 1102 * -------------------------------------------------------------------------- 1103 * Bootstrap carousel.js 1104 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 1105 * -------------------------------------------------------------------------- 1106 */ 1107 1108 1109 /** 1110 * Constants 1111 */ 1112 1113 const NAME$c = 'carousel'; 1114 const DATA_KEY$8 = 'bs.carousel'; 1115 const EVENT_KEY$8 = `.${DATA_KEY$8}`; 1116 const DATA_API_KEY$5 = '.data-api'; 1117 const ARROW_LEFT_KEY$1 = 'ArrowLeft'; 1118 const ARROW_RIGHT_KEY$1 = 'ArrowRight'; 1119 const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch 1120 1121 const ORDER_NEXT = 'next'; 1122 const ORDER_PREV = 'prev'; 1123 const DIRECTION_LEFT = 'left'; 1124 const DIRECTION_RIGHT = 'right'; 1125 const EVENT_SLIDE = `slide${EVENT_KEY$8}`; 1126 const EVENT_SLID = `slid${EVENT_KEY$8}`; 1127 const EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`; 1128 const EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`; 1129 const EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`; 1130 const EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`; 1131 const EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`; 1132 const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`; 1133 const CLASS_NAME_CAROUSEL = 'carousel'; 1134 const CLASS_NAME_ACTIVE$2 = 'active'; 1135 const CLASS_NAME_SLIDE = 'slide'; 1136 const CLASS_NAME_END = 'carousel-item-end'; 1137 const CLASS_NAME_START = 'carousel-item-start'; 1138 const CLASS_NAME_NEXT = 'carousel-item-next'; 1139 const CLASS_NAME_PREV = 'carousel-item-prev'; 1140 const SELECTOR_ACTIVE = '.active'; 1141 const SELECTOR_ITEM = '.carousel-item'; 1142 const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM; 1143 const SELECTOR_ITEM_IMG = '.carousel-item img'; 1144 const SELECTOR_INDICATORS = '.carousel-indicators'; 1145 const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'; 1146 const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]'; 1147 const KEY_TO_DIRECTION = { 1148 [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT, 1149 [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT 1150 }; 1151 const Default$b = { 1152 interval: 5000, 1153 keyboard: true, 1154 pause: 'hover', 1155 ride: false, 1156 touch: true, 1157 wrap: true 1158 }; 1159 const DefaultType$b = { 1160 interval: '(number|boolean)', 1161 // TODO:v6 remove boolean support 1162 keyboard: 'boolean', 1163 pause: '(string|boolean)', 1164 ride: '(boolean|string)', 1165 touch: 'boolean', 1166 wrap: 'boolean' 1167 }; 1168 1169 /** 1170 * Class definition 1171 */ 1172 1173 class Carousel extends BaseComponent { 1174 constructor(element, config) { 1175 super(element, config); 1176 this._interval = null; 1177 this._activeElement = null; 1178 this._isSliding = false; 1179 this.touchTimeout = null; 1180 this._swipeHelper = null; 1181 this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element); 1182 this._addEventListeners(); 1183 if (this._config.ride === CLASS_NAME_CAROUSEL) { 1184 this.cycle(); 1185 } 1186 } 1187 1188 // Getters 1189 static get Default() { 1190 return Default$b; 1191 } 1192 static get DefaultType() { 1193 return DefaultType$b; 1194 } 1195 static get NAME() { 1196 return NAME$c; 1197 } 1198 1199 // Public 1200 next() { 1201 this._slide(ORDER_NEXT); 1202 } 1203 nextWhenVisible() { 1204 // FIXME TODO use `document.visibilityState` 1205 // Don't call next when the page isn't visible 1206 // or the carousel or its parent isn't visible 1207 if (!document.hidden && isVisible(this._element)) { 1208 this.next(); 1209 } 1210 } 1211 prev() { 1212 this._slide(ORDER_PREV); 1213 } 1214 pause() { 1215 if (this._isSliding) { 1216 triggerTransitionEnd(this._element); 1217 } 1218 this._clearInterval(); 1219 } 1220 cycle() { 1221 this._clearInterval(); 1222 this._updateInterval(); 1223 this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval); 1224 } 1225 _maybeEnableCycle() { 1226 if (!this._config.ride) { 1227 return; 1228 } 1229 if (this._isSliding) { 1230 EventHandler.one(this._element, EVENT_SLID, () => this.cycle()); 1231 return; 1232 } 1233 this.cycle(); 1234 } 1235 to(index) { 1236 const items = this._getItems(); 1237 if (index > items.length - 1 || index < 0) { 1238 return; 1239 } 1240 if (this._isSliding) { 1241 EventHandler.one(this._element, EVENT_SLID, () => this.to(index)); 1242 return; 1243 } 1244 const activeIndex = this._getItemIndex(this._getActive()); 1245 if (activeIndex === index) { 1246 return; 1247 } 1248 const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV; 1249 this._slide(order, items[index]); 1250 } 1251 dispose() { 1252 if (this._swipeHelper) { 1253 this._swipeHelper.dispose(); 1254 } 1255 super.dispose(); 1256 } 1257 1258 // Private 1259 _configAfterMerge(config) { 1260 config.defaultInterval = config.interval; 1261 return config; 1262 } 1263 _addEventListeners() { 1264 if (this._config.keyboard) { 1265 EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event)); 1266 } 1267 if (this._config.pause === 'hover') { 1268 EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause()); 1269 EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle()); 1270 } 1271 if (this._config.touch && Swipe.isSupported()) { 1272 this._addTouchEventListeners(); 1273 } 1274 } 1275 _addTouchEventListeners() { 1276 for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) { 1277 EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault()); 1278 } 1279 const endCallBack = () => { 1280 if (this._config.pause !== 'hover') { 1281 return; 1282 } 1283 1284 // If it's a touch-enabled device, mouseenter/leave are fired as 1285 // part of the mouse compatibility events on first tap - the carousel 1286 // would stop cycling until user tapped out of it; 1287 // here, we listen for touchend, explicitly pause the carousel 1288 // (as if it's the second time we tap on it, mouseenter compat event 1289 // is NOT fired) and after a timeout (to allow for mouse compatibility 1290 // events to fire) we explicitly restart cycling 1291 1292 this.pause(); 1293 if (this.touchTimeout) { 1294 clearTimeout(this.touchTimeout); 1295 } 1296 this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval); 1297 }; 1298 const swipeConfig = { 1299 leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)), 1300 rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)), 1301 endCallback: endCallBack 1302 }; 1303 this._swipeHelper = new Swipe(this._element, swipeConfig); 1304 } 1305 _keydown(event) { 1306 if (/input|textarea/i.test(event.target.tagName)) { 1307 return; 1308 } 1309 const direction = KEY_TO_DIRECTION[event.key]; 1310 if (direction) { 1311 event.preventDefault(); 1312 this._slide(this._directionToOrder(direction)); 1313 } 1314 } 1315 _getItemIndex(element) { 1316 return this._getItems().indexOf(element); 1317 } 1318 _setActiveIndicatorElement(index) { 1319 if (!this._indicatorsElement) { 1320 return; 1321 } 1322 const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement); 1323 activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2); 1324 activeIndicator.removeAttribute('aria-current'); 1325 const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement); 1326 if (newActiveIndicator) { 1327 newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2); 1328 newActiveIndicator.setAttribute('aria-current', 'true'); 1329 } 1330 } 1331 _updateInterval() { 1332 const element = this._activeElement || this._getActive(); 1333 if (!element) { 1334 return; 1335 } 1336 const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10); 1337 this._config.interval = elementInterval || this._config.defaultInterval; 1338 } 1339 _slide(order, element = null) { 1340 if (this._isSliding) { 1341 return; 1342 } 1343 const activeElement = this._getActive(); 1344 const isNext = order === ORDER_NEXT; 1345 const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap); 1346 if (nextElement === activeElement) { 1347 return; 1348 } 1349 const nextElementIndex = this._getItemIndex(nextElement); 1350 const triggerEvent = eventName => { 1351 return EventHandler.trigger(this._element, eventName, { 1352 relatedTarget: nextElement, 1353 direction: this._orderToDirection(order), 1354 from: this._getItemIndex(activeElement), 1355 to: nextElementIndex 1356 }); 1357 }; 1358 const slideEvent = triggerEvent(EVENT_SLIDE); 1359 if (slideEvent.defaultPrevented) { 1360 return; 1361 } 1362 if (!activeElement || !nextElement) { 1363 // Some weirdness is happening, so we bail 1364 // TODO: change tests that use empty divs to avoid this check 1365 return; 1366 } 1367 const isCycling = Boolean(this._interval); 1368 this.pause(); 1369 this._isSliding = true; 1370 this._setActiveIndicatorElement(nextElementIndex); 1371 this._activeElement = nextElement; 1372 const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END; 1373 const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV; 1374 nextElement.classList.add(orderClassName); 1375 reflow(nextElement); 1376 activeElement.classList.add(directionalClassName); 1377 nextElement.classList.add(directionalClassName); 1378 const completeCallBack = () => { 1379 nextElement.classList.remove(directionalClassName, orderClassName); 1380 nextElement.classList.add(CLASS_NAME_ACTIVE$2); 1381 activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName); 1382 this._isSliding = false; 1383 triggerEvent(EVENT_SLID); 1384 }; 1385 this._queueCallback(completeCallBack, activeElement, this._isAnimated()); 1386 if (isCycling) { 1387 this.cycle(); 1388 } 1389 } 1390 _isAnimated() { 1391 return this._element.classList.contains(CLASS_NAME_SLIDE); 1392 } 1393 _getActive() { 1394 return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element); 1395 } 1396 _getItems() { 1397 return SelectorEngine.find(SELECTOR_ITEM, this._element); 1398 } 1399 _clearInterval() { 1400 if (this._interval) { 1401 clearInterval(this._interval); 1402 this._interval = null; 1403 } 1404 } 1405 _directionToOrder(direction) { 1406 if (isRTL()) { 1407 return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT; 1408 } 1409 return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV; 1410 } 1411 _orderToDirection(order) { 1412 if (isRTL()) { 1413 return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT; 1414 } 1415 return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT; 1416 } 1417 1418 // Static 1419 static jQueryInterface(config) { 1420 return this.each(function () { 1421 const data = Carousel.getOrCreateInstance(this, config); 1422 if (typeof config === 'number') { 1423 data.to(config); 1424 return; 1425 } 1426 if (typeof config === 'string') { 1427 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 1428 throw new TypeError(`No method named "${config}"`); 1429 } 1430 data[config](); 1431 } 1432 }); 1433 } 1434 } 1435 1436 /** 1437 * Data API implementation 1438 */ 1439 1440 EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) { 1441 const target = SelectorEngine.getElementFromSelector(this); 1442 if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) { 1443 return; 1444 } 1445 event.preventDefault(); 1446 const carousel = Carousel.getOrCreateInstance(target); 1447 const slideIndex = this.getAttribute('data-bs-slide-to'); 1448 if (slideIndex) { 1449 carousel.to(slideIndex); 1450 carousel._maybeEnableCycle(); 1451 return; 1452 } 1453 if (Manipulator.getDataAttribute(this, 'slide') === 'next') { 1454 carousel.next(); 1455 carousel._maybeEnableCycle(); 1456 return; 1457 } 1458 carousel.prev(); 1459 carousel._maybeEnableCycle(); 1460 }); 1461 EventHandler.on(window, EVENT_LOAD_DATA_API$3, () => { 1462 const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE); 1463 for (const carousel of carousels) { 1464 Carousel.getOrCreateInstance(carousel); 1465 } 1466 }); 1467 1468 /** 1469 * jQuery 1470 */ 1471 1472 defineJQueryPlugin(Carousel); 1473 1474 /** 1475 * -------------------------------------------------------------------------- 1476 * Bootstrap collapse.js 1477 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 1478 * -------------------------------------------------------------------------- 1479 */ 1480 1481 1482 /** 1483 * Constants 1484 */ 1485 1486 const NAME$b = 'collapse'; 1487 const DATA_KEY$7 = 'bs.collapse'; 1488 const EVENT_KEY$7 = `.${DATA_KEY$7}`; 1489 const DATA_API_KEY$4 = '.data-api'; 1490 const EVENT_SHOW$6 = `show${EVENT_KEY$7}`; 1491 const EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`; 1492 const EVENT_HIDE$6 = `hide${EVENT_KEY$7}`; 1493 const EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`; 1494 const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`; 1495 const CLASS_NAME_SHOW$7 = 'show'; 1496 const CLASS_NAME_COLLAPSE = 'collapse'; 1497 const CLASS_NAME_COLLAPSING = 'collapsing'; 1498 const CLASS_NAME_COLLAPSED = 'collapsed'; 1499 const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`; 1500 const CLASS_NAME_HORIZONTAL = 'collapse-horizontal'; 1501 const WIDTH = 'width'; 1502 const HEIGHT = 'height'; 1503 const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing'; 1504 const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle="collapse"]'; 1505 const Default$a = { 1506 parent: null, 1507 toggle: true 1508 }; 1509 const DefaultType$a = { 1510 parent: '(null|element)', 1511 toggle: 'boolean' 1512 }; 1513 1514 /** 1515 * Class definition 1516 */ 1517 1518 class Collapse extends BaseComponent { 1519 constructor(element, config) { 1520 super(element, config); 1521 this._isTransitioning = false; 1522 this._triggerArray = []; 1523 const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4); 1524 for (const elem of toggleList) { 1525 const selector = SelectorEngine.getSelectorFromElement(elem); 1526 const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element); 1527 if (selector !== null && filterElement.length) { 1528 this._triggerArray.push(elem); 1529 } 1530 } 1531 this._initializeChildren(); 1532 if (!this._config.parent) { 1533 this._addAriaAndCollapsedClass(this._triggerArray, this._isShown()); 1534 } 1535 if (this._config.toggle) { 1536 this.toggle(); 1537 } 1538 } 1539 1540 // Getters 1541 static get Default() { 1542 return Default$a; 1543 } 1544 static get DefaultType() { 1545 return DefaultType$a; 1546 } 1547 static get NAME() { 1548 return NAME$b; 1549 } 1550 1551 // Public 1552 toggle() { 1553 if (this._isShown()) { 1554 this.hide(); 1555 } else { 1556 this.show(); 1557 } 1558 } 1559 show() { 1560 if (this._isTransitioning || this._isShown()) { 1561 return; 1562 } 1563 let activeChildren = []; 1564 1565 // find active children 1566 if (this._config.parent) { 1567 activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, { 1568 toggle: false 1569 })); 1570 } 1571 if (activeChildren.length && activeChildren[0]._isTransitioning) { 1572 return; 1573 } 1574 const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6); 1575 if (startEvent.defaultPrevented) { 1576 return; 1577 } 1578 for (const activeInstance of activeChildren) { 1579 activeInstance.hide(); 1580 } 1581 const dimension = this._getDimension(); 1582 this._element.classList.remove(CLASS_NAME_COLLAPSE); 1583 this._element.classList.add(CLASS_NAME_COLLAPSING); 1584 this._element.style[dimension] = 0; 1585 this._addAriaAndCollapsedClass(this._triggerArray, true); 1586 this._isTransitioning = true; 1587 const complete = () => { 1588 this._isTransitioning = false; 1589 this._element.classList.remove(CLASS_NAME_COLLAPSING); 1590 this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7); 1591 this._element.style[dimension] = ''; 1592 EventHandler.trigger(this._element, EVENT_SHOWN$6); 1593 }; 1594 const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); 1595 const scrollSize = `scroll${capitalizedDimension}`; 1596 this._queueCallback(complete, this._element, true); 1597 this._element.style[dimension] = `${this._element[scrollSize]}px`; 1598 } 1599 hide() { 1600 if (this._isTransitioning || !this._isShown()) { 1601 return; 1602 } 1603 const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6); 1604 if (startEvent.defaultPrevented) { 1605 return; 1606 } 1607 const dimension = this._getDimension(); 1608 this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`; 1609 reflow(this._element); 1610 this._element.classList.add(CLASS_NAME_COLLAPSING); 1611 this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7); 1612 for (const trigger of this._triggerArray) { 1613 const element = SelectorEngine.getElementFromSelector(trigger); 1614 if (element && !this._isShown(element)) { 1615 this._addAriaAndCollapsedClass([trigger], false); 1616 } 1617 } 1618 this._isTransitioning = true; 1619 const complete = () => { 1620 this._isTransitioning = false; 1621 this._element.classList.remove(CLASS_NAME_COLLAPSING); 1622 this._element.classList.add(CLASS_NAME_COLLAPSE); 1623 EventHandler.trigger(this._element, EVENT_HIDDEN$6); 1624 }; 1625 this._element.style[dimension] = ''; 1626 this._queueCallback(complete, this._element, true); 1627 } 1628 1629 // Private 1630 _isShown(element = this._element) { 1631 return element.classList.contains(CLASS_NAME_SHOW$7); 1632 } 1633 _configAfterMerge(config) { 1634 config.toggle = Boolean(config.toggle); // Coerce string values 1635 config.parent = getElement(config.parent); 1636 return config; 1637 } 1638 _getDimension() { 1639 return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT; 1640 } 1641 _initializeChildren() { 1642 if (!this._config.parent) { 1643 return; 1644 } 1645 const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4); 1646 for (const element of children) { 1647 const selected = SelectorEngine.getElementFromSelector(element); 1648 if (selected) { 1649 this._addAriaAndCollapsedClass([element], this._isShown(selected)); 1650 } 1651 } 1652 } 1653 _getFirstLevelChildren(selector) { 1654 const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent); 1655 // remove children if greater depth 1656 return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element)); 1657 } 1658 _addAriaAndCollapsedClass(triggerArray, isOpen) { 1659 if (!triggerArray.length) { 1660 return; 1661 } 1662 for (const element of triggerArray) { 1663 element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen); 1664 element.setAttribute('aria-expanded', isOpen); 1665 } 1666 } 1667 1668 // Static 1669 static jQueryInterface(config) { 1670 const _config = {}; 1671 if (typeof config === 'string' && /show|hide/.test(config)) { 1672 _config.toggle = false; 1673 } 1674 return this.each(function () { 1675 const data = Collapse.getOrCreateInstance(this, _config); 1676 if (typeof config === 'string') { 1677 if (typeof data[config] === 'undefined') { 1678 throw new TypeError(`No method named "${config}"`); 1679 } 1680 data[config](); 1681 } 1682 }); 1683 } 1684 } 1685 1686 /** 1687 * Data API implementation 1688 */ 1689 1690 EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) { 1691 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element 1692 if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') { 1693 event.preventDefault(); 1694 } 1695 for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) { 1696 Collapse.getOrCreateInstance(element, { 1697 toggle: false 1698 }).toggle(); 1699 } 1700 }); 1701 1702 /** 1703 * jQuery 1704 */ 1705 1706 defineJQueryPlugin(Collapse); 1707 1708 /** 1709 * -------------------------------------------------------------------------- 1710 * Bootstrap dropdown.js 1711 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 1712 * -------------------------------------------------------------------------- 1713 */ 1714 1715 1716 /** 1717 * Constants 1718 */ 1719 1720 const NAME$a = 'dropdown'; 1721 const DATA_KEY$6 = 'bs.dropdown'; 1722 const EVENT_KEY$6 = `.${DATA_KEY$6}`; 1723 const DATA_API_KEY$3 = '.data-api'; 1724 const ESCAPE_KEY$2 = 'Escape'; 1725 const TAB_KEY$1 = 'Tab'; 1726 const ARROW_UP_KEY$1 = 'ArrowUp'; 1727 const ARROW_DOWN_KEY$1 = 'ArrowDown'; 1728 const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button 1729 1730 const EVENT_HIDE$5 = `hide${EVENT_KEY$6}`; 1731 const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`; 1732 const EVENT_SHOW$5 = `show${EVENT_KEY$6}`; 1733 const EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`; 1734 const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`; 1735 const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`; 1736 const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`; 1737 const CLASS_NAME_SHOW$6 = 'show'; 1738 const CLASS_NAME_DROPUP = 'dropup'; 1739 const CLASS_NAME_DROPEND = 'dropend'; 1740 const CLASS_NAME_DROPSTART = 'dropstart'; 1741 const CLASS_NAME_DROPUP_CENTER = 'dropup-center';
vendor: 6,615 bytes, lines 1742-1913
1742 const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center'; 1743 const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)'; 1744 const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`; 1745 const SELECTOR_MENU = '.dropdown-menu'; 1746 const SELECTOR_NAVBAR = '.navbar'; 1747 const SELECTOR_NAVBAR_NAV = '.navbar-nav'; 1748 const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'; 1749 const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start'; 1750 const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end'; 1751 const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start'; 1752 const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end'; 1753 const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start'; 1754 const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start'; 1755 const PLACEMENT_TOPCENTER = 'top'; 1756 const PLACEMENT_BOTTOMCENTER = 'bottom'; 1757 const Default$9 = { 1758 autoClose: true, 1759 boundary: 'clippingParents', 1760 display: 'dynamic', 1761 offset: [0, 2], 1762 popperConfig: null, 1763 reference: 'toggle' 1764 }; 1765 const DefaultType$9 = { 1766 autoClose: '(boolean|string)', 1767 boundary: '(string|element)', 1768 display: 'string', 1769 offset: '(array|string|function)', 1770 popperConfig: '(null|object|function)', 1771 reference: '(string|element|object)' 1772 }; 1773 1774 /** 1775 * Class definition 1776 */ 1777 1778 class Dropdown extends BaseComponent { 1779 constructor(element, config) { 1780 super(element, config); 1781 this._popper = null; 1782 this._parent = this._element.parentNode; // dropdown wrapper 1783 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/ 1784 this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent); 1785 this._inNavbar = this._detectNavbar(); 1786 } 1787 1788 // Getters 1789 static get Default() { 1790 return Default$9; 1791 } 1792 static get DefaultType() { 1793 return DefaultType$9; 1794 } 1795 static get NAME() { 1796 return NAME$a; 1797 } 1798 1799 // Public 1800 toggle() { 1801 return this._isShown() ? this.hide() : this.show(); 1802 } 1803 show() { 1804 if (isDisabled(this._element) || this._isShown()) { 1805 return; 1806 } 1807 const relatedTarget = { 1808 relatedTarget: this._element 1809 }; 1810 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget); 1811 if (showEvent.defaultPrevented) { 1812 return; 1813 } 1814 this._createPopper(); 1815 1816 // If this is a touch-enabled device we add extra 1817 // empty mouseover listeners to the body's immediate children; 1818 // only needed because of broken event delegation on iOS 1819 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 1820 if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) { 1821 for (const element of [].concat(...document.body.children)) { 1822 EventHandler.on(element, 'mouseover', noop); 1823 } 1824 } 1825 this._element.focus(); 1826 this._element.setAttribute('aria-expanded', true); 1827 this._menu.classList.add(CLASS_NAME_SHOW$6); 1828 this._element.classList.add(CLASS_NAME_SHOW$6); 1829 EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget); 1830 } 1831 hide() { 1832 if (isDisabled(this._element) || !this._isShown()) { 1833 return; 1834 } 1835 const relatedTarget = { 1836 relatedTarget: this._element 1837 }; 1838 this._completeHide(relatedTarget); 1839 } 1840 dispose() { 1841 if (this._popper) { 1842 this._popper.destroy(); 1843 } 1844 super.dispose(); 1845 } 1846 update() { 1847 this._inNavbar = this._detectNavbar(); 1848 if (this._popper) { 1849 this._popper.update(); 1850 } 1851 } 1852 1853 // Private 1854 _completeHide(relatedTarget) { 1855 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget); 1856 if (hideEvent.defaultPrevented) { 1857 return; 1858 } 1859 1860 // If this is a touch-enabled device we remove the extra 1861 // empty mouseover listeners we added for iOS support 1862 if ('ontouchstart' in document.documentElement) { 1863 for (const element of [].concat(...document.body.children)) { 1864 EventHandler.off(element, 'mouseover', noop); 1865 } 1866 } 1867 if (this._popper) { 1868 this._popper.destroy(); 1869 } 1870 this._menu.classList.remove(CLASS_NAME_SHOW$6); 1871 this._element.classList.remove(CLASS_NAME_SHOW$6); 1872 this._element.setAttribute('aria-expanded', 'false'); 1873 Manipulator.removeDataAttribute(this._menu, 'popper'); 1874 EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget); 1875 } 1876 _getConfig(config) { 1877 config = super._getConfig(config); 1878 if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') { 1879 // Popper virtual elements require a getBoundingClientRect method 1880 throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`); 1881 } 1882 return config; 1883 } 1884 _createPopper() { 1885 if (typeof Popper__namespace === 'undefined') { 1886 throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org/docs/v2/)'); 1887 } 1888 let referenceElement = this._element; 1889 if (this._config.reference === 'parent') { 1890 referenceElement = this._parent; 1891 } else if (isElement(this._config.reference)) { 1892 referenceElement = getElement(this._config.reference); 1893 } else if (typeof this._config.reference === 'object') { 1894 referenceElement = this._config.reference; 1895 } 1896 const popperConfig = this._getPopperConfig(); 1897 this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig); 1898 } 1899 _isShown() { 1900 return this._menu.classList.contains(CLASS_NAME_SHOW$6); 1901 } 1902 _getPlacement() { 1903 const parentDropdown = this._parent; 1904 if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) { 1905 return PLACEMENT_RIGHT; 1906 } 1907 if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) { 1908 return PLACEMENT_LEFT; 1909 } 1910 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) { 1911 return PLACEMENT_TOPCENTER; 1912 } 1913 if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENT
vendor: 50,204 bytes, lines 1913-3466
1913ER)) { 1914 return PLACEMENT_BOTTOMCENTER; 1915 } 1916 1917 // We need to trim the value because custom properties can also include spaces 1918 const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'; 1919 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) { 1920 return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP; 1921 } 1922 return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM; 1923 } 1924 _detectNavbar() { 1925 return this._element.closest(SELECTOR_NAVBAR) !== null; 1926 } 1927 _getOffset() { 1928 const { 1929 offset 1930 } = this._config; 1931 if (typeof offset === 'string') { 1932 return offset.split(',').map(value => Number.parseInt(value, 10)); 1933 } 1934 if (typeof offset === 'function') { 1935 return popperData => offset(popperData, this._element); 1936 } 1937 return offset; 1938 } 1939 _getPopperConfig() { 1940 const defaultBsPopperConfig = { 1941 placement: this._getPlacement(), 1942 modifiers: [{ 1943 name: 'preventOverflow', 1944 options: { 1945 boundary: this._config.boundary 1946 } 1947 }, { 1948 name: 'offset', 1949 options: { 1950 offset: this._getOffset() 1951 } 1952 }] 1953 }; 1954 1955 // Disable Popper if we have a static display or Dropdown is in Navbar 1956 if (this._inNavbar || this._config.display === 'static') { 1957 Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove 1958 defaultBsPopperConfig.modifiers = [{ 1959 name: 'applyStyles', 1960 enabled: false 1961 }]; 1962 } 1963 return { 1964 ...defaultBsPopperConfig, 1965 ...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig]) 1966 }; 1967 } 1968 _selectMenuItem({ 1969 key, 1970 target 1971 }) { 1972 const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element)); 1973 if (!items.length) { 1974 return; 1975 } 1976 1977 // if target isn't included in items (e.g. when expanding the dropdown) 1978 // allow cycling to get the last item in case key equals ARROW_UP_KEY 1979 getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus(); 1980 } 1981 1982 // Static 1983 static jQueryInterface(config) { 1984 return this.each(function () { 1985 const data = Dropdown.getOrCreateInstance(this, config); 1986 if (typeof config !== 'string') { 1987 return; 1988 } 1989 if (typeof data[config] === 'undefined') { 1990 throw new TypeError(`No method named "${config}"`); 1991 } 1992 data[config](); 1993 }); 1994 } 1995 static clearMenus(event) { 1996 if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) { 1997 return; 1998 } 1999 const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN); 2000 for (const toggle of openToggles) { 2001 const context = Dropdown.getInstance(toggle); 2002 if (!context || context._config.autoClose === false) { 2003 continue; 2004 } 2005 const composedPath = event.composedPath(); 2006 const isMenuTarget = composedPath.includes(context._menu); 2007 if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) { 2008 continue; 2009 } 2010 2011 // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu 2012 if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) { 2013 continue; 2014 } 2015 const relatedTarget = { 2016 relatedTarget: context._element 2017 }; 2018 if (event.type === 'click') { 2019 relatedTarget.clickEvent = event; 2020 } 2021 context._completeHide(relatedTarget); 2022 } 2023 } 2024 static dataApiKeydownHandler(event) { 2025 // If not an UP | DOWN | ESCAPE key => not a dropdown command 2026 // If input/textarea && if key is other than ESCAPE => not a dropdown command 2027 2028 const isInput = /input|textarea/i.test(event.target.tagName); 2029 const isEscapeEvent = event.key === ESCAPE_KEY$2; 2030 const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key); 2031 if (!isUpOrDownEvent && !isEscapeEvent) { 2032 return; 2033 } 2034 if (isInput && !isEscapeEvent) { 2035 return; 2036 } 2037 event.preventDefault(); 2038 2039 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/ 2040 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); 2041 const instance = Dropdown.getOrCreateInstance(getToggleButton); 2042 if (isUpOrDownEvent) { 2043 event.stopPropagation(); 2044 instance.show(); 2045 instance._selectMenuItem(event); 2046 return; 2047 } 2048 if (instance._isShown()) { 2049 // else is escape and we check if it is shown 2050 event.stopPropagation(); 2051 instance.hide(); 2052 getToggleButton.focus(); 2053 } 2054 } 2055 } 2056 2057 /** 2058 * Data API implementation 2059 */ 2060 2061 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler); 2062 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler); 2063 EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus); 2064 EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus); 2065 EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) { 2066 event.preventDefault(); 2067 Dropdown.getOrCreateInstance(this).toggle(); 2068 }); 2069 2070 /** 2071 * jQuery 2072 */ 2073 2074 defineJQueryPlugin(Dropdown); 2075 2076 /** 2077 * -------------------------------------------------------------------------- 2078 * Bootstrap util/backdrop.js 2079 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 2080 * -------------------------------------------------------------------------- 2081 */ 2082 2083 2084 /** 2085 * Constants 2086 */ 2087 2088 const NAME$9 = 'backdrop'; 2089 const CLASS_NAME_FADE$4 = 'fade'; 2090 const CLASS_NAME_SHOW$5 = 'show'; 2091 const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`; 2092 const Default$8 = { 2093 className: 'modal-backdrop', 2094 clickCallback: null, 2095 isAnimated: false, 2096 isVisible: true, 2097 // if false, we use the backdrop helper without adding any element to the dom 2098 rootElement: 'body' // give the choice to place backdrop under different elements 2099 }; 2100 const DefaultType$8 = { 2101 className: 'string', 2102 clickCallback: '(function|null)', 2103 isAnimated: 'boolean', 2104 isVisible: 'boolean', 2105 rootElement: '(element|string)' 2106 }; 2107 2108 /** 2109 * Class definition 2110 */ 2111 2112 class Backdrop extends Config { 2113 constructor(config) { 2114 super(); 2115 this._config = this._getConfig(config); 2116 this._isAppended = false; 2117 this._element = null; 2118 } 2119 2120 // Getters 2121 static get Default() { 2122 return Default$8; 2123 } 2124 static get DefaultType() { 2125 return DefaultType$8; 2126 } 2127 static get NAME() { 2128 return NAME$9; 2129 } 2130 2131 // Public 2132 show(callback) { 2133 if (!this._config.isVisible) { 2134 execute(callback); 2135 return; 2136 } 2137 this._append(); 2138 const element = this._getElement(); 2139 if (this._config.isAnimated) { 2140 reflow(element); 2141 } 2142 element.classList.add(CLASS_NAME_SHOW$5); 2143 this._emulateAnimation(() => { 2144 execute(callback); 2145 }); 2146 } 2147 hide(callback) { 2148 if (!this._config.isVisible) { 2149 execute(callback); 2150 return; 2151 } 2152 this._getElement().classList.remove(CLASS_NAME_SHOW$5); 2153 this._emulateAnimation(() => { 2154 this.dispose(); 2155 execute(callback); 2156 }); 2157 } 2158 dispose() { 2159 if (!this._isAppended) { 2160 return; 2161 } 2162 EventHandler.off(this._element, EVENT_MOUSEDOWN); 2163 this._element.remove(); 2164 this._isAppended = false; 2165 } 2166 2167 // Private 2168 _getElement() { 2169 if (!this._element) { 2170 const backdrop = document.createElement('div'); 2171 backdrop.className = this._config.className; 2172 if (this._config.isAnimated) { 2173 backdrop.classList.add(CLASS_NAME_FADE$4); 2174 } 2175 this._element = backdrop; 2176 } 2177 return this._element; 2178 } 2179 _configAfterMerge(config) { 2180 // use getElement() with the default "body" to get a fresh Element on each instantiation 2181 config.rootElement = getElement(config.rootElement); 2182 return config; 2183 } 2184 _append() { 2185 if (this._isAppended) { 2186 return; 2187 } 2188 const element = this._getElement(); 2189 this._config.rootElement.append(element); 2190 EventHandler.on(element, EVENT_MOUSEDOWN, () => { 2191 execute(this._config.clickCallback); 2192 }); 2193 this._isAppended = true; 2194 } 2195 _emulateAnimation(callback) { 2196 executeAfterTransition(callback, this._getElement(), this._config.isAnimated); 2197 } 2198 } 2199 2200 /** 2201 * -------------------------------------------------------------------------- 2202 * Bootstrap util/focustrap.js 2203 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 2204 * -------------------------------------------------------------------------- 2205 */ 2206 2207 2208 /** 2209 * Constants 2210 */ 2211 2212 const NAME$8 = 'focustrap'; 2213 const DATA_KEY$5 = 'bs.focustrap'; 2214 const EVENT_KEY$5 = `.${DATA_KEY$5}`; 2215 const EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`; 2216 const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`; 2217 const TAB_KEY = 'Tab'; 2218 const TAB_NAV_FORWARD = 'forward'; 2219 const TAB_NAV_BACKWARD = 'backward'; 2220 const Default$7 = { 2221 autofocus: true, 2222 trapElement: null // The element to trap focus inside of 2223 }; 2224 const DefaultType$7 = { 2225 autofocus: 'boolean', 2226 trapElement: 'element' 2227 }; 2228 2229 /** 2230 * Class definition 2231 */ 2232 2233 class FocusTrap extends Config { 2234 constructor(config) { 2235 super(); 2236 this._config = this._getConfig(config); 2237 this._isActive = false; 2238 this._lastTabNavDirection = null; 2239 } 2240 2241 // Getters 2242 static get Default() { 2243 return Default$7; 2244 } 2245 static get DefaultType() { 2246 return DefaultType$7; 2247 } 2248 static get NAME() { 2249 return NAME$8; 2250 } 2251 2252 // Public 2253 activate() { 2254 if (this._isActive) { 2255 return; 2256 } 2257 if (this._config.autofocus) { 2258 this._config.trapElement.focus(); 2259 } 2260 EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop 2261 EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event)); 2262 EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event)); 2263 this._isActive = true; 2264 } 2265 deactivate() { 2266 if (!this._isActive) { 2267 return; 2268 } 2269 this._isActive = false; 2270 EventHandler.off(document, EVENT_KEY$5); 2271 } 2272 2273 // Private 2274 _handleFocusin(event) { 2275 const { 2276 trapElement 2277 } = this._config; 2278 if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) { 2279 return; 2280 } 2281 const elements = SelectorEngine.focusableChildren(trapElement); 2282 if (elements.length === 0) { 2283 trapElement.focus(); 2284 } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) { 2285 elements[elements.length - 1].focus(); 2286 } else { 2287 elements[0].focus(); 2288 } 2289 } 2290 _handleKeydown(event) { 2291 if (event.key !== TAB_KEY) { 2292 return; 2293 } 2294 this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD; 2295 } 2296 } 2297 2298 /** 2299 * -------------------------------------------------------------------------- 2300 * Bootstrap util/scrollBar.js 2301 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 2302 * -------------------------------------------------------------------------- 2303 */ 2304 2305 2306 /** 2307 * Constants 2308 */ 2309 2310 const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'; 2311 const SELECTOR_STICKY_CONTENT = '.sticky-top'; 2312 const PROPERTY_PADDING = 'padding-right'; 2313 const PROPERTY_MARGIN = 'margin-right'; 2314 2315 /** 2316 * Class definition 2317 */ 2318 2319 class ScrollBarHelper { 2320 constructor() { 2321 this._element = document.body; 2322 } 2323 2324 // Public 2325 getWidth() { 2326 // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes 2327 const documentWidth = document.documentElement.clientWidth; 2328 return Math.abs(window.innerWidth - documentWidth); 2329 } 2330 hide() { 2331 const width = this.getWidth(); 2332 this._disableOverFlow(); 2333 // give padding to element to balance the hidden scrollbar width 2334 this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width); 2335 // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth 2336 this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width); 2337 this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width); 2338 } 2339 reset() { 2340 this._resetElementAttributes(this._element, 'overflow'); 2341 this._resetElementAttributes(this._element, PROPERTY_PADDING); 2342 this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING); 2343 this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN); 2344 } 2345 isOverflowing() { 2346 return this.getWidth() > 0; 2347 } 2348 2349 // Private 2350 _disableOverFlow() { 2351 this._saveInitialAttribute(this._element, 'overflow'); 2352 this._element.style.overflow = 'hidden'; 2353 } 2354 _setElementAttributes(selector, styleProperty, callback) { 2355 const scrollbarWidth = this.getWidth(); 2356 const manipulationCallBack = element => { 2357 if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) { 2358 return; 2359 } 2360 this._saveInitialAttribute(element, styleProperty); 2361 const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty); 2362 element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`); 2363 }; 2364 this._applyManipulationCallback(selector, manipulationCallBack); 2365 } 2366 _saveInitialAttribute(element, styleProperty) { 2367 const actualValue = element.style.getPropertyValue(styleProperty); 2368 if (actualValue) { 2369 Manipulator.setDataAttribute(element, styleProperty, actualValue); 2370 } 2371 } 2372 _resetElementAttributes(selector, styleProperty) { 2373 const manipulationCallBack = element => { 2374 const value = Manipulator.getDataAttribute(element, styleProperty); 2375 // We only want to remove the property if the value is `null`; the value can also be zero 2376 if (value === null) { 2377 element.style.removeProperty(styleProperty); 2378 return; 2379 } 2380 Manipulator.removeDataAttribute(element, styleProperty); 2381 element.style.setProperty(styleProperty, value); 2382 }; 2383 this._applyManipulationCallback(selector, manipulationCallBack); 2384 } 2385 _applyManipulationCallback(selector, callBack) { 2386 if (isElement(selector)) { 2387 callBack(selector); 2388 return; 2389 } 2390 for (const sel of SelectorEngine.find(selector, this._element)) { 2391 callBack(sel); 2392 } 2393 } 2394 } 2395 2396 /** 2397 * -------------------------------------------------------------------------- 2398 * Bootstrap modal.js 2399 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 2400 * -------------------------------------------------------------------------- 2401 */ 2402 2403 2404 /** 2405 * Constants 2406 */ 2407 2408 const NAME$7 = 'modal'; 2409 const DATA_KEY$4 = 'bs.modal'; 2410 const EVENT_KEY$4 = `.${DATA_KEY$4}`; 2411 const DATA_API_KEY$2 = '.data-api'; 2412 const ESCAPE_KEY$1 = 'Escape'; 2413 const EVENT_HIDE$4 = `hide${EVENT_KEY$4}`; 2414 const EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`; 2415 const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`; 2416 const EVENT_SHOW$4 = `show${EVENT_KEY$4}`; 2417 const EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`; 2418 const EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`; 2419 const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`; 2420 const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`; 2421 const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`; 2422 const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`; 2423 const CLASS_NAME_OPEN = 'modal-open'; 2424 const CLASS_NAME_FADE$3 = 'fade'; 2425 const CLASS_NAME_SHOW$4 = 'show'; 2426 const CLASS_NAME_STATIC = 'modal-static'; 2427 const OPEN_SELECTOR$1 = '.modal.show'; 2428 const SELECTOR_DIALOG = '.modal-dialog'; 2429 const SELECTOR_MODAL_BODY = '.modal-body'; 2430 const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle="modal"]'; 2431 const Default$6 = { 2432 backdrop: true, 2433 focus: true, 2434 keyboard: true 2435 }; 2436 const DefaultType$6 = { 2437 backdrop: '(boolean|string)', 2438 focus: 'boolean', 2439 keyboard: 'boolean' 2440 }; 2441 2442 /** 2443 * Class definition 2444 */ 2445 2446 class Modal extends BaseComponent { 2447 constructor(element, config) { 2448 super(element, config); 2449 this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element); 2450 this._backdrop = this._initializeBackDrop(); 2451 this._focustrap = this._initializeFocusTrap(); 2452 this._isShown = false; 2453 this._isTransitioning = false; 2454 this._scrollBar = new ScrollBarHelper(); 2455 this._addEventListeners(); 2456 } 2457 2458 // Getters 2459 static get Default() { 2460 return Default$6; 2461 } 2462 static get DefaultType() { 2463 return DefaultType$6; 2464 } 2465 static get NAME() { 2466 return NAME$7; 2467 } 2468 2469 // Public 2470 toggle(relatedTarget) { 2471 return this._isShown ? this.hide() : this.show(relatedTarget); 2472 } 2473 show(relatedTarget) { 2474 if (this._isShown || this._isTransitioning) { 2475 return; 2476 } 2477 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, { 2478 relatedTarget 2479 }); 2480 if (showEvent.defaultPrevented) { 2481 return; 2482 } 2483 this._isShown = true; 2484 this._isTransitioning = true; 2485 this._scrollBar.hide(); 2486 document.body.classList.add(CLASS_NAME_OPEN); 2487 this._adjustDialog(); 2488 this._backdrop.show(() => this._showElement(relatedTarget)); 2489 } 2490 hide() { 2491 if (!this._isShown || this._isTransitioning) { 2492 return; 2493 } 2494 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4); 2495 if (hideEvent.defaultPrevented) { 2496 return; 2497 } 2498 this._isShown = false; 2499 this._isTransitioning = true; 2500 this._focustrap.deactivate(); 2501 this._element.classList.remove(CLASS_NAME_SHOW$4); 2502 this._queueCallback(() => this._hideModal(), this._element, this._isAnimated()); 2503 } 2504 dispose() { 2505 EventHandler.off(window, EVENT_KEY$4); 2506 EventHandler.off(this._dialog, EVENT_KEY$4); 2507 this._backdrop.dispose(); 2508 this._focustrap.deactivate(); 2509 super.dispose(); 2510 } 2511 handleUpdate() { 2512 this._adjustDialog(); 2513 } 2514 2515 // Private 2516 _initializeBackDrop() { 2517 return new Backdrop({ 2518 isVisible: Boolean(this._config.backdrop), 2519 // 'static' option will be translated to true, and booleans will keep their value, 2520 isAnimated: this._isAnimated() 2521 }); 2522 } 2523 _initializeFocusTrap() { 2524 return new FocusTrap({ 2525 trapElement: this._element 2526 }); 2527 } 2528 _showElement(relatedTarget) { 2529 // try to append dynamic modal 2530 if (!document.body.contains(this._element)) { 2531 document.body.append(this._element); 2532 } 2533 this._element.style.display = 'block'; 2534 this._element.removeAttribute('aria-hidden'); 2535 this._element.setAttribute('aria-modal', true); 2536 this._element.setAttribute('role', 'dialog'); 2537 this._element.scrollTop = 0; 2538 const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog); 2539 if (modalBody) { 2540 modalBody.scrollTop = 0; 2541 } 2542 reflow(this._element); 2543 this._element.classList.add(CLASS_NAME_SHOW$4); 2544 const transitionComplete = () => { 2545 if (this._config.focus) { 2546 this._focustrap.activate(); 2547 } 2548 this._isTransitioning = false; 2549 EventHandler.trigger(this._element, EVENT_SHOWN$4, { 2550 relatedTarget 2551 }); 2552 }; 2553 this._queueCallback(transitionComplete, this._dialog, this._isAnimated()); 2554 } 2555 _addEventListeners() { 2556 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => { 2557 if (event.key !== ESCAPE_KEY$1) { 2558 return; 2559 } 2560 if (this._config.keyboard) { 2561 this.hide(); 2562 return; 2563 } 2564 this._triggerBackdropTransition(); 2565 }); 2566 EventHandler.on(window, EVENT_RESIZE$1, () => { 2567 if (this._isShown && !this._isTransitioning) { 2568 this._adjustDialog(); 2569 } 2570 }); 2571 EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => { 2572 // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks 2573 EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => { 2574 if (this._element !== event.target || this._element !== event2.target) { 2575 return; 2576 } 2577 if (this._config.backdrop === 'static') { 2578 this._triggerBackdropTransition(); 2579 return; 2580 } 2581 if (this._config.backdrop) { 2582 this.hide(); 2583 } 2584 }); 2585 }); 2586 } 2587 _hideModal() { 2588 this._element.style.display = 'none'; 2589 this._element.setAttribute('aria-hidden', true); 2590 this._element.removeAttribute('aria-modal'); 2591 this._element.removeAttribute('role'); 2592 this._isTransitioning = false; 2593 this._backdrop.hide(() => { 2594 document.body.classList.remove(CLASS_NAME_OPEN); 2595 this._resetAdjustments(); 2596 this._scrollBar.reset(); 2597 EventHandler.trigger(this._element, EVENT_HIDDEN$4); 2598 }); 2599 } 2600 _isAnimated() { 2601 return this._element.classList.contains(CLASS_NAME_FADE$3); 2602 } 2603 _triggerBackdropTransition() { 2604 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1); 2605 if (hideEvent.defaultPrevented) { 2606 return; 2607 } 2608 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 2609 const initialOverflowY = this._element.style.overflowY; 2610 // return if the following background transition hasn't yet completed 2611 if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) { 2612 return; 2613 } 2614 if (!isModalOverflowing) { 2615 this._element.style.overflowY = 'hidden'; 2616 } 2617 this._element.classList.add(CLASS_NAME_STATIC); 2618 this._queueCallback(() => { 2619 this._element.classList.remove(CLASS_NAME_STATIC); 2620 this._queueCallback(() => { 2621 this._element.style.overflowY = initialOverflowY; 2622 }, this._dialog); 2623 }, this._dialog); 2624 this._element.focus(); 2625 } 2626 2627 /** 2628 * The following methods are used to handle overflowing modals 2629 */ 2630 2631 _adjustDialog() { 2632 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 2633 const scrollbarWidth = this._scrollBar.getWidth(); 2634 const isBodyOverflowing = scrollbarWidth > 0; 2635 if (isBodyOverflowing && !isModalOverflowing) { 2636 const property = isRTL() ? 'paddingLeft' : 'paddingRight'; 2637 this._element.style[property] = `${scrollbarWidth}px`; 2638 } 2639 if (!isBodyOverflowing && isModalOverflowing) { 2640 const property = isRTL() ? 'paddingRight' : 'paddingLeft'; 2641 this._element.style[property] = `${scrollbarWidth}px`; 2642 } 2643 } 2644 _resetAdjustments() { 2645 this._element.style.paddingLeft = ''; 2646 this._element.style.paddingRight = ''; 2647 } 2648 2649 // Static 2650 static jQueryInterface(config, relatedTarget) { 2651 return this.each(function () { 2652 const data = Modal.getOrCreateInstance(this, config); 2653 if (typeof config !== 'string') { 2654 return; 2655 } 2656 if (typeof data[config] === 'undefined') { 2657 throw new TypeError(`No method named "${config}"`); 2658 } 2659 data[config](relatedTarget); 2660 }); 2661 } 2662 } 2663 2664 /** 2665 * Data API implementation 2666 */ 2667 2668 EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) { 2669 const target = SelectorEngine.getElementFromSelector(this); 2670 if (['A', 'AREA'].includes(this.tagName)) { 2671 event.preventDefault(); 2672 } 2673 EventHandler.one(target, EVENT_SHOW$4, showEvent => { 2674 if (showEvent.defaultPrevented) { 2675 // only register focus restorer if modal will actually get shown 2676 return; 2677 } 2678 EventHandler.one(target, EVENT_HIDDEN$4, () => { 2679 if (isVisible(this)) { 2680 this.focus(); 2681 } 2682 }); 2683 }); 2684 2685 // avoid conflict when clicking modal toggler while another one is open 2686 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1); 2687 if (alreadyOpen) { 2688 Modal.getInstance(alreadyOpen).hide(); 2689 } 2690 const data = Modal.getOrCreateInstance(target); 2691 data.toggle(this); 2692 }); 2693 enableDismissTrigger(Modal); 2694 2695 /** 2696 * jQuery 2697 */ 2698 2699 defineJQueryPlugin(Modal); 2700 2701 /** 2702 * -------------------------------------------------------------------------- 2703 * Bootstrap offcanvas.js 2704 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 2705 * -------------------------------------------------------------------------- 2706 */ 2707 2708 2709 /** 2710 * Constants 2711 */ 2712 2713 const NAME$6 = 'offcanvas'; 2714 const DATA_KEY$3 = 'bs.offcanvas'; 2715 const EVENT_KEY$3 = `.${DATA_KEY$3}`; 2716 const DATA_API_KEY$1 = '.data-api'; 2717 const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`; 2718 const ESCAPE_KEY = 'Escape'; 2719 const CLASS_NAME_SHOW$3 = 'show'; 2720 const CLASS_NAME_SHOWING$1 = 'showing'; 2721 const CLASS_NAME_HIDING = 'hiding'; 2722 const CLASS_NAME_BACKDROP = 'offcanvas-backdrop'; 2723 const OPEN_SELECTOR = '.offcanvas.show'; 2724 const EVENT_SHOW$3 = `show${EVENT_KEY$3}`; 2725 const EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`; 2726 const EVENT_HIDE$3 = `hide${EVENT_KEY$3}`; 2727 const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`; 2728 const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`; 2729 const EVENT_RESIZE = `resize${EVENT_KEY$3}`; 2730 const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`; 2731 const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`; 2732 const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="offcanvas"]'; 2733 const Default$5 = { 2734 backdrop: true, 2735 keyboard: true, 2736 scroll: false 2737 }; 2738 const DefaultType$5 = { 2739 backdrop: '(boolean|string)', 2740 keyboard: 'boolean', 2741 scroll: 'boolean' 2742 }; 2743 2744 /** 2745 * Class definition 2746 */ 2747 2748 class Offcanvas extends BaseComponent { 2749 constructor(element, config) { 2750 super(element, config); 2751 this._isShown = false; 2752 this._backdrop = this._initializeBackDrop(); 2753 this._focustrap = this._initializeFocusTrap(); 2754 this._addEventListeners(); 2755 } 2756 2757 // Getters 2758 static get Default() { 2759 return Default$5; 2760 } 2761 static get DefaultType() { 2762 return DefaultType$5; 2763 } 2764 static get NAME() { 2765 return NAME$6; 2766 } 2767 2768 // Public 2769 toggle(relatedTarget) { 2770 return this._isShown ? this.hide() : this.show(relatedTarget); 2771 } 2772 show(relatedTarget) { 2773 if (this._isShown) { 2774 return; 2775 } 2776 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, { 2777 relatedTarget 2778 }); 2779 if (showEvent.defaultPrevented) { 2780 return; 2781 } 2782 this._isShown = true; 2783 this._backdrop.show(); 2784 if (!this._config.scroll) { 2785 new ScrollBarHelper().hide(); 2786 } 2787 this._element.setAttribute('aria-modal', true); 2788 this._element.setAttribute('role', 'dialog'); 2789 this._element.classList.add(CLASS_NAME_SHOWING$1); 2790 const completeCallBack = () => { 2791 if (!this._config.scroll || this._config.backdrop) { 2792 this._focustrap.activate(); 2793 } 2794 this._element.classList.add(CLASS_NAME_SHOW$3); 2795 this._element.classList.remove(CLASS_NAME_SHOWING$1); 2796 EventHandler.trigger(this._element, EVENT_SHOWN$3, { 2797 relatedTarget 2798 }); 2799 }; 2800 this._queueCallback(completeCallBack, this._element, true); 2801 } 2802 hide() { 2803 if (!this._isShown) { 2804 return; 2805 } 2806 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3); 2807 if (hideEvent.defaultPrevented) { 2808 return; 2809 } 2810 this._focustrap.deactivate(); 2811 this._element.blur(); 2812 this._isShown = false; 2813 this._element.classList.add(CLASS_NAME_HIDING); 2814 this._backdrop.hide(); 2815 const completeCallback = () => { 2816 this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING); 2817 this._element.removeAttribute('aria-modal'); 2818 this._element.removeAttribute('role'); 2819 if (!this._config.scroll) { 2820 new ScrollBarHelper().reset(); 2821 } 2822 EventHandler.trigger(this._element, EVENT_HIDDEN$3); 2823 }; 2824 this._queueCallback(completeCallback, this._element, true); 2825 } 2826 dispose() { 2827 this._backdrop.dispose(); 2828 this._focustrap.deactivate(); 2829 super.dispose(); 2830 } 2831 2832 // Private 2833 _initializeBackDrop() { 2834 const clickCallback = () => { 2835 if (this._config.backdrop === 'static') { 2836 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); 2837 return; 2838 } 2839 this.hide(); 2840 }; 2841 2842 // 'static' option will be translated to true, and booleans will keep their value 2843 const isVisible = Boolean(this._config.backdrop); 2844 return new Backdrop({ 2845 className: CLASS_NAME_BACKDROP, 2846 isVisible, 2847 isAnimated: true, 2848 rootElement: this._element.parentNode, 2849 clickCallback: isVisible ? clickCallback : null 2850 }); 2851 } 2852 _initializeFocusTrap() { 2853 return new FocusTrap({ 2854 trapElement: this._element 2855 }); 2856 } 2857 _addEventListeners() { 2858 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => { 2859 if (event.key !== ESCAPE_KEY) { 2860 return; 2861 } 2862 if (this._config.keyboard) { 2863 this.hide(); 2864 return; 2865 } 2866 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); 2867 }); 2868 } 2869 2870 // Static 2871 static jQueryInterface(config) { 2872 return this.each(function () { 2873 const data = Offcanvas.getOrCreateInstance(this, config); 2874 if (typeof config !== 'string') { 2875 return; 2876 } 2877 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 2878 throw new TypeError(`No method named "${config}"`); 2879 } 2880 data[config](this); 2881 }); 2882 } 2883 } 2884 2885 /** 2886 * Data API implementation 2887 */ 2888 2889 EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) { 2890 const target = SelectorEngine.getElementFromSelector(this); 2891 if (['A', 'AREA'].includes(this.tagName)) { 2892 event.preventDefault(); 2893 } 2894 if (isDisabled(this)) { 2895 return; 2896 } 2897 EventHandler.one(target, EVENT_HIDDEN$3, () => { 2898 // focus on trigger when it is closed 2899 if (isVisible(this)) { 2900 this.focus(); 2901 } 2902 }); 2903 2904 // avoid conflict when clicking a toggler of an offcanvas, while another is open 2905 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR); 2906 if (alreadyOpen && alreadyOpen !== target) { 2907 Offcanvas.getInstance(alreadyOpen).hide(); 2908 } 2909 const data = Offcanvas.getOrCreateInstance(target); 2910 data.toggle(this); 2911 }); 2912 EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => { 2913 for (const selector of SelectorEngine.find(OPEN_SELECTOR)) { 2914 Offcanvas.getOrCreateInstance(selector).show(); 2915 } 2916 }); 2917 EventHandler.on(window, EVENT_RESIZE, () => { 2918 for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) { 2919 if (getComputedStyle(element).position !== 'fixed') { 2920 Offcanvas.getOrCreateInstance(element).hide(); 2921 } 2922 } 2923 }); 2924 enableDismissTrigger(Offcanvas); 2925 2926 /** 2927 * jQuery 2928 */ 2929 2930 defineJQueryPlugin(Offcanvas); 2931 2932 /** 2933 * -------------------------------------------------------------------------- 2934 * Bootstrap util/sanitizer.js 2935 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 2936 * -------------------------------------------------------------------------- 2937 */ 2938 2939 // js-docs-start allow-list 2940 const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; 2941 const DefaultAllowlist = { 2942 // Global attributes allowed on any supplied element below. 2943 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], 2944 a: ['target', 'href', 'title', 'rel'], 2945 area: [], 2946 b: [], 2947 br: [], 2948 col: [], 2949 code: [], 2950 dd: [], 2951 div: [], 2952 dl: [], 2953 dt: [], 2954 em: [], 2955 hr: [], 2956 h1: [], 2957 h2: [], 2958 h3: [], 2959 h4: [], 2960 h5: [], 2961 h6: [], 2962 i: [], 2963 img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], 2964 li: [], 2965 ol: [], 2966 p: [], 2967 pre: [], 2968 s: [], 2969 small: [], 2970 span: [], 2971 sub: [], 2972 sup: [], 2973 strong: [], 2974 u: [], 2975 ul: [] 2976 }; 2977 // js-docs-end allow-list 2978 2979 const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']); 2980 2981 /** 2982 * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation 2983 * contexts. 2984 * 2985 * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38 2986 */ 2987 const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i; 2988 const allowedAttribute = (attribute, allowedAttributeList) => { 2989 const attributeName = attribute.nodeName.toLowerCase(); 2990 if (allowedAttributeList.includes(attributeName)) { 2991 if (uriAttributes.has(attributeName)) { 2992 return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue)); 2993 } 2994 return true; 2995 } 2996 2997 // Check if a regular expression validates the attribute. 2998 return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName)); 2999 }; 3000 function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) { 3001 if (!unsafeHtml.length) { 3002 return unsafeHtml; 3003 } 3004 if (sanitizeFunction && typeof sanitizeFunction === 'function') { 3005 return sanitizeFunction(unsafeHtml); 3006 } 3007 const domParser = new window.DOMParser(); 3008 const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); 3009 const elements = [].concat(...createdDocument.body.querySelectorAll('*')); 3010 for (const element of elements) { 3011 const elementName = element.nodeName.toLowerCase(); 3012 if (!Object.keys(allowList).includes(elementName)) { 3013 element.remove(); 3014 continue; 3015 } 3016 const attributeList = [].concat(...element.attributes); 3017 const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []); 3018 for (const attribute of attributeList) { 3019 if (!allowedAttribute(attribute, allowedAttributes)) { 3020 element.removeAttribute(attribute.nodeName); 3021 } 3022 } 3023 } 3024 return createdDocument.body.innerHTML; 3025 } 3026 3027 /** 3028 * -------------------------------------------------------------------------- 3029 * Bootstrap util/template-factory.js 3030 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 3031 * -------------------------------------------------------------------------- 3032 */ 3033 3034 3035 /** 3036 * Constants 3037 */ 3038 3039 const NAME$5 = 'TemplateFactory'; 3040 const Default$4 = { 3041 allowList: DefaultAllowlist, 3042 content: {}, 3043 // { selector : text , selector2 : text2 , } 3044 extraClass: '', 3045 html: false, 3046 sanitize: true, 3047 sanitizeFn: null, 3048 template: '<div></div>' 3049 }; 3050 const DefaultType$4 = { 3051 allowList: 'object', 3052 content: 'object', 3053 extraClass: '(string|function)', 3054 html: 'boolean', 3055 sanitize: 'boolean', 3056 sanitizeFn: '(null|function)', 3057 template: 'string' 3058 }; 3059 const DefaultContentType = { 3060 entry: '(string|element|function|null)', 3061 selector: '(string|element)' 3062 }; 3063 3064 /** 3065 * Class definition 3066 */ 3067 3068 class TemplateFactory extends Config { 3069 constructor(config) { 3070 super(); 3071 this._config = this._getConfig(config); 3072 } 3073 3074 // Getters 3075 static get Default() { 3076 return Default$4; 3077 } 3078 static get DefaultType() { 3079 return DefaultType$4; 3080 } 3081 static get NAME() { 3082 return NAME$5; 3083 } 3084 3085 // Public 3086 getContent() { 3087 return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean); 3088 } 3089 hasContent() { 3090 return this.getContent().length > 0; 3091 } 3092 changeContent(content) { 3093 this._checkContent(content); 3094 this._config.content = { 3095 ...this._config.content, 3096 ...content 3097 }; 3098 return this; 3099 } 3100 toHtml() { 3101 const templateWrapper = document.createElement('div'); 3102 templateWrapper.innerHTML = this._maybeSanitize(this._config.template); 3103 for (const [selector, text] of Object.entries(this._config.content)) { 3104 this._setContent(templateWrapper, text, selector); 3105 } 3106 const template = templateWrapper.children[0]; 3107 const extraClass = this._resolvePossibleFunction(this._config.extraClass); 3108 if (extraClass) { 3109 template.classList.add(...extraClass.split(' ')); 3110 } 3111 return template; 3112 } 3113 3114 // Private 3115 _typeCheckConfig(config) { 3116 super._typeCheckConfig(config); 3117 this._checkContent(config.content); 3118 } 3119 _checkContent(arg) { 3120 for (const [selector, content] of Object.entries(arg)) { 3121 super._typeCheckConfig({ 3122 selector, 3123 entry: content 3124 }, DefaultContentType); 3125 } 3126 } 3127 _setContent(template, content, selector) { 3128 const templateElement = SelectorEngine.findOne(selector, template); 3129 if (!templateElement) { 3130 return; 3131 } 3132 content = this._resolvePossibleFunction(content); 3133 if (!content) { 3134 templateElement.remove(); 3135 return; 3136 } 3137 if (isElement(content)) { 3138 this._putElementInTemplate(getElement(content), templateElement); 3139 return; 3140 } 3141 if (this._config.html) { 3142 templateElement.innerHTML = this._maybeSanitize(content); 3143 return; 3144 } 3145 templateElement.textContent = content; 3146 } 3147 _maybeSanitize(arg) { 3148 return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg; 3149 } 3150 _resolvePossibleFunction(arg) { 3151 return execute(arg, [undefined, this]); 3152 } 3153 _putElementInTemplate(element, templateElement) { 3154 if (this._config.html) { 3155 templateElement.innerHTML = ''; 3156 templateElement.append(element); 3157 return; 3158 } 3159 templateElement.textContent = element.textContent; 3160 } 3161 } 3162 3163 /** 3164 * -------------------------------------------------------------------------- 3165 * Bootstrap tooltip.js 3166 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 3167 * -------------------------------------------------------------------------- 3168 */ 3169 3170 3171 /** 3172 * Constants 3173 */ 3174 3175 const NAME$4 = 'tooltip'; 3176 const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']); 3177 const CLASS_NAME_FADE$2 = 'fade'; 3178 const CLASS_NAME_MODAL = 'modal'; 3179 const CLASS_NAME_SHOW$2 = 'show'; 3180 const SELECTOR_TOOLTIP_INNER = '.tooltip-inner'; 3181 const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`; 3182 const EVENT_MODAL_HIDE = 'hide.bs.modal'; 3183 const TRIGGER_HOVER = 'hover'; 3184 const TRIGGER_FOCUS = 'focus'; 3185 const TRIGGER_CLICK = 'click'; 3186 const TRIGGER_MANUAL = 'manual'; 3187 const EVENT_HIDE$2 = 'hide'; 3188 const EVENT_HIDDEN$2 = 'hidden'; 3189 const EVENT_SHOW$2 = 'show'; 3190 const EVENT_SHOWN$2 = 'shown'; 3191 const EVENT_INSERTED = 'inserted'; 3192 const EVENT_CLICK$1 = 'click'; 3193 const EVENT_FOCUSIN$1 = 'focusin'; 3194 const EVENT_FOCUSOUT$1 = 'focusout'; 3195 const EVENT_MOUSEENTER = 'mouseenter'; 3196 const EVENT_MOUSELEAVE = 'mouseleave'; 3197 const AttachmentMap = { 3198 AUTO: 'auto', 3199 TOP: 'top', 3200 RIGHT: isRTL() ? 'left' : 'right', 3201 BOTTOM: 'bottom', 3202 LEFT: isRTL() ? 'right' : 'left' 3203 }; 3204 const Default$3 = { 3205 allowList: DefaultAllowlist, 3206 animation: true, 3207 boundary: 'clippingParents', 3208 container: false, 3209 customClass: '', 3210 delay: 0, 3211 fallbackPlacements: ['top', 'right', 'bottom', 'left'], 3212 html: false, 3213 offset: [0, 6], 3214 placement: 'top', 3215 popperConfig: null, 3216 sanitize: true, 3217 sanitizeFn: null, 3218 selector: false, 3219 template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>', 3220 title: '', 3221 trigger: 'hover focus' 3222 }; 3223 const DefaultType$3 = { 3224 allowList: 'object', 3225 animation: 'boolean', 3226 boundary: '(string|element)', 3227 container: '(string|element|boolean)', 3228 customClass: '(string|function)', 3229 delay: '(number|object)', 3230 fallbackPlacements: 'array', 3231 html: 'boolean', 3232 offset: '(array|string|function)', 3233 placement: '(string|function)', 3234 popperConfig: '(null|object|function)', 3235 sanitize: 'boolean', 3236 sanitizeFn: '(null|function)', 3237 selector: '(string|boolean)', 3238 template: 'string', 3239 title: '(string|element|function)', 3240 trigger: 'string' 3241 }; 3242 3243 /** 3244 * Class definition 3245 */ 3246 3247 class Tooltip extends BaseComponent { 3248 constructor(element, config) { 3249 if (typeof Popper__namespace === 'undefined') { 3250 throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org/docs/v2/)'); 3251 } 3252 super(element, config); 3253 3254 // Private 3255 this._isEnabled = true; 3256 this._timeout = 0; 3257 this._isHovered = null; 3258 this._activeTrigger = {}; 3259 this._popper = null; 3260 this._templateFactory = null; 3261 this._newContent = null; 3262 3263 // Protected 3264 this.tip = null; 3265 this._setListeners(); 3266 if (!this._config.selector) { 3267 this._fixTitle(); 3268 } 3269 } 3270 3271 // Getters 3272 static get Default() { 3273 return Default$3; 3274 } 3275 static get DefaultType() { 3276 return DefaultType$3; 3277 } 3278 static get NAME() { 3279 return NAME$4; 3280 } 3281 3282 // Public 3283 enable() { 3284 this._isEnabled = true; 3285 } 3286 disable() { 3287 this._isEnabled = false; 3288 } 3289 toggleEnabled() { 3290 this._isEnabled = !this._isEnabled; 3291 } 3292 toggle() { 3293 if (!this._isEnabled) { 3294 return; 3295 } 3296 if (this._isShown()) { 3297 this._leave(); 3298 return; 3299 } 3300 this._enter(); 3301 } 3302 dispose() { 3303 clearTimeout(this._timeout); 3304 EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); 3305 if (this._element.getAttribute('data-bs-original-title')) { 3306 this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title')); 3307 } 3308 this._disposePopper(); 3309 super.dispose(); 3310 } 3311 show() { 3312 if (this._element.style.display === 'none') { 3313 throw new Error('Please use show on visible elements'); 3314 } 3315 if (!(this._isWithContent() && this._isEnabled)) { 3316 return; 3317 } 3318 const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2)); 3319 const shadowRoot = findShadowRoot(this._element); 3320 const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element); 3321 if (showEvent.defaultPrevented || !isInTheDom) { 3322 return; 3323 } 3324 3325 // TODO: v6 remove this or make it optional 3326 this._disposePopper(); 3327 const tip = this._getTipElement(); 3328 this._element.setAttribute('aria-describedby', tip.getAttribute('id')); 3329 const { 3330 container 3331 } = this._config; 3332 if (!this._element.ownerDocument.documentElement.contains(this.tip)) { 3333 container.append(tip); 3334 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED)); 3335 } 3336 this._popper = this._createPopper(tip); 3337 tip.classList.add(CLASS_NAME_SHOW$2); 3338 3339 // If this is a touch-enabled device we add extra 3340 // empty mouseover listeners to the body's immediate children; 3341 // only needed because of broken event delegation on iOS 3342 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 3343 if ('ontouchstart' in document.documentElement) { 3344 for (const element of [].concat(...document.body.children)) { 3345 EventHandler.on(element, 'mouseover', noop); 3346 } 3347 } 3348 const complete = () => { 3349 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2)); 3350 if (this._isHovered === false) { 3351 this._leave(); 3352 } 3353 this._isHovered = false; 3354 }; 3355 this._queueCallback(complete, this.tip, this._isAnimated()); 3356 } 3357 hide() { 3358 if (!this._isShown()) { 3359 return; 3360 } 3361 const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2)); 3362 if (hideEvent.defaultPrevented) { 3363 return; 3364 } 3365 const tip = this._getTipElement(); 3366 tip.classList.remove(CLASS_NAME_SHOW$2); 3367 3368 // If this is a touch-enabled device we remove the extra 3369 // empty mouseover listeners we added for iOS support 3370 if ('ontouchstart' in document.documentElement) { 3371 for (const element of [].concat(...document.body.children)) { 3372 EventHandler.off(element, 'mouseover', noop); 3373 } 3374 } 3375 this._activeTrigger[TRIGGER_CLICK] = false; 3376 this._activeTrigger[TRIGGER_FOCUS] = false; 3377 this._activeTrigger[TRIGGER_HOVER] = false; 3378 this._isHovered = null; // it is a trick to support manual triggering 3379 3380 const complete = () => { 3381 if (this._isWithActiveTrigger()) { 3382 return; 3383 } 3384 if (!this._isHovered) { 3385 this._disposePopper(); 3386 } 3387 this._element.removeAttribute('aria-describedby'); 3388 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2)); 3389 }; 3390 this._queueCallback(complete, this.tip, this._isAnimated()); 3391 } 3392 update() { 3393 if (this._popper) { 3394 this._popper.update(); 3395 } 3396 } 3397 3398 // Protected 3399 _isWithContent() { 3400 return Boolean(this._getTitle()); 3401 } 3402 _getTipElement() { 3403 if (!this.tip) { 3404 this.tip = this._createTipElement(this._newContent || this._getContentForTemplate()); 3405 } 3406 return this.tip; 3407 } 3408 _createTipElement(content) { 3409 const tip = this._getTemplateFactory(content).toHtml(); 3410 3411 // TODO: remove this check in v6 3412 if (!tip) { 3413 return null; 3414 } 3415 tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2); 3416 // TODO: v6 the following can be achieved with CSS only 3417 tip.classList.add(`bs-${this.constructor.NAME}-auto`); 3418 const tipId = getUID(this.constructor.NAME).toString(); 3419 tip.setAttribute('id', tipId); 3420 if (this._isAnimated()) { 3421 tip.classList.add(CLASS_NAME_FADE$2); 3422 } 3423 return tip; 3424 } 3425 setContent(content) { 3426 this._newContent = content; 3427 if (this._isShown()) { 3428 this._disposePopper(); 3429 this.show(); 3430 } 3431 } 3432 _getTemplateFactory(content) { 3433 if (this._templateFactory) { 3434 this._templateFactory.changeContent(content); 3435 } else { 3436 this._templateFactory = new TemplateFactory({ 3437 ...this._config, 3438 // the `content` var has to be after `this._config` 3439 // to override config.content in case of popover 3440 content, 3441 extraClass: this._resolvePossibleFunction(this._config.customClass) 3442 }); 3443 } 3444 return this._templateFactory; 3445 } 3446 _getContentForTemplate() { 3447 return { 3448 [SELECTOR_TOOLTIP_INNER]: this._getTitle() 3449 }; 3450 } 3451 _getTitle() { 3452 return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title'); 3453 } 3454 3455 // Private 3456 _initializeOnDelegatedTarget(event) { 3457 return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig()); 3458 } 3459 _isAnimated() { 3460 return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2); 3461 } 3462 _isShown() { 3463 return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2); 3464 } 3465 _createPopper(tip) { 3466 const placement = execute(this._config.placement, [this, tip, this._element]);
vendor: 5,002 bytes, lines 3467-3597
3467 const attachment = AttachmentMap[placement.toUpperCase()]; 3468 return Popper__namespace.createPopper(this._element, tip, this._getPopperConfig(attachment)); 3469 } 3470 _getOffset() { 3471 const { 3472 offset 3473 } = this._config; 3474 if (typeof offset === 'string') { 3475 return offset.split(',').map(value => Number.parseInt(value, 10)); 3476 } 3477 if (typeof offset === 'function') { 3478 return popperData => offset(popperData, this._element); 3479 } 3480 return offset; 3481 } 3482 _resolvePossibleFunction(arg) { 3483 return execute(arg, [this._element, this._element]); 3484 } 3485 _getPopperConfig(attachment) { 3486 const defaultBsPopperConfig = { 3487 placement: attachment, 3488 modifiers: [{ 3489 name: 'flip', 3490 options: { 3491 fallbackPlacements: this._config.fallbackPlacements 3492 } 3493 }, { 3494 name: 'offset', 3495 options: { 3496 offset: this._getOffset() 3497 } 3498 }, { 3499 name: 'preventOverflow', 3500 options: { 3501 boundary: this._config.boundary 3502 } 3503 }, { 3504 name: 'arrow', 3505 options: { 3506 element: `.${this.constructor.NAME}-arrow` 3507 } 3508 }, { 3509 name: 'preSetPlacement', 3510 enabled: true, 3511 phase: 'beforeMain', 3512 fn: data => { 3513 // Pre-set Popper's placement attribute in order to read the arrow sizes properly. 3514 // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement 3515 this._getTipElement().setAttribute('data-popper-placement', data.state.placement); 3516 } 3517 }] 3518 }; 3519 return { 3520 ...defaultBsPopperConfig, 3521 ...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig]) 3522 }; 3523 } 3524 _setListeners() { 3525 const triggers = this._config.trigger.split(' '); 3526 for (const trigger of triggers) { 3527 if (trigger === 'click') { 3528 EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => { 3529 const context = this._initializeOnDelegatedTarget(event); 3530 context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK]); 3531 context.toggle(); 3532 }); 3533 } else if (trigger !== TRIGGER_MANUAL) { 3534 const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1); 3535 const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1); 3536 EventHandler.on(this._element, eventIn, this._config.selector, event => { 3537 const context = this._initializeOnDelegatedTarget(event); 3538 context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; 3539 context._enter(); 3540 }); 3541 EventHandler.on(this._element, eventOut, this._config.selector, event => { 3542 const context = this._initializeOnDelegatedTarget(event); 3543 context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget); 3544 context._leave(); 3545 }); 3546 } 3547 } 3548 this._hideModalHandler = () => { 3549 if (this._element) { 3550 this.hide(); 3551 } 3552 }; 3553 EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); 3554 } 3555 _fixTitle() { 3556 const title = this._element.getAttribute('title'); 3557 if (!title) { 3558 return; 3559 } 3560 if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) { 3561 this._element.setAttribute('aria-label', title); 3562 } 3563 this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility 3564 this._element.removeAttribute('title'); 3565 } 3566 _enter() { 3567 if (this._isShown() || this._isHovered) { 3568 this._isHovered = true; 3569 return; 3570 } 3571 this._isHovered = true; 3572 this._setTimeout(() => { 3573 if (this._isHovered) { 3574 this.show(); 3575 } 3576 }, this._config.delay.show); 3577 } 3578 _leave() { 3579 if (this._isWithActiveTrigger()) { 3580 return; 3581 } 3582 this._isHovered = false; 3583 this._setTimeout(() => { 3584 if (!this._isHovered) { 3585 this.hide(); 3586 } 3587 }, this._config.delay.hide); 3588 } 3589 _setTimeout(handler, timeout) { 3590 clearTimeout(this._timeout); 3591 this._timeout = setTimeout(handler, timeout); 3592 } 3593 _isWithActiveTrigger() { 3594 return Object.values(this._activeTrigger).includes(true); 3595 } 3596 _getConfig(config) { 3597 const dataAttributes = Manipulator.getDataAttributes(this._element);
vendor: 28,140 bytes, lines 3598-4448
3598 for (const dataAttribute of Object.keys(dataAttributes)) { 3599 if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) { 3600 delete dataAttributes[dataAttribute]; 3601 } 3602 } 3603 config = { 3604 ...dataAttributes, 3605 ...(typeof config === 'object' && config ? config : {}) 3606 }; 3607 config = this._mergeConfigObj(config); 3608 config = this._configAfterMerge(config); 3609 this._typeCheckConfig(config); 3610 return config; 3611 } 3612 _configAfterMerge(config) { 3613 config.container = config.container === false ? document.body : getElement(config.container); 3614 if (typeof config.delay === 'number') { 3615 config.delay = { 3616 show: config.delay, 3617 hide: config.delay 3618 }; 3619 } 3620 if (typeof config.title === 'number') { 3621 config.title = config.title.toString(); 3622 } 3623 if (typeof config.content === 'number') { 3624 config.content = config.content.toString(); 3625 } 3626 return config; 3627 } 3628 _getDelegateConfig() { 3629 const config = {}; 3630 for (const [key, value] of Object.entries(this._config)) { 3631 if (this.constructor.Default[key] !== value) { 3632 config[key] = value; 3633 } 3634 } 3635 config.selector = false; 3636 config.trigger = 'manual'; 3637 3638 // In the future can be replaced with: 3639 // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]]) 3640 // `Object.fromEntries(keysWithDifferentValues)` 3641 return config; 3642 } 3643 _disposePopper() { 3644 if (this._popper) { 3645 this._popper.destroy(); 3646 this._popper = null; 3647 } 3648 if (this.tip) { 3649 this.tip.remove(); 3650 this.tip = null; 3651 } 3652 } 3653 3654 // Static 3655 static jQueryInterface(config) { 3656 return this.each(function () { 3657 const data = Tooltip.getOrCreateInstance(this, config); 3658 if (typeof config !== 'string') { 3659 return; 3660 } 3661 if (typeof data[config] === 'undefined') { 3662 throw new TypeError(`No method named "${config}"`); 3663 } 3664 data[config](); 3665 }); 3666 } 3667 } 3668 3669 /** 3670 * jQuery 3671 */ 3672 3673 defineJQueryPlugin(Tooltip); 3674 3675 /** 3676 * -------------------------------------------------------------------------- 3677 * Bootstrap popover.js 3678 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 3679 * -------------------------------------------------------------------------- 3680 */ 3681 3682 3683 /** 3684 * Constants 3685 */ 3686 3687 const NAME$3 = 'popover'; 3688 const SELECTOR_TITLE = '.popover-header'; 3689 const SELECTOR_CONTENT = '.popover-body'; 3690 const Default$2 = { 3691 ...Tooltip.Default, 3692 content: '', 3693 offset: [0, 8], 3694 placement: 'right', 3695 template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div>' + '</div>', 3696 trigger: 'click' 3697 }; 3698 const DefaultType$2 = { 3699 ...Tooltip.DefaultType, 3700 content: '(null|string|element|function)' 3701 }; 3702 3703 /** 3704 * Class definition 3705 */ 3706 3707 class Popover extends Tooltip { 3708 // Getters 3709 static get Default() { 3710 return Default$2; 3711 } 3712 static get DefaultType() { 3713 return DefaultType$2; 3714 } 3715 static get NAME() { 3716 return NAME$3; 3717 } 3718 3719 // Overrides 3720 _isWithContent() { 3721 return this._getTitle() || this._getContent(); 3722 } 3723 3724 // Private 3725 _getContentForTemplate() { 3726 return { 3727 [SELECTOR_TITLE]: this._getTitle(), 3728 [SELECTOR_CONTENT]: this._getContent() 3729 }; 3730 } 3731 _getContent() { 3732 return this._resolvePossibleFunction(this._config.content); 3733 } 3734 3735 // Static 3736 static jQueryInterface(config) { 3737 return this.each(function () { 3738 const data = Popover.getOrCreateInstance(this, config); 3739 if (typeof config !== 'string') { 3740 return; 3741 } 3742 if (typeof data[config] === 'undefined') { 3743 throw new TypeError(`No method named "${config}"`); 3744 } 3745 data[config](); 3746 }); 3747 } 3748 } 3749 3750 /** 3751 * jQuery 3752 */ 3753 3754 defineJQueryPlugin(Popover); 3755 3756 /** 3757 * -------------------------------------------------------------------------- 3758 * Bootstrap scrollspy.js 3759 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 3760 * -------------------------------------------------------------------------- 3761 */ 3762 3763 3764 /** 3765 * Constants 3766 */ 3767 3768 const NAME$2 = 'scrollspy'; 3769 const DATA_KEY$2 = 'bs.scrollspy'; 3770 const EVENT_KEY$2 = `.${DATA_KEY$2}`; 3771 const DATA_API_KEY = '.data-api'; 3772 const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`; 3773 const EVENT_CLICK = `click${EVENT_KEY$2}`; 3774 const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`; 3775 const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'; 3776 const CLASS_NAME_ACTIVE$1 = 'active'; 3777 const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]'; 3778 const SELECTOR_TARGET_LINKS = '[href]'; 3779 const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'; 3780 const SELECTOR_NAV_LINKS = '.nav-link'; 3781 const SELECTOR_NAV_ITEMS = '.nav-item'; 3782 const SELECTOR_LIST_ITEMS = '.list-group-item'; 3783 const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`; 3784 const SELECTOR_DROPDOWN = '.dropdown'; 3785 const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle'; 3786 const Default$1 = { 3787 offset: null, 3788 // TODO: v6 @deprecated, keep it for backwards compatibility reasons 3789 rootMargin: '0px 0px -25%', 3790 smoothScroll: false, 3791 target: null, 3792 threshold: [0.1, 0.5, 1] 3793 }; 3794 const DefaultType$1 = { 3795 offset: '(number|null)', 3796 // TODO v6 @deprecated, keep it for backwards compatibility reasons 3797 rootMargin: 'string', 3798 smoothScroll: 'boolean', 3799 target: 'element', 3800 threshold: 'array' 3801 }; 3802 3803 /** 3804 * Class definition 3805 */ 3806 3807 class ScrollSpy extends BaseComponent { 3808 constructor(element, config) { 3809 super(element, config); 3810 3811 // this._element is the observablesContainer and config.target the menu links wrapper 3812 this._targetLinks = new Map(); 3813 this._observableSections = new Map(); 3814 this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element; 3815 this._activeTarget = null; 3816 this._observer = null; 3817 this._previousScrollData = { 3818 visibleEntryTop: 0, 3819 parentScrollTop: 0 3820 }; 3821 this.refresh(); // initialize 3822 } 3823 3824 // Getters 3825 static get Default() { 3826 return Default$1; 3827 } 3828 static get DefaultType() { 3829 return DefaultType$1; 3830 } 3831 static get NAME() { 3832 return NAME$2; 3833 } 3834 3835 // Public 3836 refresh() { 3837 this._initializeTargetsAndObservables(); 3838 this._maybeEnableSmoothScroll(); 3839 if (this._observer) { 3840 this._observer.disconnect(); 3841 } else { 3842 this._observer = this._getNewObserver(); 3843 } 3844 for (const section of this._observableSections.values()) { 3845 this._observer.observe(section); 3846 } 3847 } 3848 dispose() { 3849 this._observer.disconnect(); 3850 super.dispose(); 3851 } 3852 3853 // Private 3854 _configAfterMerge(config) { 3855 // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case 3856 config.target = getElement(config.target) || document.body; 3857 3858 // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only 3859 config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin; 3860 if (typeof config.threshold === 'string') { 3861 config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value)); 3862 } 3863 return config; 3864 } 3865 _maybeEnableSmoothScroll() { 3866 if (!this._config.smoothScroll) { 3867 return; 3868 } 3869 3870 // unregister any previous listeners 3871 EventHandler.off(this._config.target, EVENT_CLICK); 3872 EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => { 3873 const observableSection = this._observableSections.get(event.target.hash); 3874 if (observableSection) { 3875 event.preventDefault(); 3876 const root = this._rootElement || window; 3877 const height = observableSection.offsetTop - this._element.offsetTop; 3878 if (root.scrollTo) { 3879 root.scrollTo({ 3880 top: height, 3881 behavior: 'smooth' 3882 }); 3883 return; 3884 } 3885 3886 // Chrome 60 doesn't support `scrollTo` 3887 root.scrollTop = height; 3888 } 3889 }); 3890 } 3891 _getNewObserver() { 3892 const options = { 3893 root: this._rootElement, 3894 threshold: this._config.threshold, 3895 rootMargin: this._config.rootMargin 3896 }; 3897 return new IntersectionObserver(entries => this._observerCallback(entries), options); 3898 } 3899 3900 // The logic of selection 3901 _observerCallback(entries) { 3902 const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`); 3903 const activate = entry => { 3904 this._previousScrollData.visibleEntryTop = entry.target.offsetTop; 3905 this._process(targetElement(entry)); 3906 }; 3907 const parentScrollTop = (this._rootElement || document.documentElement).scrollTop; 3908 const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop; 3909 this._previousScrollData.parentScrollTop = parentScrollTop; 3910 for (const entry of entries) { 3911 if (!entry.isIntersecting) { 3912 this._activeTarget = null; 3913 this._clearActiveClass(targetElement(entry)); 3914 continue; 3915 } 3916 const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; 3917 // if we are scrolling down, pick the bigger offsetTop 3918 if (userScrollsDown && entryIsLowerThanPrevious) { 3919 activate(entry); 3920 // if parent isn't scrolled, let's keep the first visible item, breaking the iteration 3921 if (!parentScrollTop) { 3922 return; 3923 } 3924 continue; 3925 } 3926 3927 // if we are scrolling up, pick the smallest offsetTop 3928 if (!userScrollsDown && !entryIsLowerThanPrevious) { 3929 activate(entry); 3930 } 3931 } 3932 } 3933 _initializeTargetsAndObservables() { 3934 this._targetLinks = new Map(); 3935 this._observableSections = new Map(); 3936 const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target); 3937 for (const anchor of targetLinks) { 3938 // ensure that the anchor has an id and is not disabled 3939 if (!anchor.hash || isDisabled(anchor)) { 3940 continue; 3941 } 3942 const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element); 3943 3944 // ensure that the observableSection exists & is visible 3945 if (isVisible(observableSection)) { 3946 this._targetLinks.set(decodeURI(anchor.hash), anchor); 3947 this._observableSections.set(anchor.hash, observableSection); 3948 } 3949 } 3950 } 3951 _process(target) { 3952 if (this._activeTarget === target) { 3953 return; 3954 } 3955 this._clearActiveClass(this._config.target); 3956 this._activeTarget = target; 3957 target.classList.add(CLASS_NAME_ACTIVE$1); 3958 this._activateParents(target); 3959 EventHandler.trigger(this._element, EVENT_ACTIVATE, { 3960 relatedTarget: target 3961 }); 3962 } 3963 _activateParents(target) { 3964 // Activate dropdown parents 3965 if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) { 3966 SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1); 3967 return; 3968 } 3969 for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) { 3970 // Set triggered links parents as active 3971 // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor 3972 for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) { 3973 item.classList.add(CLASS_NAME_ACTIVE$1); 3974 } 3975 } 3976 } 3977 _clearActiveClass(parent) { 3978 parent.classList.remove(CLASS_NAME_ACTIVE$1); 3979 const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE$1}`, parent); 3980 for (const node of activeNodes) { 3981 node.classList.remove(CLASS_NAME_ACTIVE$1); 3982 } 3983 } 3984 3985 // Static 3986 static jQueryInterface(config) { 3987 return this.each(function () { 3988 const data = ScrollSpy.getOrCreateInstance(this, config); 3989 if (typeof config !== 'string') { 3990 return; 3991 } 3992 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 3993 throw new TypeError(`No method named "${config}"`); 3994 } 3995 data[config](); 3996 }); 3997 } 3998 } 3999 4000 /** 4001 * Data API implementation 4002 */ 4003 4004 EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => { 4005 for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) { 4006 ScrollSpy.getOrCreateInstance(spy); 4007 } 4008 }); 4009 4010 /** 4011 * jQuery 4012 */ 4013 4014 defineJQueryPlugin(ScrollSpy); 4015 4016 /** 4017 * -------------------------------------------------------------------------- 4018 * Bootstrap tab.js 4019 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4020 * -------------------------------------------------------------------------- 4021 */ 4022 4023 4024 /** 4025 * Constants 4026 */ 4027 4028 const NAME$1 = 'tab'; 4029 const DATA_KEY$1 = 'bs.tab'; 4030 const EVENT_KEY$1 = `.${DATA_KEY$1}`; 4031 const EVENT_HIDE$1 = `hide${EVENT_KEY$1}`; 4032 const EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`; 4033 const EVENT_SHOW$1 = `show${EVENT_KEY$1}`; 4034 const EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`; 4035 const EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}`; 4036 const EVENT_KEYDOWN = `keydown${EVENT_KEY$1}`; 4037 const EVENT_LOAD_DATA_API = `load${EVENT_KEY$1}`; 4038 const ARROW_LEFT_KEY = 'ArrowLeft'; 4039 const ARROW_RIGHT_KEY = 'ArrowRight'; 4040 const ARROW_UP_KEY = 'ArrowUp'; 4041 const ARROW_DOWN_KEY = 'ArrowDown'; 4042 const HOME_KEY = 'Home'; 4043 const END_KEY = 'End'; 4044 const CLASS_NAME_ACTIVE = 'active'; 4045 const CLASS_NAME_FADE$1 = 'fade'; 4046 const CLASS_NAME_SHOW$1 = 'show'; 4047 const CLASS_DROPDOWN = 'dropdown'; 4048 const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'; 4049 const SELECTOR_DROPDOWN_MENU = '.dropdown-menu'; 4050 const NOT_SELECTOR_DROPDOWN_TOGGLE = `:not(${SELECTOR_DROPDOWN_TOGGLE})`; 4051 const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]'; 4052 const SELECTOR_OUTER = '.nav-item, .list-group-item'; 4053 const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`; 4054 const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // TODO: could only be `tab` in v6 4055 const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`; 4056 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"]`; 4057 4058 /** 4059 * Class definition 4060 */ 4061 4062 class Tab extends BaseComponent { 4063 constructor(element) { 4064 super(element); 4065 this._parent = this._element.closest(SELECTOR_TAB_PANEL); 4066 if (!this._parent) { 4067 return; 4068 // TODO: should throw exception in v6 4069 // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`) 4070 } 4071 4072 // Set up initial aria attributes 4073 this._setInitialAttributes(this._parent, this._getChildren()); 4074 EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event)); 4075 } 4076 4077 // Getters 4078 static get NAME() { 4079 return NAME$1; 4080 } 4081 4082 // Public 4083 show() { 4084 // Shows this elem and deactivate the active sibling if exists 4085 const innerElem = this._element; 4086 if (this._elemIsActive(innerElem)) { 4087 return; 4088 } 4089 4090 // Search for active tab on same parent to deactivate it 4091 const active = this._getActiveElem(); 4092 const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE$1, { 4093 relatedTarget: innerElem 4094 }) : null; 4095 const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW$1, { 4096 relatedTarget: active 4097 }); 4098 if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) { 4099 return; 4100 } 4101 this._deactivate(active, innerElem); 4102 this._activate(innerElem, active); 4103 } 4104 4105 // Private 4106 _activate(element, relatedElem) { 4107 if (!element) { 4108 return; 4109 } 4110 element.classList.add(CLASS_NAME_ACTIVE); 4111 this._activate(SelectorEngine.getElementFromSelector(element)); // Search and activate/show the proper section 4112 4113 const complete = () => { 4114 if (element.getAttribute('role') !== 'tab') { 4115 element.classList.add(CLASS_NAME_SHOW$1); 4116 return; 4117 } 4118 element.removeAttribute('tabindex'); 4119 element.setAttribute('aria-selected', true); 4120 this._toggleDropDown(element, true); 4121 EventHandler.trigger(element, EVENT_SHOWN$1, { 4122 relatedTarget: relatedElem 4123 }); 4124 }; 4125 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1)); 4126 } 4127 _deactivate(element, relatedElem) { 4128 if (!element) { 4129 return; 4130 } 4131 element.classList.remove(CLASS_NAME_ACTIVE); 4132 element.blur(); 4133 this._deactivate(SelectorEngine.getElementFromSelector(element)); // Search and deactivate the shown section too 4134 4135 const complete = () => { 4136 if (element.getAttribute('role') !== 'tab') { 4137 element.classList.remove(CLASS_NAME_SHOW$1); 4138 return; 4139 } 4140 element.setAttribute('aria-selected', false); 4141 element.setAttribute('tabindex', '-1'); 4142 this._toggleDropDown(element, false); 4143 EventHandler.trigger(element, EVENT_HIDDEN$1, { 4144 relatedTarget: relatedElem 4145 }); 4146 }; 4147 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1)); 4148 } 4149 _keydown(event) { 4150 if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) { 4151 return; 4152 } 4153 event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page 4154 event.preventDefault(); 4155 const children = this._getChildren().filter(element => !isDisabled(element)); 4156 let nextActiveElement; 4157 if ([HOME_KEY, END_KEY].includes(event.key)) { 4158 nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1]; 4159 } else { 4160 const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key); 4161 nextActiveElement = getNextActiveElement(children, event.target, isNext, true); 4162 } 4163 if (nextActiveElement) { 4164 nextActiveElement.focus({ 4165 preventScroll: true 4166 }); 4167 Tab.getOrCreateInstance(nextActiveElement).show(); 4168 } 4169 } 4170 _getChildren() { 4171 // collection of inner elements 4172 return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent); 4173 } 4174 _getActiveElem() { 4175 return this._getChildren().find(child => this._elemIsActive(child)) || null; 4176 } 4177 _setInitialAttributes(parent, children) { 4178 this._setAttributeIfNotExists(parent, 'role', 'tablist'); 4179 for (const child of children) { 4180 this._setInitialAttributesOnChild(child); 4181 } 4182 } 4183 _setInitialAttributesOnChild(child) { 4184 child = this._getInnerElement(child); 4185 const isActive = this._elemIsActive(child); 4186 const outerElem = this._getOuterElement(child); 4187 child.setAttribute('aria-selected', isActive); 4188 if (outerElem !== child) { 4189 this._setAttributeIfNotExists(outerElem, 'role', 'presentation'); 4190 } 4191 if (!isActive) { 4192 child.setAttribute('tabindex', '-1'); 4193 } 4194 this._setAttributeIfNotExists(child, 'role', 'tab'); 4195 4196 // set attributes to the related panel too 4197 this._setInitialAttributesOnTargetPanel(child); 4198 } 4199 _setInitialAttributesOnTargetPanel(child) { 4200 const target = SelectorEngine.getElementFromSelector(child); 4201 if (!target) { 4202 return; 4203 } 4204 this._setAttributeIfNotExists(target, 'role', 'tabpanel'); 4205 if (child.id) { 4206 this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`); 4207 } 4208 } 4209 _toggleDropDown(element, open) { 4210 const outerElem = this._getOuterElement(element); 4211 if (!outerElem.classList.contains(CLASS_DROPDOWN)) { 4212 return; 4213 } 4214 const toggle = (selector, className) => { 4215 const element = SelectorEngine.findOne(selector, outerElem); 4216 if (element) { 4217 element.classList.toggle(className, open); 4218 } 4219 }; 4220 toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE); 4221 toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW$1); 4222 outerElem.setAttribute('aria-expanded', open); 4223 } 4224 _setAttributeIfNotExists(element, attribute, value) { 4225 if (!element.hasAttribute(attribute)) { 4226 element.setAttribute(attribute, value); 4227 } 4228 } 4229 _elemIsActive(elem) { 4230 return elem.classList.contains(CLASS_NAME_ACTIVE); 4231 } 4232 4233 // Try to get the inner element (usually the .nav-link) 4234 _getInnerElement(elem) { 4235 return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem); 4236 } 4237 4238 // Try to get the outer element (usually the .nav-item) 4239 _getOuterElement(elem) { 4240 return elem.closest(SELECTOR_OUTER) || elem; 4241 } 4242 4243 // Static 4244 static jQueryInterface(config) { 4245 return this.each(function () { 4246 const data = Tab.getOrCreateInstance(this); 4247 if (typeof config !== 'string') { 4248 return; 4249 } 4250 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 4251 throw new TypeError(`No method named "${config}"`); 4252 } 4253 data[config](); 4254 }); 4255 } 4256 } 4257 4258 /** 4259 * Data API implementation 4260 */ 4261 4262 EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { 4263 if (['A', 'AREA'].includes(this.tagName)) { 4264 event.preventDefault(); 4265 } 4266 if (isDisabled(this)) { 4267 return; 4268 } 4269 Tab.getOrCreateInstance(this).show(); 4270 }); 4271 4272 /** 4273 * Initialize on focus 4274 */ 4275 EventHandler.on(window, EVENT_LOAD_DATA_API, () => { 4276 for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) { 4277 Tab.getOrCreateInstance(element); 4278 } 4279 }); 4280 /** 4281 * jQuery 4282 */ 4283 4284 defineJQueryPlugin(Tab); 4285 4286 /** 4287 * -------------------------------------------------------------------------- 4288 * Bootstrap toast.js 4289 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4290 * -------------------------------------------------------------------------- 4291 */ 4292 4293 4294 /** 4295 * Constants 4296 */ 4297 4298 const NAME = 'toast'; 4299 const DATA_KEY = 'bs.toast'; 4300 const EVENT_KEY = `.${DATA_KEY}`; 4301 const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`; 4302 const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`; 4303 const EVENT_FOCUSIN = `focusin${EVENT_KEY}`; 4304 const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`; 4305 const EVENT_HIDE = `hide${EVENT_KEY}`; 4306 const EVENT_HIDDEN = `hidden${EVENT_KEY}`; 4307 const EVENT_SHOW = `show${EVENT_KEY}`; 4308 const EVENT_SHOWN = `shown${EVENT_KEY}`; 4309 const CLASS_NAME_FADE = 'fade'; 4310 const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility 4311 const CLASS_NAME_SHOW = 'show'; 4312 const CLASS_NAME_SHOWING = 'showing'; 4313 const DefaultType = { 4314 animation: 'boolean', 4315 autohide: 'boolean', 4316 delay: 'number' 4317 }; 4318 const Default = { 4319 animation: true, 4320 autohide: true, 4321 delay: 5000 4322 }; 4323 4324 /** 4325 * Class definition 4326 */ 4327 4328 class Toast extends BaseComponent { 4329 constructor(element, config) { 4330 super(element, config); 4331 this._timeout = null; 4332 this._hasMouseInteraction = false; 4333 this._hasKeyboardInteraction = false; 4334 this._setListeners(); 4335 } 4336 4337 // Getters 4338 static get Default() { 4339 return Default; 4340 } 4341 static get DefaultType() { 4342 return DefaultType; 4343 } 4344 static get NAME() { 4345 return NAME; 4346 } 4347 4348 // Public 4349 show() { 4350 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW); 4351 if (showEvent.defaultPrevented) { 4352 return; 4353 } 4354 this._clearTimeout(); 4355 if (this._config.animation) { 4356 this._element.classList.add(CLASS_NAME_FADE); 4357 } 4358 const complete = () => { 4359 this._element.classList.remove(CLASS_NAME_SHOWING); 4360 EventHandler.trigger(this._element, EVENT_SHOWN); 4361 this._maybeScheduleHide(); 4362 }; 4363 this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated 4364 reflow(this._element); 4365 this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING); 4366 this._queueCallback(complete, this._element, this._config.animation); 4367 } 4368 hide() { 4369 if (!this.isShown()) { 4370 return; 4371 } 4372 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE); 4373 if (hideEvent.defaultPrevented) { 4374 return; 4375 } 4376 const complete = () => { 4377 this._element.classList.add(CLASS_NAME_HIDE); // @deprecated 4378 this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW); 4379 EventHandler.trigger(this._element, EVENT_HIDDEN); 4380 }; 4381 this._element.classList.add(CLASS_NAME_SHOWING); 4382 this._queueCallback(complete, this._element, this._config.animation); 4383 } 4384 dispose() { 4385 this._clearTimeout(); 4386 if (this.isShown()) { 4387 this._element.classList.remove(CLASS_NAME_SHOW); 4388 } 4389 super.dispose(); 4390 } 4391 isShown() { 4392 return this._element.classList.contains(CLASS_NAME_SHOW); 4393 } 4394 4395 // Private 4396 _maybeScheduleHide() { 4397 if (!this._config.autohide) { 4398 return; 4399 } 4400 if (this._hasMouseInteraction || this._hasKeyboardInteraction) { 4401 return; 4402 } 4403 this._timeout = setTimeout(() => { 4404 this.hide(); 4405 }, this._config.delay); 4406 } 4407 _onInteraction(event, isInteracting) { 4408 switch (event.type) { 4409 case 'mouseover': 4410 case 'mouseout': 4411 { 4412 this._hasMouseInteraction = isInteracting; 4413 break; 4414 } 4415 case 'focusin': 4416 case 'focusout': 4417 { 4418 this._hasKeyboardInteraction = isInteracting; 4419 break; 4420 } 4421 } 4422 if (isInteracting) { 4423 this._clearTimeout(); 4424 return; 4425 } 4426 const nextElement = event.relatedTarget; 4427 if (this._element === nextElement || this._element.contains(nextElement)) { 4428 return; 4429 } 4430 this._maybeScheduleHide(); 4431 } 4432 _setListeners() { 4433 EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true)); 4434 EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false)); 4435 EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true)); 4436 EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false)); 4437 } 4438 _clearTimeout() { 4439 clearTimeout(this._timeout); 4440 this._timeout = null; 4441 } 4442 4443 // Static 4444 static jQueryInterface(config) { 4445 return this.each(function () { 4446 const data = Toast.getOrCreateInstance(this, config); 4447 if (typeof config === 'string') { 4448 if (typeof data[config] === 'undefined') {
4449 throw new TypeError(`No method named "${config}"`); 4450 } 4451 data[config](this); 4452 } 4453 }); 4454 } 4455 } 4456 4457 /** 4458 * Data API implementation 4459 */ 4460 4461 enableDismissTrigger(Toast); 4462 4463 /** 4464 * jQuery 4465 */ 4466 4467 defineJQueryPlugin(Toast); 4468 4469 /** 4470 * -------------------------------------------------------------------------- 4471 * Bootstrap index.umd.js 4472 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4473 * -------------------------------------------------------------------------- 4474 */ 4475 4476 const index_umd = { 4477 Alert, 4478 Button, 4479 Carousel, 4480 Collapse, 4481 Dropdown, 4482 Modal, 4483 Offcanvas, 4484 Popover, 4485 ScrollSpy, 4486 Tab, 4487 Toast, 4488 Tooltip 4489 }; 4490 4491 return index_umd; 4492 4493})); 4494//# sourceMappingURL=bootstrap.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.