2 * Bootstrap v5.3.2 (https://getbootstrap.com/)
3 * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
6 (function (global
, factory
) {
7 typeof exports
=== 'object' && typeof module
!== 'undefined' ? module
.exports
= factory() :
8 typeof define
=== 'function' && define
.amd
? define(factory
) :
9 (global
= typeof globalThis
!== 'undefined' ? globalThis : global
|| self
, global
.bootstrap
= factory());
10 })(this, (function () { 'use strict';
13 * --------------------------------------------------------------------------
14 * Bootstrap dom/data.js
15 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
16 * --------------------------------------------------------------------------
23 const elementMap
= new Map();
25 set(element
, key
, instance
) {
26 if (!elementMap
.has(element
)) {
27 elementMap
.set(element
, new Map());
29 const instanceMap
= elementMap
.get(element
);
31 // make it clear we only want one instance per element
32 // can be removed later when multiple key/instances are fine to be used
33 if (!instanceMap
.has(key
) && instanceMap
.size
!== 0) {
34 // eslint-disable-next-line no-console
35 console
.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);
38 instanceMap
.set(key
, instance
);
41 if (elementMap
.has(element
)) {
42 return elementMap
.get(element
).get(key
) || null;
46 remove(element
, key
) {
47 if (!elementMap
.has(element
)) {
50 const instanceMap
= elementMap
.get(element
);
51 instanceMap
.delete(key
);
53 // free up element references if there are no instances left for an element
54 if (instanceMap
.size
=== 0) {
55 elementMap
.delete(element
);
61 * --------------------------------------------------------------------------
62 * Bootstrap util/index.js
63 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
64 * --------------------------------------------------------------------------
67 const MAX_UID
= 1000000;
68 const MILLISECONDS_MULTIPLIER
= 1000;
69 const TRANSITION_END
= 'transitionend';
72 * Properly escape IDs selectors to handle weird IDs
73 * @param {string} selector
76 const parseSelector
= selector
=> {
77 if (selector
&& window
.CSS
&& window
.CSS
.escape
) {
78 // document.querySelector needs escaping to handle IDs (html5+) containing for instance /
79 selector
= selector
.replace(/#([^\s"#']+)/g, (match
, id
) => `#${CSS.escape(id)}`);
84 // Shout-out Angus Croll (https://goo.gl/pxwQGp)
85 const toType
= object
=> {
86 if (object
=== null || object
=== undefined) {
89 return Object
.prototype.toString
.call(object
).match(/\s([a-z]+)/i)[1].toLowerCase();
96 const getUID
= prefix
=> {
98 prefix
+= Math
.floor(Math
.random() * MAX_UID
);
99 } while (document
.getElementById(prefix
));
102 const getTransitionDurationFromElement
= element
=> {
107 // Get transition-duration of the element
111 } = window
.getComputedStyle(element
);
112 const floatTransitionDuration
= Number
.parseFloat(transitionDuration
);
113 const floatTransitionDelay
= Number
.parseFloat(transitionDelay
);
115 // Return 0 if element or transition duration is not found
116 if (!floatTransitionDuration
&& !floatTransitionDelay
) {
120 // If multiple durations are defined, take the first
121 transitionDuration
= transitionDuration
.split(',')[0];
122 transitionDelay
= transitionDelay
.split(',')[0];
123 return (Number
.parseFloat(transitionDuration
) + Number
.parseFloat(transitionDelay
)) * MILLISECONDS_MULTIPLIER
;
125 const triggerTransitionEnd
= element
=> {
126 element
.dispatchEvent(new Event(TRANSITION_END
));
128 const isElement
$1 = object
=> {
129 if (!object
|| typeof object
!== 'object') {
132 if (typeof object
.jquery
!== 'undefined') {
135 return typeof object
.nodeType
!== 'undefined';
137 const getElement
= object
=> {
138 // it's a jQuery object or a node element
139 if (isElement
$1(object
)) {
140 return object
.jquery
? object
[0] : object
;
142 if (typeof object
=== 'string' && object
.length
> 0) {
143 return document
.querySelector(parseSelector(object
));
147 const isVisible
= element
=> {
148 if (!isElement
$1(element
) || element
.getClientRects().length
=== 0) {
151 const elementIsVisible
= getComputedStyle(element
).getPropertyValue('visibility') === 'visible';
152 // Handle `details` element as its content may falsie appear visible when it is closed
153 const closedDetails
= element
.closest('details:not([open])');
154 if (!closedDetails
) {
155 return elementIsVisible
;
157 if (closedDetails
!== element
) {
158 const summary
= element
.closest('summary');
159 if (summary
&& summary
.parentNode
!== closedDetails
) {
162 if (summary
=== null) {
166 return elementIsVisible
;
168 const isDisabled
= element
=> {
169 if (!element
|| element
.nodeType
!== Node
.ELEMENT_NODE
) {
172 if (element
.classList
.contains('disabled')) {
175 if (typeof element
.disabled
!== 'undefined') {
176 return element
.disabled
;
178 return element
.hasAttribute('disabled') && element
.getAttribute('disabled') !== 'false';
180 const findShadowRoot
= element
=> {
181 if (!document
.documentElement
.attachShadow
) {
185 // Can find the shadow root otherwise it'll return the document
186 if (typeof element
.getRootNode
=== 'function') {
187 const root
= element
.getRootNode();
188 return root
instanceof ShadowRoot
? root : null;
190 if (element
instanceof ShadowRoot
) {
194 // when we don't find a shadow root
195 if (!element
.parentNode
) {
198 return findShadowRoot(element
.parentNode
);
200 const noop
= () => {};
203 * Trick to restart an element's animation
205 * @param {HTMLElement} element
208 * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
210 const reflow
= element
=> {
211 element
.offsetHeight
; // eslint-disable-line no-unused-expressions
214 const getjQuery
= () => {
215 if (window
.jQuery
&& !document
.body
.hasAttribute('data-bs-no-jquery')) {
216 return window
.jQuery
;
220 const DOMContentLoadedCallbacks
= [];
221 const onDOMContentLoaded
= callback
=> {
222 if (document
.readyState
=== 'loading') {
223 // add listener on the first call when the document is in loading state
224 if (!DOMContentLoadedCallbacks
.length
) {
225 document
.addEventListener('DOMContentLoaded', () => {
226 for (const callback
of DOMContentLoadedCallbacks
) {
231 DOMContentLoadedCallbacks
.push(callback
);
236 const isRTL
= () => document
.documentElement
.dir
=== 'rtl';
237 const defineJQueryPlugin
= plugin
=> {
238 onDOMContentLoaded(() => {
239 const $ = getjQuery();
240 /* istanbul ignore if */
242 const name
= plugin
.NAME
;
243 const JQUERY_NO_CONFLICT
= $.fn
[name
];
244 $.fn
[name
] = plugin
.jQueryInterface
;
245 $.fn
[name
].Constructor
= plugin
;
246 $.fn
[name
].noConflict
= () => {
247 $.fn
[name
] = JQUERY_NO_CONFLICT
;
248 return plugin
.jQueryInterface
;
253 const execute
= (possibleCallback
, args
= [], defaultValue
= possibleCallback
) => {
254 return typeof possibleCallback
=== 'function' ? possibleCallback(...args
) : defaultValue
;
256 const executeAfterTransition
= (callback
, transitionElement
, waitForTransition
= true) => {
257 if (!waitForTransition
) {
261 const durationPadding
= 5;
262 const emulatedDuration
= getTransitionDurationFromElement(transitionElement
) + durationPadding
;
267 if (target
!== transitionElement
) {
271 transitionElement
.removeEventListener(TRANSITION_END
, handler
);
274 transitionElement
.addEventListener(TRANSITION_END
, handler
);
277 triggerTransitionEnd(transitionElement
);
279 }, emulatedDuration
);
283 * Return the previous/next element of a list.
285 * @param {array} list The list of elements
286 * @param activeElement The active element
287 * @param shouldGetNext Choose to get next or previous element
288 * @param isCycleAllowed
289 * @return {Element|elem} The proper element
291 const getNextActiveElement
= (list
, activeElement
, shouldGetNext
, isCycleAllowed
) => {
292 const listLength
= list
.length
;
293 let index
= list
.indexOf(activeElement
);
295 // if the element does not exist in the list return an element
296 // depending on the direction and if cycle is allowed
298 return !shouldGetNext
&& isCycleAllowed
? list
[listLength
- 1] : list
[0];
300 index
+= shouldGetNext
? 1 : -1;
301 if (isCycleAllowed
) {
302 index
= (index
+ listLength
) % listLength
;
304 return list
[Math
.max(0, Math
.min(index
, listLength
- 1))];
308 * --------------------------------------------------------------------------
309 * Bootstrap dom/event-handler.js
310 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
311 * --------------------------------------------------------------------------
319 const namespaceRegex
= /[^.]*(?=\..*)\.|.*/;
320 const stripNameRegex
= /\..*/;
321 const stripUidRegex
= /::\d+$/;
322 const eventRegistry
= {}; // Events storage
324 const customEvents
= {
325 mouseenter: 'mouseover',
326 mouseleave: 'mouseout'
328 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']);
334 function makeEventUid(element
, uid
) {
335 return uid
&& `${uid}::${uidEvent++}` || element
.uidEvent
|| uidEvent
++;
337 function getElementEvents(element
) {
338 const uid
= makeEventUid(element
);
339 element
.uidEvent
= uid
;
340 eventRegistry
[uid
] = eventRegistry
[uid
] || {};
341 return eventRegistry
[uid
];
343 function bootstrapHandler(element
, fn
) {
344 return function handler(event
) {
346 delegateTarget: element
348 if (handler
.oneOff
) {
349 EventHandler
.off(element
, event
.type
, fn
);
351 return fn
.apply(element
, [event
]);
354 function bootstrapDelegationHandler(element
, selector
, fn
) {
355 return function handler(event
) {
356 const domElements
= element
.querySelectorAll(selector
);
359 } = event
; target
&& target
!== this; target
= target
.parentNode
) {
360 for (const domElement
of domElements
) {
361 if (domElement
!== target
) {
365 delegateTarget: target
367 if (handler
.oneOff
) {
368 EventHandler
.off(element
, event
.type
, selector
, fn
);
370 return fn
.apply(target
, [event
]);
375 function findHandler(events
, callable
, delegationSelector
= null) {
376 return Object
.values(events
).find(event
=> event
.callable
=== callable
&& event
.delegationSelector
=== delegationSelector
);
378 function normalizeParameters(originalTypeEvent
, handler
, delegationFunction
) {
379 const isDelegated
= typeof handler
=== 'string';
380 // TODO: tooltip passes `false` instead of selector, so we need to check
381 const callable
= isDelegated
? delegationFunction : handler
|| delegationFunction
;
382 let typeEvent
= getTypeEvent(originalTypeEvent
);
383 if (!nativeEvents
.has(typeEvent
)) {
384 typeEvent
= originalTypeEvent
;
386 return [isDelegated
, callable
, typeEvent
];
388 function addHandler(element
, originalTypeEvent
, handler
, delegationFunction
, oneOff
) {
389 if (typeof originalTypeEvent
!== 'string' || !element
) {
392 let [isDelegated
, callable
, typeEvent
] = normalizeParameters(originalTypeEvent
, handler
, delegationFunction
);
394 // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
395 // this prevents the handler from being dispatched the same way as mouseover or mouseout does
396 if (originalTypeEvent
in customEvents
) {
397 const wrapFunction
= fn
=> {
398 return function (event
) {
399 if (!event
.relatedTarget
|| event
.relatedTarget
!== event
.delegateTarget
&& !event
.delegateTarget
.contains(event
.relatedTarget
)) {
400 return fn
.call(this, event
);
404 callable
= wrapFunction(callable
);
406 const events
= getElementEvents(element
);
407 const handlers
= events
[typeEvent
] || (events
[typeEvent
] = {});
408 const previousFunction
= findHandler(handlers
, callable
, isDelegated
? handler : null);
409 if (previousFunction
) {
410 previousFunction
.oneOff
= previousFunction
.oneOff
&& oneOff
;
413 const uid
= makeEventUid(callable
, originalTypeEvent
.replace(namespaceRegex
, ''));
414 const fn
= isDelegated
? bootstrapDelegationHandler(element
, handler
, callable
) : bootstrapHandler(element
, callable
);
415 fn
.delegationSelector
= isDelegated
? handler : null;
416 fn
.callable
= callable
;
420 element
.addEventListener(typeEvent
, fn
, isDelegated
);
422 function removeHandler(element
, events
, typeEvent
, handler
, delegationSelector
) {
423 const fn
= findHandler(events
[typeEvent
], handler
, delegationSelector
);
427 element
.removeEventListener(typeEvent
, fn
, Boolean(delegationSelector
));
428 delete events
[typeEvent
][fn
.uidEvent
];
430 function removeNamespacedHandlers(element
, events
, typeEvent
, namespace) {
431 const storeElementEvent
= events
[typeEvent
] || {};
432 for (const [handlerKey
, event
] of Object
.entries(storeElementEvent
)) {
433 if (handlerKey
.includes(namespace)) {
434 removeHandler(element
, events
, typeEvent
, event
.callable
, event
.delegationSelector
);
438 function getTypeEvent(event
) {
439 // allow to get the native events from namespaced events ('click.bs.button' --> 'click')
440 event
= event
.replace(stripNameRegex
, '');
441 return customEvents
[event
] || event
;
443 const EventHandler
= {
444 on(element
, event
, handler
, delegationFunction
) {
445 addHandler(element
, event
, handler
, delegationFunction
, false);
447 one(element
, event
, handler
, delegationFunction
) {
448 addHandler(element
, event
, handler
, delegationFunction
, true);
450 off(element
, originalTypeEvent
, handler
, delegationFunction
) {
451 if (typeof originalTypeEvent
!== 'string' || !element
) {
454 const [isDelegated
, callable
, typeEvent
] = normalizeParameters(originalTypeEvent
, handler
, delegationFunction
);
455 const inNamespace
= typeEvent
!== originalTypeEvent
;
456 const events
= getElementEvents(element
);
457 const storeElementEvent
= events
[typeEvent
] || {};
458 const isNamespace
= originalTypeEvent
.startsWith('.');
459 if (typeof callable
!== 'undefined') {
460 // Simplest case: handler is passed, remove that listener ONLY.
461 if (!Object
.keys(storeElementEvent
).length
) {
464 removeHandler(element
, events
, typeEvent
, callable
, isDelegated
? handler : null);
468 for (const elementEvent
of Object
.keys(events
)) {
469 removeNamespacedHandlers(element
, events
, elementEvent
, originalTypeEvent
.slice(1));
472 for (const [keyHandlers
, event
] of Object
.entries(storeElementEvent
)) {
473 const handlerKey
= keyHandlers
.replace(stripUidRegex
, '');
474 if (!inNamespace
|| originalTypeEvent
.includes(handlerKey
)) {
475 removeHandler(element
, events
, typeEvent
, event
.callable
, event
.delegationSelector
);
479 trigger(element
, event
, args
) {
480 if (typeof event
!== 'string' || !element
) {
483 const $ = getjQuery();
484 const typeEvent
= getTypeEvent(event
);
485 const inNamespace
= event
!== typeEvent
;
486 let jQueryEvent
= null;
488 let nativeDispatch
= true;
489 let defaultPrevented
= false;
490 if (inNamespace
&& $) {
491 jQueryEvent
= $.Event(event
, args
);
492 $(element
).trigger(jQueryEvent
);
493 bubbles
= !jQueryEvent
.isPropagationStopped();
494 nativeDispatch
= !jQueryEvent
.isImmediatePropagationStopped();
495 defaultPrevented
= jQueryEvent
.isDefaultPrevented();
497 const evt
= hydrateObj(new Event(event
, {
501 if (defaultPrevented
) {
502 evt
.preventDefault();
504 if (nativeDispatch
) {
505 element
.dispatchEvent(evt
);
507 if (evt
.defaultPrevented
&& jQueryEvent
) {
508 jQueryEvent
.preventDefault();
513 function hydrateObj(obj
, meta
= {}) {
514 for (const [key
, value
] of Object
.entries(meta
)) {
518 Object
.defineProperty(obj
, key
, {
530 * --------------------------------------------------------------------------
531 * Bootstrap dom/manipulator.js
532 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
533 * --------------------------------------------------------------------------
536 function normalizeData(value
) {
537 if (value
=== 'true') {
540 if (value
=== 'false') {
543 if (value
=== Number(value
).toString()) {
544 return Number(value
);
546 if (value
=== '' || value
=== 'null') {
549 if (typeof value
!== 'string') {
553 return JSON
.parse(decodeURIComponent(value
));
558 function normalizeDataKey(key
) {
559 return key
.replace(/[A-Z]/g, chr
=> `-${chr.toLowerCase()}`);
561 const Manipulator
= {
562 setDataAttribute(element
, key
, value
) {
563 element
.setAttribute(`data-bs-${normalizeDataKey(key)}`, value
);
565 removeDataAttribute(element
, key
) {
566 element
.removeAttribute(`data-bs-${normalizeDataKey(key)}`);
568 getDataAttributes(element
) {
572 const attributes
= {};
573 const bsKeys
= Object
.keys(element
.dataset
).filter(key
=> key
.startsWith('bs') && !key
.startsWith('bsConfig'));
574 for (const key
of bsKeys
) {
575 let pureKey
= key
.replace(/^bs/, '');
576 pureKey
= pureKey
.charAt(0).toLowerCase() + pureKey
.slice(1, pureKey
.length
);
577 attributes
[pureKey
] = normalizeData(element
.dataset
[key
]);
581 getDataAttribute(element
, key
) {
582 return normalizeData(element
.getAttribute(`data-bs-${normalizeDataKey(key)}`));
587 * --------------------------------------------------------------------------
588 * Bootstrap util/config.js
589 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
590 * --------------------------------------------------------------------------
600 static get Default() {
603 static get DefaultType() {
607 throw new Error('You have to implement the static method "NAME", for each component!');
610 config
= this._mergeConfigObj(config
);
611 config
= this._configAfterMerge(config
);
612 this._typeCheckConfig(config
);
615 _configAfterMerge(config
) {
618 _mergeConfigObj(config
, element
) {
619 const jsonConfig
= isElement
$1(element
) ? Manipulator
.getDataAttribute(element
, 'config') : {}; // try to parse
622 ...this.constructor.Default
,
623 ...(typeof jsonConfig
=== 'object' ? jsonConfig : {}),
624 ...(isElement
$1(element
) ? Manipulator
.getDataAttributes(element
) : {}),
625 ...(typeof config
=== 'object' ? config : {})
628 _typeCheckConfig(config
, configTypes
= this.constructor.DefaultType
) {
629 for (const [property
, expectedTypes
] of Object
.entries(configTypes
)) {
630 const value
= config
[property
];
631 const valueType
= isElement
$1(value
) ? 'element' : toType(value
);
632 if (!new RegExp(expectedTypes
).test(valueType
)) {
633 throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
640 * --------------------------------------------------------------------------
641 * Bootstrap base-component.js
642 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
643 * --------------------------------------------------------------------------
651 const VERSION
= '5.3.2';
657 class BaseComponent
extends Config
{
658 constructor(element
, config
) {
660 element
= getElement(element
);
664 this._element
= element
;
665 this._config
= this._getConfig(config
);
666 Data
.set(this._element
, this.constructor.DATA_KEY
, this);
671 Data
.remove(this._element
, this.constructor.DATA_KEY
);
672 EventHandler
.off(this._element
, this.constructor.EVENT_KEY
);
673 for (const propertyName
of Object
.getOwnPropertyNames(this)) {
674 this[propertyName
] = null;
677 _queueCallback(callback
, element
, isAnimated
= true) {
678 executeAfterTransition(callback
, element
, isAnimated
);
681 config
= this._mergeConfigObj(config
, this._element
);
682 config
= this._configAfterMerge(config
);
683 this._typeCheckConfig(config
);
688 static getInstance(element
) {
689 return Data
.get(getElement(element
), this.DATA_KEY
);
691 static getOrCreateInstance(element
, config
= {}) {
692 return this.getInstance(element
) || new this(element
, typeof config
=== 'object' ? config : null);
694 static get VERSION() {
697 static get DATA_KEY() {
698 return `bs.${this.NAME}`;
700 static get EVENT_KEY() {
701 return `.${this.DATA_KEY}`;
703 static eventName(name
) {
704 return `${name}${this.EVENT_KEY}`;
709 * --------------------------------------------------------------------------
710 * Bootstrap dom/selector-engine.js
711 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
712 * --------------------------------------------------------------------------
715 const getSelector
= element
=> {
716 let selector
= element
.getAttribute('data-bs-target');
717 if (!selector
|| selector
=== '#') {
718 let hrefAttribute
= element
.getAttribute('href');
720 // The only valid content that could double as a selector are IDs or classes,
721 // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
722 // `document.querySelector` will rightfully complain it is invalid.
723 // See https://github.com/twbs/bootstrap/issues/32273
724 if (!hrefAttribute
|| !hrefAttribute
.includes('#') && !hrefAttribute
.startsWith('.')) {
728 // Just in case some CMS puts out a full URL with the anchor appended
729 if (hrefAttribute
.includes('#') && !hrefAttribute
.startsWith('#')) {
730 hrefAttribute
= `#${hrefAttribute.split('#')[1]}`;
732 selector
= hrefAttribute
&& hrefAttribute
!== '#' ? parseSelector(hrefAttribute
.trim()) : null;
736 const SelectorEngine
= {
737 find(selector
, element
= document
.documentElement
) {
738 return [].concat(...Element
.prototype.querySelectorAll
.call(element
, selector
));
740 findOne(selector
, element
= document
.documentElement
) {
741 return Element
.prototype.querySelector
.call(element
, selector
);
743 children(element
, selector
) {
744 return [].concat(...element
.children
).filter(child
=> child
.matches(selector
));
746 parents(element
, selector
) {
748 let ancestor
= element
.parentNode
.closest(selector
);
750 parents
.push(ancestor
);
751 ancestor
= ancestor
.parentNode
.closest(selector
);
755 prev(element
, selector
) {
756 let previous
= element
.previousElementSibling
;
758 if (previous
.matches(selector
)) {
761 previous
= previous
.previousElementSibling
;
765 // TODO: this is now unused; remove later along with prev()
766 next(element
, selector
) {
767 let next
= element
.nextElementSibling
;
769 if (next
.matches(selector
)) {
772 next
= next
.nextElementSibling
;
776 focusableChildren(element
) {
777 const focusables
= ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector
=> `${selector}:not([tabindex^="-"])`).join(',');
778 return this.find(focusables
, element
).filter(el
=> !isDisabled(el
) && isVisible(el
));
780 getSelectorFromElement(element
) {
781 const selector
= getSelector(element
);
783 return SelectorEngine
.findOne(selector
) ? selector : null;
787 getElementFromSelector(element
) {
788 const selector
= getSelector(element
);
789 return selector
? SelectorEngine
.findOne(selector
) : null;
791 getMultipleElementsFromSelector(element
) {
792 const selector
= getSelector(element
);
793 return selector
? SelectorEngine
.find(selector
) : [];
798 * --------------------------------------------------------------------------
799 * Bootstrap util/component-functions.js
800 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
801 * --------------------------------------------------------------------------
804 const enableDismissTrigger
= (component
, method
= 'hide') => {
805 const clickEvent
= `click.dismiss${component.EVENT_KEY}`;
806 const name
= component
.NAME
;
807 EventHandler
.on(document
, clickEvent
, `[data-bs-dismiss="${name}"]`, function (event
) {
808 if (['A', 'AREA'].includes(this.tagName
)) {
809 event
.preventDefault();
811 if (isDisabled(this)) {
814 const target
= SelectorEngine
.getElementFromSelector(this) || this.closest(`.${name}`);
815 const instance
= component
.getOrCreateInstance(target
);
817 // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
823 * --------------------------------------------------------------------------
825 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
826 * --------------------------------------------------------------------------
834 const NAME
$f
= 'alert';
835 const DATA_KEY
$a
= 'bs.alert';
836 const EVENT_KEY
$b
= `.${DATA_KEY$a}`;
837 const EVENT_CLOSE
= `close${EVENT_KEY$b}`;
838 const EVENT_CLOSED
= `closed${EVENT_KEY$b}`;
839 const CLASS_NAME_FADE
$5 = 'fade';
840 const CLASS_NAME_SHOW
$8 = 'show';
846 class Alert
extends BaseComponent
{
854 const closeEvent
= EventHandler
.trigger(this._element
, EVENT_CLOSE
);
855 if (closeEvent
.defaultPrevented
) {
858 this._element
.classList
.remove(CLASS_NAME_SHOW
$8);
859 const isAnimated
= this._element
.classList
.contains(CLASS_NAME_FADE
$5);
860 this._queueCallback(() => this._destroyElement(), this._element
, isAnimated
);
865 this._element
.remove();
866 EventHandler
.trigger(this._element
, EVENT_CLOSED
);
871 static jQueryInterface(config
) {
872 return this.each(function () {
873 const data
= Alert
.getOrCreateInstance(this);
874 if (typeof config
!== 'string') {
877 if (data
[config
] === undefined || config
.startsWith('_') || config
=== 'constructor') {
878 throw new TypeError(`No method named "${config}"`);
886 * Data API implementation
889 enableDismissTrigger(Alert
, 'close');
895 defineJQueryPlugin(Alert
);
898 * --------------------------------------------------------------------------
899 * Bootstrap button.js
900 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
901 * --------------------------------------------------------------------------
909 const NAME
$e
= 'button';
910 const DATA_KEY
$9 = 'bs.button';
911 const EVENT_KEY
$a
= `.${DATA_KEY$9}`;
912 const DATA_API_KEY
$6 = '.data-api';
913 const CLASS_NAME_ACTIVE
$3 = 'active';
914 const SELECTOR_DATA_TOGGLE
$5 = '[data-bs-toggle="button"]';
915 const EVENT_CLICK_DATA_API
$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;
921 class Button
extends BaseComponent
{
929 // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
930 this._element
.setAttribute('aria-pressed', this._element
.classList
.toggle(CLASS_NAME_ACTIVE
$3));
934 static jQueryInterface(config
) {
935 return this.each(function () {
936 const data
= Button
.getOrCreateInstance(this);
937 if (config
=== 'toggle') {
945 * Data API implementation
948 EventHandler
.on(document
, EVENT_CLICK_DATA_API
$6, SELECTOR_DATA_TOGGLE
$5, event
=> {
949 event
.preventDefault();
950 const button
= event
.target
.closest(SELECTOR_DATA_TOGGLE
$5);
951 const data
= Button
.getOrCreateInstance(button
);
959 defineJQueryPlugin(Button
);
962 * --------------------------------------------------------------------------
963 * Bootstrap util/swipe.js
964 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
965 * --------------------------------------------------------------------------
973 const NAME
$d
= 'swipe';
974 const EVENT_KEY
$9 = '.bs.swipe';
975 const EVENT_TOUCHSTART
= `touchstart${EVENT_KEY$9}`;
976 const EVENT_TOUCHMOVE
= `touchmove${EVENT_KEY$9}`;
977 const EVENT_TOUCHEND
= `touchend${EVENT_KEY$9}`;
978 const EVENT_POINTERDOWN
= `pointerdown${EVENT_KEY$9}`;
979 const EVENT_POINTERUP
= `pointerup${EVENT_KEY$9}`;
980 const POINTER_TYPE_TOUCH
= 'touch';
981 const POINTER_TYPE_PEN
= 'pen';
982 const CLASS_NAME_POINTER_EVENT
= 'pointer-event';
983 const SWIPE_THRESHOLD
= 40;
989 const DefaultType
$c
= {
990 endCallback: '(function|null)',
991 leftCallback: '(function|null)',
992 rightCallback: '(function|null)'
999 class Swipe
extends Config
{
1000 constructor(element
, config
) {
1002 this._element
= element
;
1003 if (!element
|| !Swipe
.isSupported()) {
1006 this._config
= this._getConfig(config
);
1008 this._supportPointerEvents
= Boolean(window
.PointerEvent
);
1013 static get Default() {
1016 static get DefaultType() {
1017 return DefaultType
$c
;
1025 EventHandler
.off(this._element
, EVENT_KEY
$9);
1030 if (!this._supportPointerEvents
) {
1031 this._deltaX
= event
.touches
[0].clientX
;
1034 if (this._eventIsPointerPenTouch(event
)) {
1035 this._deltaX
= event
.clientX
;
1039 if (this._eventIsPointerPenTouch(event
)) {
1040 this._deltaX
= event
.clientX
- this._deltaX
;
1042 this._handleSwipe();
1043 execute(this._config
.endCallback
);
1046 this._deltaX
= event
.touches
&& event
.touches
.length
> 1 ? 0 : event
.touches
[0].clientX
- this._deltaX
;
1049 const absDeltaX
= Math
.abs(this._deltaX
);
1050 if (absDeltaX
<= SWIPE_THRESHOLD
) {
1053 const direction
= absDeltaX
/ this._deltaX
;
1058 execute(direction
> 0 ? this._config
.rightCallback : this._config
.leftCallback
);
1061 if (this._supportPointerEvents
) {
1062 EventHandler
.on(this._element
, EVENT_POINTERDOWN
, event
=> this._start(event
));
1063 EventHandler
.on(this._element
, EVENT_POINTERUP
, event
=> this._end(event
));
1064 this._element
.classList
.add(CLASS_NAME_POINTER_EVENT
);
1066 EventHandler
.on(this._element
, EVENT_TOUCHSTART
, event
=> this._start(event
));
1067 EventHandler
.on(this._element
, EVENT_TOUCHMOVE
, event
=> this._move(event
));
1068 EventHandler
.on(this._element
, EVENT_TOUCHEND
, event
=> this._end(event
));
1071 _eventIsPointerPenTouch(event
) {
1072 return this._supportPointerEvents
&& (event
.pointerType
=== POINTER_TYPE_PEN
|| event
.pointerType
=== POINTER_TYPE_TOUCH
);
1076 static isSupported() {
1077 return 'ontouchstart' in document
.documentElement
|| navigator
.maxTouchPoints
> 0;
1082 * --------------------------------------------------------------------------
1083 * Bootstrap carousel.js
1084 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1085 * --------------------------------------------------------------------------
1093 const NAME
$c
= 'carousel';
1094 const DATA_KEY
$8 = 'bs.carousel';
1095 const EVENT_KEY
$8 = `.${DATA_KEY$8}`;
1096 const DATA_API_KEY
$5 = '.data-api';
1097 const ARROW_LEFT_KEY
$1 = 'ArrowLeft';
1098 const ARROW_RIGHT_KEY
$1 = 'ArrowRight';
1099 const TOUCHEVENT_COMPAT_WAIT
= 500; // Time for mouse compat events to fire after touch
1101 const ORDER_NEXT
= 'next';
1102 const ORDER_PREV
= 'prev';
1103 const DIRECTION_LEFT
= 'left';
1104 const DIRECTION_RIGHT
= 'right';
1105 const EVENT_SLIDE
= `slide${EVENT_KEY$8}`;
1106 const EVENT_SLID
= `slid${EVENT_KEY$8}`;
1107 const EVENT_KEYDOWN
$1 = `keydown${EVENT_KEY$8}`;
1108 const EVENT_MOUSEENTER
$1 = `mouseenter${EVENT_KEY$8}`;
1109 const EVENT_MOUSELEAVE
$1 = `mouseleave${EVENT_KEY$8}`;
1110 const EVENT_DRAG_START
= `dragstart${EVENT_KEY$8}`;
1111 const EVENT_LOAD_DATA_API
$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`;
1112 const EVENT_CLICK_DATA_API
$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;
1113 const CLASS_NAME_CAROUSEL
= 'carousel';
1114 const CLASS_NAME_ACTIVE
$2 = 'active';
1115 const CLASS_NAME_SLIDE
= 'slide';
1116 const CLASS_NAME_END
= 'carousel-item-end';
1117 const CLASS_NAME_START
= 'carousel-item-start';
1118 const CLASS_NAME_NEXT
= 'carousel-item-next';
1119 const CLASS_NAME_PREV
= 'carousel-item-prev';
1120 const SELECTOR_ACTIVE
= '.active';
1121 const SELECTOR_ITEM
= '.carousel-item';
1122 const SELECTOR_ACTIVE_ITEM
= SELECTOR_ACTIVE
+ SELECTOR_ITEM
;
1123 const SELECTOR_ITEM_IMG
= '.carousel-item img';
1124 const SELECTOR_INDICATORS
= '.carousel-indicators';
1125 const SELECTOR_DATA_SLIDE
= '[data-bs-slide], [data-bs-slide-to]';
1126 const SELECTOR_DATA_RIDE
= '[data-bs-ride="carousel"]';
1127 const KEY_TO_DIRECTION
= {
1128 [ARROW_LEFT_KEY
$1]: DIRECTION_RIGHT
,
1129 [ARROW_RIGHT_KEY
$1]: DIRECTION_LEFT
1139 const DefaultType
$b
= {
1140 interval: '(number|boolean)',
1141 // TODO:v6 remove boolean support
1142 keyboard: 'boolean',
1143 pause: '(string|boolean)',
1144 ride: '(boolean|string)',
1153 class Carousel
extends BaseComponent
{
1154 constructor(element
, config
) {
1155 super(element
, config
);
1156 this._interval
= null;
1157 this._activeElement
= null;
1158 this._isSliding
= false;
1159 this.touchTimeout
= null;
1160 this._swipeHelper
= null;
1161 this._indicatorsElement
= SelectorEngine
.findOne(SELECTOR_INDICATORS
, this._element
);
1162 this._addEventListeners();
1163 if (this._config
.ride
=== CLASS_NAME_CAROUSEL
) {
1169 static get Default() {
1172 static get DefaultType() {
1173 return DefaultType
$b
;
1181 this._slide(ORDER_NEXT
);
1184 // FIXME TODO use `document.visibilityState`
1185 // Don't call next when the page isn't visible
1186 // or the carousel or its parent isn't visible
1187 if (!document
.hidden
&& isVisible(this._element
)) {
1192 this._slide(ORDER_PREV
);
1195 if (this._isSliding
) {
1196 triggerTransitionEnd(this._element
);
1198 this._clearInterval();
1201 this._clearInterval();
1202 this._updateInterval();
1203 this._interval
= setInterval(() => this.nextWhenVisible(), this._config
.interval
);
1205 _maybeEnableCycle() {
1206 if (!this._config
.ride
) {
1209 if (this._isSliding
) {
1210 EventHandler
.one(this._element
, EVENT_SLID
, () => this.cycle());
1216 const items
= this._getItems();
1217 if (index
> items
.length
- 1 || index
< 0) {
1220 if (this._isSliding
) {
1221 EventHandler
.one(this._element
, EVENT_SLID
, () => this.to(index
));
1224 const activeIndex
= this._getItemIndex(this._getActive());
1225 if (activeIndex
=== index
) {
1228 const order
= index
> activeIndex
? ORDER_NEXT : ORDER_PREV
;
1229 this._slide(order
, items
[index
]);
1232 if (this._swipeHelper
) {
1233 this._swipeHelper
.dispose();
1239 _configAfterMerge(config
) {
1240 config
.defaultInterval
= config
.interval
;
1243 _addEventListeners() {
1244 if (this._config
.keyboard
) {
1245 EventHandler
.on(this._element
, EVENT_KEYDOWN
$1, event
=> this._keydown(event
));
1247 if (this._config
.pause
=== 'hover') {
1248 EventHandler
.on(this._element
, EVENT_MOUSEENTER
$1, () => this.pause());
1249 EventHandler
.on(this._element
, EVENT_MOUSELEAVE
$1, () => this._maybeEnableCycle());
1251 if (this._config
.touch
&& Swipe
.isSupported()) {
1252 this._addTouchEventListeners();
1255 _addTouchEventListeners() {
1256 for (const img
of SelectorEngine
.find(SELECTOR_ITEM_IMG
, this._element
)) {
1257 EventHandler
.on(img
, EVENT_DRAG_START
, event
=> event
.preventDefault());
1259 const endCallBack
= () => {
1260 if (this._config
.pause
!== 'hover') {
1264 // If it's a touch-enabled device, mouseenter/leave are fired as
1265 // part of the mouse compatibility events on first tap - the carousel
1266 // would stop cycling until user tapped out of it;
1267 // here, we listen for touchend, explicitly pause the carousel
1268 // (as if it's the second time we tap on it, mouseenter compat event
1269 // is NOT fired) and after a timeout (to allow for mouse compatibility
1270 // events to fire) we explicitly restart cycling
1273 if (this.touchTimeout
) {
1274 clearTimeout(this.touchTimeout
);
1276 this.touchTimeout
= setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT
+ this._config
.interval
);
1278 const swipeConfig
= {
1279 leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT
)),
1280 rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT
)),
1281 endCallback: endCallBack
1283 this._swipeHelper
= new Swipe(this._element
, swipeConfig
);
1286 if (/input|textarea/i.test(event
.target
.tagName
)) {
1289 const direction
= KEY_TO_DIRECTION
[event
.key
];
1291 event
.preventDefault();
1292 this._slide(this._directionToOrder(direction
));
1295 _getItemIndex(element
) {
1296 return this._getItems().indexOf(element
);
1298 _setActiveIndicatorElement(index
) {
1299 if (!this._indicatorsElement
) {
1302 const activeIndicator
= SelectorEngine
.findOne(SELECTOR_ACTIVE
, this._indicatorsElement
);
1303 activeIndicator
.classList
.remove(CLASS_NAME_ACTIVE
$2);
1304 activeIndicator
.removeAttribute('aria-current');
1305 const newActiveIndicator
= SelectorEngine
.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement
);
1306 if (newActiveIndicator
) {
1307 newActiveIndicator
.classList
.add(CLASS_NAME_ACTIVE
$2);
1308 newActiveIndicator
.setAttribute('aria-current', 'true');
1312 const element
= this._activeElement
|| this._getActive();
1316 const elementInterval
= Number
.parseInt(element
.getAttribute('data-bs-interval'), 10);
1317 this._config
.interval
= elementInterval
|| this._config
.defaultInterval
;
1319 _slide(order
, element
= null) {
1320 if (this._isSliding
) {
1323 const activeElement
= this._getActive();
1324 const isNext
= order
=== ORDER_NEXT
;
1325 const nextElement
= element
|| getNextActiveElement(this._getItems(), activeElement
, isNext
, this._config
.wrap
);
1326 if (nextElement
=== activeElement
) {
1329 const nextElementIndex
= this._getItemIndex(nextElement
);
1330 const triggerEvent
= eventName
=> {
1331 return EventHandler
.trigger(this._element
, eventName
, {
1332 relatedTarget: nextElement
,
1333 direction: this._orderToDirection(order
),
1334 from: this._getItemIndex(activeElement
),
1335 to: nextElementIndex
1338 const slideEvent
= triggerEvent(EVENT_SLIDE
);
1339 if (slideEvent
.defaultPrevented
) {
1342 if (!activeElement
|| !nextElement
) {
1343 // Some weirdness is happening, so we bail
1344 // TODO: change tests that use empty divs to avoid this check
1347 const isCycling
= Boolean(this._interval
);
1349 this._isSliding
= true;
1350 this._setActiveIndicatorElement(nextElementIndex
);
1351 this._activeElement
= nextElement
;
1352 const directionalClassName
= isNext
? CLASS_NAME_START : CLASS_NAME_END
;
1353 const orderClassName
= isNext
? CLASS_NAME_NEXT : CLASS_NAME_PREV
;
1354 nextElement
.classList
.add(orderClassName
);
1355 reflow(nextElement
);
1356 activeElement
.classList
.add(directionalClassName
);
1357 nextElement
.classList
.add(directionalClassName
);
1358 const completeCallBack
= () => {
1359 nextElement
.classList
.remove(directionalClassName
, orderClassName
);
1360 nextElement
.classList
.add(CLASS_NAME_ACTIVE
$2);
1361 activeElement
.classList
.remove(CLASS_NAME_ACTIVE
$2, orderClassName
, directionalClassName
);
1362 this._isSliding
= false;
1363 triggerEvent(EVENT_SLID
);
1365 this._queueCallback(completeCallBack
, activeElement
, this._isAnimated());
1371 return this._element
.classList
.contains(CLASS_NAME_SLIDE
);
1374 return SelectorEngine
.findOne(SELECTOR_ACTIVE_ITEM
, this._element
);
1377 return SelectorEngine
.find(SELECTOR_ITEM
, this._element
);
1380 if (this._interval
) {
1381 clearInterval(this._interval
);
1382 this._interval
= null;
1385 _directionToOrder(direction
) {
1387 return direction
=== DIRECTION_LEFT
? ORDER_PREV : ORDER_NEXT
;
1389 return direction
=== DIRECTION_LEFT
? ORDER_NEXT : ORDER_PREV
;
1391 _orderToDirection(order
) {
1393 return order
=== ORDER_PREV
? DIRECTION_LEFT : DIRECTION_RIGHT
;
1395 return order
=== ORDER_PREV
? DIRECTION_RIGHT : DIRECTION_LEFT
;
1399 static jQueryInterface(config
) {
1400 return this.each(function () {
1401 const data
= Carousel
.getOrCreateInstance(this, config
);
1402 if (typeof config
=== 'number') {
1406 if (typeof config
=== 'string') {
1407 if (data
[config
] === undefined || config
.startsWith('_') || config
=== 'constructor') {
1408 throw new TypeError(`No method named "${config}"`);
1417 * Data API implementation
1420 EventHandler
.on(document
, EVENT_CLICK_DATA_API
$5, SELECTOR_DATA_SLIDE
, function (event
) {
1421 const target
= SelectorEngine
.getElementFromSelector(this);
1422 if (!target
|| !target
.classList
.contains(CLASS_NAME_CAROUSEL
)) {
1425 event
.preventDefault();
1426 const carousel
= Carousel
.getOrCreateInstance(target
);
1427 const slideIndex
= this.getAttribute('data-bs-slide-to');
1429 carousel
.to(slideIndex
);
1430 carousel
._maybeEnableCycle();
1433 if (Manipulator
.getDataAttribute(this, 'slide') === 'next') {
1435 carousel
._maybeEnableCycle();
1439 carousel
._maybeEnableCycle();
1441 EventHandler
.on(window
, EVENT_LOAD_DATA_API
$3, () => {
1442 const carousels
= SelectorEngine
.find(SELECTOR_DATA_RIDE
);
1443 for (const carousel
of carousels
) {
1444 Carousel
.getOrCreateInstance(carousel
);
1452 defineJQueryPlugin(Carousel
);
1455 * --------------------------------------------------------------------------
1456 * Bootstrap collapse.js
1457 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1458 * --------------------------------------------------------------------------
1466 const NAME
$b
= 'collapse';
1467 const DATA_KEY
$7 = 'bs.collapse';
1468 const EVENT_KEY
$7 = `.${DATA_KEY$7}`;
1469 const DATA_API_KEY
$4 = '.data-api';
1470 const EVENT_SHOW
$6 = `show${EVENT_KEY$7}`;
1471 const EVENT_SHOWN
$6 = `shown${EVENT_KEY$7}`;
1472 const EVENT_HIDE
$6 = `hide${EVENT_KEY$7}`;
1473 const EVENT_HIDDEN
$6 = `hidden${EVENT_KEY$7}`;
1474 const EVENT_CLICK_DATA_API
$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`;
1475 const CLASS_NAME_SHOW
$7 = 'show';
1476 const CLASS_NAME_COLLAPSE
= 'collapse';
1477 const CLASS_NAME_COLLAPSING
= 'collapsing';
1478 const CLASS_NAME_COLLAPSED
= 'collapsed';
1479 const CLASS_NAME_DEEPER_CHILDREN
= `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;
1480 const CLASS_NAME_HORIZONTAL
= 'collapse-horizontal';
1481 const WIDTH
= 'width';
1482 const HEIGHT
= 'height';
1483 const SELECTOR_ACTIVES
= '.collapse.show, .collapse.collapsing';
1484 const SELECTOR_DATA_TOGGLE
$4 = '[data-bs-toggle="collapse"]';
1489 const DefaultType
$a
= {
1490 parent: '(null|element)',
1498 class Collapse
extends BaseComponent
{
1499 constructor(element
, config
) {
1500 super(element
, config
);
1501 this._isTransitioning
= false;
1502 this._triggerArray
= [];
1503 const toggleList
= SelectorEngine
.find(SELECTOR_DATA_TOGGLE
$4);
1504 for (const elem
of toggleList
) {
1505 const selector
= SelectorEngine
.getSelectorFromElement(elem
);
1506 const filterElement
= SelectorEngine
.find(selector
).filter(foundElement
=> foundElement
=== this._element
);
1507 if (selector
!== null && filterElement
.length
) {
1508 this._triggerArray
.push(elem
);
1511 this._initializeChildren();
1512 if (!this._config
.parent
) {
1513 this._addAriaAndCollapsedClass(this._triggerArray
, this._isShown());
1515 if (this._config
.toggle
) {
1521 static get Default() {
1524 static get DefaultType() {
1525 return DefaultType
$a
;
1533 if (this._isShown()) {
1540 if (this._isTransitioning
|| this._isShown()) {
1543 let activeChildren
= [];
1545 // find active children
1546 if (this._config
.parent
) {
1547 activeChildren
= this._getFirstLevelChildren(SELECTOR_ACTIVES
).filter(element
=> element
!== this._element
).map(element
=> Collapse
.getOrCreateInstance(element
, {
1551 if (activeChildren
.length
&& activeChildren
[0]._isTransitioning
) {
1554 const startEvent
= EventHandler
.trigger(this._element
, EVENT_SHOW
$6);
1555 if (startEvent
.defaultPrevented
) {
1558 for (const activeInstance
of activeChildren
) {
1559 activeInstance
.hide();
1561 const dimension
= this._getDimension();
1562 this._element
.classList
.remove(CLASS_NAME_COLLAPSE
);
1563 this._element
.classList
.add(CLASS_NAME_COLLAPSING
);
1564 this._element
.style
[dimension
] = 0;
1565 this._addAriaAndCollapsedClass(this._triggerArray
, true);
1566 this._isTransitioning
= true;
1567 const complete
= () => {
1568 this._isTransitioning
= false;
1569 this._element
.classList
.remove(CLASS_NAME_COLLAPSING
);
1570 this._element
.classList
.add(CLASS_NAME_COLLAPSE
, CLASS_NAME_SHOW
$7);
1571 this._element
.style
[dimension
] = '';
1572 EventHandler
.trigger(this._element
, EVENT_SHOWN
$6);
1574 const capitalizedDimension
= dimension
[0].toUpperCase() + dimension
.slice(1);
1575 const scrollSize
= `scroll${capitalizedDimension}`;
1576 this._queueCallback(complete
, this._element
, true);
1577 this._element
.style
[dimension
] = `${this._element[scrollSize]}px`;
1580 if (this._isTransitioning
|| !this._isShown()) {
1583 const startEvent
= EventHandler
.trigger(this._element
, EVENT_HIDE
$6);
1584 if (startEvent
.defaultPrevented
) {
1587 const dimension
= this._getDimension();
1588 this._element
.style
[dimension
] = `${this._element.getBoundingClientRect()[dimension]}px`;
1589 reflow(this._element
);
1590 this._element
.classList
.add(CLASS_NAME_COLLAPSING
);
1591 this._element
.classList
.remove(CLASS_NAME_COLLAPSE
, CLASS_NAME_SHOW
$7);
1592 for (const trigger
of this._triggerArray
) {
1593 const element
= SelectorEngine
.getElementFromSelector(trigger
);
1594 if (element
&& !this._isShown(element
)) {
1595 this._addAriaAndCollapsedClass([trigger
], false);
1598 this._isTransitioning
= true;
1599 const complete
= () => {
1600 this._isTransitioning
= false;
1601 this._element
.classList
.remove(CLASS_NAME_COLLAPSING
);
1602 this._element
.classList
.add(CLASS_NAME_COLLAPSE
);
1603 EventHandler
.trigger(this._element
, EVENT_HIDDEN
$6);
1605 this._element
.style
[dimension
] = '';
1606 this._queueCallback(complete
, this._element
, true);
1608 _isShown(element
= this._element
) {
1609 return element
.classList
.contains(CLASS_NAME_SHOW
$7);
1613 _configAfterMerge(config
) {
1614 config
.toggle
= Boolean(config
.toggle
); // Coerce string values
1615 config
.parent
= getElement(config
.parent
);
1619 return this._element
.classList
.contains(CLASS_NAME_HORIZONTAL
) ? WIDTH : HEIGHT
;
1621 _initializeChildren() {
1622 if (!this._config
.parent
) {
1625 const children
= this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE
$4);
1626 for (const element
of children
) {
1627 const selected
= SelectorEngine
.getElementFromSelector(element
);
1629 this._addAriaAndCollapsedClass([element
], this._isShown(selected
));
1633 _getFirstLevelChildren(selector
) {
1634 const children
= SelectorEngine
.find(CLASS_NAME_DEEPER_CHILDREN
, this._config
.parent
);
1635 // remove children if greater depth
1636 return SelectorEngine
.find(selector
, this._config
.parent
).filter(element
=> !children
.includes(element
));
1638 _addAriaAndCollapsedClass(triggerArray
, isOpen
) {
1639 if (!triggerArray
.length
) {
1642 for (const element
of triggerArray
) {
1643 element
.classList
.toggle(CLASS_NAME_COLLAPSED
, !isOpen
);
1644 element
.setAttribute('aria-expanded', isOpen
);
1649 static jQueryInterface(config
) {
1651 if (typeof config
=== 'string' && /show|hide/.test(config
)) {
1652 _config
.toggle
= false;
1654 return this.each(function () {
1655 const data
= Collapse
.getOrCreateInstance(this, _config
);
1656 if (typeof config
=== 'string') {
1657 if (typeof data
[config
] === 'undefined') {
1658 throw new TypeError(`No method named "${config}"`);
1667 * Data API implementation
1670 EventHandler
.on(document
, EVENT_CLICK_DATA_API
$4, SELECTOR_DATA_TOGGLE
$4, function (event
) {
1671 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
1672 if (event
.target
.tagName
=== 'A' || event
.delegateTarget
&& event
.delegateTarget
.tagName
=== 'A') {
1673 event
.preventDefault();
1675 for (const element
of SelectorEngine
.getMultipleElementsFromSelector(this)) {
1676 Collapse
.getOrCreateInstance(element
, {
1686 defineJQueryPlugin(Collapse
);
1689 var bottom
= 'bottom';
1690 var right
= 'right';
1693 var basePlacements
= [top
, bottom
, right
, left
];
1694 var start
= 'start';
1696 var clippingParents
= 'clippingParents';
1697 var viewport
= 'viewport';
1698 var popper
= 'popper';
1699 var reference
= 'reference';
1700 var variationPlacements
= /*#__PURE__*/basePlacements
.reduce(function (acc
, placement
) {
1701 return acc
.concat([placement
+ "-" + start
, placement
+ "-" + end
]);
1703 var placements
= /*#__PURE__*/[].concat(basePlacements
, [auto
]).reduce(function (acc
, placement
) {
1704 return acc
.concat([placement
, placement
+ "-" + start
, placement
+ "-" + end
]);
1705 }, []); // modifiers that need to read the DOM
1707 var beforeRead
= 'beforeRead';
1709 var afterRead
= 'afterRead'; // pure-logic modifiers
1711 var beforeMain
= 'beforeMain';
1713 var afterMain
= 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)
1715 var beforeWrite
= 'beforeWrite';
1716 var write
= 'write';
1717 var afterWrite
= 'afterWrite';
1718 var modifierPhases
= [beforeRead
, read
, afterRead
, beforeMain
, main
, afterMain
, beforeWrite
, write
, afterWrite
];
1720 function getNodeName(element
) {
1721 return element
? (element
.nodeName
|| '').toLowerCase() : null;
1724 function getWindow(node
) {
1729 if (node
.toString() !== '[object Window]') {
1730 var ownerDocument
= node
.ownerDocument
;
1731 return ownerDocument
? ownerDocument
.defaultView
|| window : window
;
1737 function isElement(node
) {
1738 var OwnElement
= getWindow(node
).Element
;
1739 return node
instanceof OwnElement
|| node
instanceof Element
;
1742 function isHTMLElement(node
) {
1743 var OwnElement
= getWindow(node
).HTMLElement
;
1744 return node
instanceof OwnElement
|| node
instanceof HTMLElement
;
1747 function isShadowRoot(node
) {
1748 // IE 11 has no ShadowRoot
1749 if (typeof ShadowRoot
=== 'undefined') {
1753 var OwnElement
= getWindow(node
).ShadowRoot
;
1754 return node
instanceof OwnElement
|| node
instanceof ShadowRoot
;
1757 // and applies them to the HTMLElements such as popper and arrow
1759 function applyStyles(_ref
) {
1760 var state
= _ref
.state
;
1761 Object
.keys(state
.elements
).forEach(function (name
) {
1762 var style
= state
.styles
[name
] || {};
1763 var attributes
= state
.attributes
[name
] || {};
1764 var element
= state
.elements
[name
]; // arrow is optional + virtual elements
1766 if (!isHTMLElement(element
) || !getNodeName(element
)) {
1768 } // Flow doesn't support to extend this property, but it's the most
1769 // effective way to apply styles to an HTMLElement
1770 // $FlowFixMe[cannot-write]
1773 Object
.assign(element
.style
, style
);
1774 Object
.keys(attributes
).forEach(function (name
) {
1775 var value
= attributes
[name
];
1777 if (value
=== false) {
1778 element
.removeAttribute(name
);
1780 element
.setAttribute(name
, value
=== true ? '' : value
);
1786 function effect
$2(_ref2
) {
1787 var state
= _ref2
.state
;
1788 var initialStyles
= {
1790 position: state
.options
.strategy
,
1796 position: 'absolute'
1800 Object
.assign(state
.elements
.popper
.style
, initialStyles
.popper
);
1801 state
.styles
= initialStyles
;
1803 if (state
.elements
.arrow
) {
1804 Object
.assign(state
.elements
.arrow
.style
, initialStyles
.arrow
);
1807 return function () {
1808 Object
.keys(state
.elements
).forEach(function (name
) {
1809 var element
= state
.elements
[name
];
1810 var attributes
= state
.attributes
[name
] || {};
1811 var styleProperties
= Object
.keys(state
.styles
.hasOwnProperty(name
) ? state
.styles
[name
] : initialStyles
[name
]); // Set all values to an empty string to unset them
1813 var style
= styleProperties
.reduce(function (style
, property
) {
1814 style
[property
] = '';
1816 }, {}); // arrow is optional + virtual elements
1818 if (!isHTMLElement(element
) || !getNodeName(element
)) {
1822 Object
.assign(element
.style
, style
);
1823 Object
.keys(attributes
).forEach(function (attribute
) {
1824 element
.removeAttribute(attribute
);
1828 } // eslint-disable-next-line import/no-unused-modules
1831 const applyStyles
$1 = {
1832 name: 'applyStyles',
1837 requires: ['computeStyles']
1840 function getBasePlacement(placement
) {
1841 return placement
.split('-')[0];
1846 var round
= Math
.round
;
1848 function getUAString() {
1849 var uaData
= navigator
.userAgentData
;
1851 if (uaData
!= null && uaData
.brands
&& Array
.isArray(uaData
.brands
)) {
1852 return uaData
.brands
.map(function (item
) {
1853 return item
.brand
+ "/" + item
.version
;
1857 return navigator
.userAgent
;
1860 function isLayoutViewport() {
1861 return !/^((?!chrome|android).)*safari/i.test(getUAString());
1864 function getBoundingClientRect(element
, includeScale
, isFixedStrategy
) {
1865 if (includeScale
=== void 0) {
1866 includeScale
= false;
1869 if (isFixedStrategy
=== void 0) {
1870 isFixedStrategy
= false;
1873 var clientRect
= element
.getBoundingClientRect();
1877 if (includeScale
&& isHTMLElement(element
)) {
1878 scaleX
= element
.offsetWidth
> 0 ? round(clientRect
.width
) / element
.offsetWidth
|| 1 : 1;
1879 scaleY
= element
.offsetHeight
> 0 ? round(clientRect
.height
) / element
.offsetHeight
|| 1 : 1;
1882 var _ref
= isElement(element
) ? getWindow(element
) : window
,
1883 visualViewport
= _ref
.visualViewport
;
1885 var addVisualOffsets
= !isLayoutViewport() && isFixedStrategy
;
1886 var x
= (clientRect
.left
+ (addVisualOffsets
&& visualViewport
? visualViewport
.offsetLeft : 0)) / scaleX
;
1887 var y
= (clientRect
.top
+ (addVisualOffsets
&& visualViewport
? visualViewport
.offsetTop : 0)) / scaleY
;
1888 var width
= clientRect
.width
/ scaleX
;
1889 var height
= clientRect
.height
/ scaleY
;
1902 // means it doesn't take into account transforms.
1904 function getLayoutRect(element
) {
1905 var clientRect
= getBoundingClientRect(element
); // Use the clientRect sizes if it's not been transformed.
1906 // Fixes https://github.com/popperjs/popper-core/issues/1223
1908 var width
= element
.offsetWidth
;
1909 var height
= element
.offsetHeight
;
1911 if (Math
.abs(clientRect
.width
- width
) <= 1) {
1912 width
= clientRect
.width
;
1915 if (Math
.abs(clientRect
.height
- height
) <= 1) {
1916 height
= clientRect
.height
;
1920 x: element
.offsetLeft
,
1921 y: element
.offsetTop
,
1927 function contains(parent
, child
) {
1928 var rootNode
= child
.getRootNode
&& child
.getRootNode(); // First, attempt with faster native method
1930 if (parent
.contains(child
)) {
1932 } // then fallback to custom implementation with Shadow DOM support
1933 else if (rootNode
&& isShadowRoot(rootNode
)) {
1937 if (next
&& parent
.isSameNode(next
)) {
1939 } // $FlowFixMe[prop-missing]: need a better way to handle this...
1942 next
= next
.parentNode
|| next
.host
;
1944 } // Give up, the result is false
1950 function getComputedStyle
$1(element
) {
1951 return getWindow(element
).getComputedStyle(element
);
1954 function isTableElement(element
) {
1955 return ['table', 'td', 'th'].indexOf(getNodeName(element
)) >= 0;
1958 function getDocumentElement(element
) {
1959 // $FlowFixMe[incompatible-return]: assume body is always available
1960 return ((isElement(element
) ? element
.ownerDocument : // $FlowFixMe[prop-missing]
1961 element
.document
) || window
.document
).documentElement
;
1964 function getParentNode(element
) {
1965 if (getNodeName(element
) === 'html') {
1969 return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle
1970 // $FlowFixMe[incompatible-return]
1971 // $FlowFixMe[prop-missing]
1972 element
.assignedSlot
|| // step into the shadow DOM of the parent of a slotted node
1973 element
.parentNode
|| ( // DOM Element detected
1974 isShadowRoot(element
) ? element
.host : null) || // ShadowRoot detected
1975 // $FlowFixMe[incompatible-call]: HTMLElement is a Node
1976 getDocumentElement(element
) // fallback
1981 function getTrueOffsetParent(element
) {
1982 if (!isHTMLElement(element
) || // https://github.com/popperjs/popper-core/issues/837
1983 getComputedStyle
$1(element
).position
=== 'fixed') {
1987 return element
.offsetParent
;
1988 } // `.offsetParent` reports `null` for fixed elements, while absolute elements
1989 // return the containing block
1992 function getContainingBlock(element
) {
1993 var isFirefox
= /firefox/i.test(getUAString());
1994 var isIE
= /Trident/i.test(getUAString());
1996 if (isIE
&& isHTMLElement(element
)) {
1997 // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport
1998 var elementCss
= getComputedStyle
$1(element
);
2000 if (elementCss
.position
=== 'fixed') {
2005 var currentNode
= getParentNode(element
);
2007 if (isShadowRoot(currentNode
)) {
2008 currentNode
= currentNode
.host
;
2011 while (isHTMLElement(currentNode
) && ['html', 'body'].indexOf(getNodeName(currentNode
)) < 0) {
2012 var css
= getComputedStyle
$1(currentNode
); // This is non-exhaustive but covers the most common CSS properties that
2013 // create a containing block.
2014 // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
2016 if (css
.transform
!== 'none' || css
.perspective
!== 'none' || css
.contain
=== 'paint' || ['transform', 'perspective'].indexOf(css
.willChange
) !== -1 || isFirefox
&& css
.willChange
=== 'filter' || isFirefox
&& css
.filter
&& css
.filter
!== 'none') {
2019 currentNode
= currentNode
.parentNode
;
2024 } // Gets the closest ancestor positioned element. Handles some edge cases,
2025 // such as table ancestors and cross browser bugs.
2028 function getOffsetParent(element
) {
2029 var window
= getWindow(element
);
2030 var offsetParent
= getTrueOffsetParent(element
);
2032 while (offsetParent
&& isTableElement(offsetParent
) && getComputedStyle
$1(offsetParent
).position
=== 'static') {
2033 offsetParent
= getTrueOffsetParent(offsetParent
);
2036 if (offsetParent
&& (getNodeName(offsetParent
) === 'html' || getNodeName(offsetParent
) === 'body' && getComputedStyle
$1(offsetParent
).position
=== 'static')) {
2040 return offsetParent
|| getContainingBlock(element
) || window
;
2043 function getMainAxisFromPlacement(placement
) {
2044 return ['top', 'bottom'].indexOf(placement
) >= 0 ? 'x' : 'y';
2047 function within(min
$1, value
, max
$1) {
2048 return max(min
$1, min(value
, max
$1));
2050 function withinMaxClamp(min
, value
, max
) {
2051 var v
= within(min
, value
, max
);
2052 return v
> max
? max : v
;
2055 function getFreshSideObject() {
2064 function mergePaddingObject(paddingObject
) {
2065 return Object
.assign({}, getFreshSideObject(), paddingObject
);
2068 function expandToHashMap(value
, keys
) {
2069 return keys
.reduce(function (hashMap
, key
) {
2070 hashMap
[key
] = value
;
2075 var toPaddingObject
= function toPaddingObject(padding
, state
) {
2076 padding
= typeof padding
=== 'function' ? padding(Object
.assign({}, state
.rects
, {
2077 placement: state
.placement
2079 return mergePaddingObject(typeof padding
!== 'number' ? padding : expandToHashMap(padding
, basePlacements
));
2082 function arrow(_ref
) {
2083 var _state
$modifiersData
$;
2085 var state
= _ref
.state
,
2087 options
= _ref
.options
;
2088 var arrowElement
= state
.elements
.arrow
;
2089 var popperOffsets
= state
.modifiersData
.popperOffsets
;
2090 var basePlacement
= getBasePlacement(state
.placement
);
2091 var axis
= getMainAxisFromPlacement(basePlacement
);
2092 var isVertical
= [left
, right
].indexOf(basePlacement
) >= 0;
2093 var len
= isVertical
? 'height' : 'width';
2095 if (!arrowElement
|| !popperOffsets
) {
2099 var paddingObject
= toPaddingObject(options
.padding
, state
);
2100 var arrowRect
= getLayoutRect(arrowElement
);
2101 var minProp
= axis
=== 'y' ? top : left
;
2102 var maxProp
= axis
=== 'y' ? bottom : right
;
2103 var endDiff
= state
.rects
.reference
[len
] + state
.rects
.reference
[axis
] - popperOffsets
[axis
] - state
.rects
.popper
[len
];
2104 var startDiff
= popperOffsets
[axis
] - state
.rects
.reference
[axis
];
2105 var arrowOffsetParent
= getOffsetParent(arrowElement
);
2106 var clientSize
= arrowOffsetParent
? axis
=== 'y' ? arrowOffsetParent
.clientHeight
|| 0 : arrowOffsetParent
.clientWidth
|| 0 : 0;
2107 var centerToReference
= endDiff
/ 2 - startDiff
/ 2; // Make sure the arrow doesn't overflow the popper if the center point is
2108 // outside of the popper bounds
2110 var min
= paddingObject
[minProp
];
2111 var max
= clientSize
- arrowRect
[len
] - paddingObject
[maxProp
];
2112 var center
= clientSize
/ 2 - arrowRect
[len
] / 2 + centerToReference
;
2113 var offset
= within(min
, center
, max
); // Prevents breaking syntax highlighting...
2115 var axisProp
= axis
;
2116 state
.modifiersData
[name
] = (_state
$modifiersData
$ = {}, _state
$modifiersData
$[axisProp
] = offset
, _state
$modifiersData
$.centerOffset
= offset
- center
, _state
$modifiersData
$);
2119 function effect
$1(_ref2
) {
2120 var state
= _ref2
.state
,
2121 options
= _ref2
.options
;
2122 var _options
$element
= options
.element
,
2123 arrowElement
= _options
$element
=== void 0 ? '[data-popper-arrow]' : _options
$element
;
2125 if (arrowElement
== null) {
2130 if (typeof arrowElement
=== 'string') {
2131 arrowElement
= state
.elements
.popper
.querySelector(arrowElement
);
2133 if (!arrowElement
) {
2138 if (!contains(state
.elements
.popper
, arrowElement
)) {
2142 state
.elements
.arrow
= arrowElement
;
2143 } // eslint-disable-next-line import/no-unused-modules
2152 requires: ['popperOffsets'],
2153 requiresIfExists: ['preventOverflow']
2156 function getVariation(placement
) {
2157 return placement
.split('-')[1];
2165 }; // Round the offsets to the nearest suitable subpixel based on the DPR.
2166 // Zooming can change the DPR, but it seems to report a value that will
2167 // cleanly divide the values into the appropriate subpixels.
2169 function roundOffsetsByDPR(_ref
, win
) {
2172 var dpr
= win
.devicePixelRatio
|| 1;
2174 x: round(x
* dpr
) / dpr
|| 0,
2175 y: round(y
* dpr
) / dpr
|| 0
2179 function mapToStyles(_ref2
) {
2180 var _Object
$assign2
;
2182 var popper
= _ref2
.popper
,
2183 popperRect
= _ref2
.popperRect
,
2184 placement
= _ref2
.placement
,
2185 variation
= _ref2
.variation
,
2186 offsets
= _ref2
.offsets
,
2187 position
= _ref2
.position
,
2188 gpuAcceleration
= _ref2
.gpuAcceleration
,
2189 adaptive
= _ref2
.adaptive
,
2190 roundOffsets
= _ref2
.roundOffsets
,
2191 isFixed
= _ref2
.isFixed
;
2192 var _offsets
$x
= offsets
.x
,
2193 x
= _offsets
$x
=== void 0 ? 0 : _offsets
$x
,
2194 _offsets
$y
= offsets
.y
,
2195 y
= _offsets
$y
=== void 0 ? 0 : _offsets
$y
;
2197 var _ref3
= typeof roundOffsets
=== 'function' ? roundOffsets({
2207 var hasX
= offsets
.hasOwnProperty('x');
2208 var hasY
= offsets
.hasOwnProperty('y');
2214 var offsetParent
= getOffsetParent(popper
);
2215 var heightProp
= 'clientHeight';
2216 var widthProp
= 'clientWidth';
2218 if (offsetParent
=== getWindow(popper
)) {
2219 offsetParent
= getDocumentElement(popper
);
2221 if (getComputedStyle
$1(offsetParent
).position
!== 'static' && position
=== 'absolute') {
2222 heightProp
= 'scrollHeight';
2223 widthProp
= 'scrollWidth';
2225 } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it
2228 offsetParent
= offsetParent
;
2230 if (placement
=== top
|| (placement
=== left
|| placement
=== right
) && variation
=== end
) {
2232 var offsetY
= isFixed
&& offsetParent
=== win
&& win
.visualViewport
? win
.visualViewport
.height : // $FlowFixMe[prop-missing]
2233 offsetParent
[heightProp
];
2234 y
-= offsetY
- popperRect
.height
;
2235 y
*= gpuAcceleration
? 1 : -1;
2238 if (placement
=== left
|| (placement
=== top
|| placement
=== bottom
) && variation
=== end
) {
2240 var offsetX
= isFixed
&& offsetParent
=== win
&& win
.visualViewport
? win
.visualViewport
.width : // $FlowFixMe[prop-missing]
2241 offsetParent
[widthProp
];
2242 x
-= offsetX
- popperRect
.width
;
2243 x
*= gpuAcceleration
? 1 : -1;
2247 var commonStyles
= Object
.assign({
2249 }, adaptive
&& unsetSides
);
2251 var _ref4
= roundOffsets
=== true ? roundOffsetsByDPR({
2254 }, getWindow(popper
)) : {
2262 if (gpuAcceleration
) {
2265 return Object
.assign({}, commonStyles
, (_Object
$assign
= {}, _Object
$assign
[sideY
] = hasY
? '0' : '', _Object
$assign
[sideX
] = hasX
? '0' : '', _Object
$assign
.transform
= (win
.devicePixelRatio
|| 1) <= 1 ? "translate(" + x
+ "px, " + y
+ "px)" : "translate3d(" + x
+ "px, " + y
+ "px, 0)", _Object
$assign
));
2268 return Object
.assign({}, commonStyles
, (_Object
$assign2
= {}, _Object
$assign2
[sideY
] = hasY
? y
+ "px" : '', _Object
$assign2
[sideX
] = hasX
? x
+ "px" : '', _Object
$assign2
.transform
= '', _Object
$assign2
));
2271 function computeStyles(_ref5
) {
2272 var state
= _ref5
.state
,
2273 options
= _ref5
.options
;
2274 var _options
$gpuAccelerat
= options
.gpuAcceleration
,
2275 gpuAcceleration
= _options
$gpuAccelerat
=== void 0 ? true : _options
$gpuAccelerat
,
2276 _options
$adaptive
= options
.adaptive
,
2277 adaptive
= _options
$adaptive
=== void 0 ? true : _options
$adaptive
,
2278 _options
$roundOffsets
= options
.roundOffsets
,
2279 roundOffsets
= _options
$roundOffsets
=== void 0 ? true : _options
$roundOffsets
;
2280 var commonStyles
= {
2281 placement: getBasePlacement(state
.placement
),
2282 variation: getVariation(state
.placement
),
2283 popper: state
.elements
.popper
,
2284 popperRect: state
.rects
.popper
,
2285 gpuAcceleration: gpuAcceleration
,
2286 isFixed: state
.options
.strategy
=== 'fixed'
2289 if (state
.modifiersData
.popperOffsets
!= null) {
2290 state
.styles
.popper
= Object
.assign({}, state
.styles
.popper
, mapToStyles(Object
.assign({}, commonStyles
, {
2291 offsets: state
.modifiersData
.popperOffsets
,
2292 position: state
.options
.strategy
,
2294 roundOffsets: roundOffsets
2298 if (state
.modifiersData
.arrow
!= null) {
2299 state
.styles
.arrow
= Object
.assign({}, state
.styles
.arrow
, mapToStyles(Object
.assign({}, commonStyles
, {
2300 offsets: state
.modifiersData
.arrow
,
2301 position: 'absolute',
2303 roundOffsets: roundOffsets
2307 state
.attributes
.popper
= Object
.assign({}, state
.attributes
.popper
, {
2308 'data-popper-placement': state
.placement
2310 } // eslint-disable-next-line import/no-unused-modules
2313 const computeStyles
$1 = {
2314 name: 'computeStyles',
2316 phase: 'beforeWrite',
2325 function effect(_ref
) {
2326 var state
= _ref
.state
,
2327 instance
= _ref
.instance
,
2328 options
= _ref
.options
;
2329 var _options
$scroll
= options
.scroll
,
2330 scroll
= _options
$scroll
=== void 0 ? true : _options
$scroll
,
2331 _options
$resize
= options
.resize
,
2332 resize
= _options
$resize
=== void 0 ? true : _options
$resize
;
2333 var window
= getWindow(state
.elements
.popper
);
2334 var scrollParents
= [].concat(state
.scrollParents
.reference
, state
.scrollParents
.popper
);
2337 scrollParents
.forEach(function (scrollParent
) {
2338 scrollParent
.addEventListener('scroll', instance
.update
, passive
);
2343 window
.addEventListener('resize', instance
.update
, passive
);
2346 return function () {
2348 scrollParents
.forEach(function (scrollParent
) {
2349 scrollParent
.removeEventListener('scroll', instance
.update
, passive
);
2354 window
.removeEventListener('resize', instance
.update
, passive
);
2357 } // eslint-disable-next-line import/no-unused-modules
2360 const eventListeners
= {
2361 name: 'eventListeners',
2364 fn: function fn() {},
2375 function getOppositePlacement(placement
) {
2376 return placement
.replace(/left|right|bottom|top/g, function (matched
) {
2377 return hash
$1[matched
];
2385 function getOppositeVariationPlacement(placement
) {
2386 return placement
.replace(/start|end/g, function (matched
) {
2387 return hash
[matched
];
2391 function getWindowScroll(node
) {
2392 var win
= getWindow(node
);
2393 var scrollLeft
= win
.pageXOffset
;
2394 var scrollTop
= win
.pageYOffset
;
2396 scrollLeft: scrollLeft
,
2397 scrollTop: scrollTop
2401 function getWindowScrollBarX(element
) {
2402 // If <html> has a CSS width greater than the viewport, then this will be
2403 // incorrect for RTL.
2404 // Popper 1 is broken in this case and never had a bug report so let's assume
2405 // it's not an issue. I don't think anyone ever specifies width on <html>
2407 // Browsers where the left scrollbar doesn't cause an issue report `0` for
2408 // this (e.g. Edge 2019, IE11, Safari)
2409 return getBoundingClientRect(getDocumentElement(element
)).left
+ getWindowScroll(element
).scrollLeft
;
2412 function getViewportRect(element
, strategy
) {
2413 var win
= getWindow(element
);
2414 var html
= getDocumentElement(element
);
2415 var visualViewport
= win
.visualViewport
;
2416 var width
= html
.clientWidth
;
2417 var height
= html
.clientHeight
;
2421 if (visualViewport
) {
2422 width
= visualViewport
.width
;
2423 height
= visualViewport
.height
;
2424 var layoutViewport
= isLayoutViewport();
2426 if (layoutViewport
|| !layoutViewport
&& strategy
=== 'fixed') {
2427 x
= visualViewport
.offsetLeft
;
2428 y
= visualViewport
.offsetTop
;
2435 x: x
+ getWindowScrollBarX(element
),
2440 // of the `<html>` and `<body>` rect bounds if horizontally scrollable
2442 function getDocumentRect(element
) {
2443 var _element
$ownerDocumen
;
2445 var html
= getDocumentElement(element
);
2446 var winScroll
= getWindowScroll(element
);
2447 var body
= (_element
$ownerDocumen
= element
.ownerDocument
) == null ? void 0 : _element
$ownerDocumen
.body
;
2448 var width
= max(html
.scrollWidth
, html
.clientWidth
, body
? body
.scrollWidth : 0, body
? body
.clientWidth : 0);
2449 var height
= max(html
.scrollHeight
, html
.clientHeight
, body
? body
.scrollHeight : 0, body
? body
.clientHeight : 0);
2450 var x
= -winScroll
.scrollLeft
+ getWindowScrollBarX(element
);
2451 var y
= -winScroll
.scrollTop
;
2453 if (getComputedStyle
$1(body
|| html
).direction
=== 'rtl') {
2454 x
+= max(html
.clientWidth
, body
? body
.clientWidth : 0) - width
;
2465 function isScrollParent(element
) {
2466 // Firefox wants us to check `-x` and `-y` variations as well
2467 var _getComputedStyle
= getComputedStyle
$1(element
),
2468 overflow
= _getComputedStyle
.overflow
,
2469 overflowX
= _getComputedStyle
.overflowX
,
2470 overflowY
= _getComputedStyle
.overflowY
;
2472 return /auto|scroll|overlay|hidden/.test(overflow
+ overflowY
+ overflowX
);
2475 function getScrollParent(node
) {
2476 if (['html', 'body', '#document'].indexOf(getNodeName(node
)) >= 0) {
2477 // $FlowFixMe[incompatible-return]: assume body is always available
2478 return node
.ownerDocument
.body
;
2481 if (isHTMLElement(node
) && isScrollParent(node
)) {
2485 return getScrollParent(getParentNode(node
));
2489 given a DOM element, return the list of all scroll parents, up the list of ancesors
2490 until we get to the top window object. This list is what we attach scroll listeners
2491 to, because if any of these parent elements scroll, we'll need to re-calculate the
2492 reference element's position.
2495 function listScrollParents(element
, list
) {
2496 var _element
$ownerDocumen
;
2498 if (list
=== void 0) {
2502 var scrollParent
= getScrollParent(element
);
2503 var isBody
= scrollParent
=== ((_element
$ownerDocumen
= element
.ownerDocument
) == null ? void 0 : _element
$ownerDocumen
.body
);
2504 var win
= getWindow(scrollParent
);
2505 var target
= isBody
? [win
].concat(win
.visualViewport
|| [], isScrollParent(scrollParent
) ? scrollParent : []) : scrollParent
;
2506 var updatedList
= list
.concat(target
);
2507 return isBody
? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
2508 updatedList
.concat(listScrollParents(getParentNode(target
)));
2511 function rectToClientRect(rect
) {
2512 return Object
.assign({}, rect
, {
2515 right: rect
.x
+ rect
.width
,
2516 bottom: rect
.y
+ rect
.height
2520 function getInnerBoundingClientRect(element
, strategy
) {
2521 var rect
= getBoundingClientRect(element
, false, strategy
=== 'fixed');
2522 rect
.top
= rect
.top
+ element
.clientTop
;
2523 rect
.left
= rect
.left
+ element
.clientLeft
;
2524 rect
.bottom
= rect
.top
+ element
.clientHeight
;
2525 rect
.right
= rect
.left
+ element
.clientWidth
;
2526 rect
.width
= element
.clientWidth
;
2527 rect
.height
= element
.clientHeight
;
2533 function getClientRectFromMixedType(element
, clippingParent
, strategy
) {
2534 return clippingParent
=== viewport
? rectToClientRect(getViewportRect(element
, strategy
)) : isElement(clippingParent
) ? getInnerBoundingClientRect(clippingParent
, strategy
) : rectToClientRect(getDocumentRect(getDocumentElement(element
)));
2535 } // A "clipping parent" is an overflowable container with the characteristic of
2536 // clipping (or hiding) overflowing elements with a position different from
2540 function getClippingParents(element
) {
2541 var clippingParents
= listScrollParents(getParentNode(element
));
2542 var canEscapeClipping
= ['absolute', 'fixed'].indexOf(getComputedStyle
$1(element
).position
) >= 0;
2543 var clipperElement
= canEscapeClipping
&& isHTMLElement(element
) ? getOffsetParent(element
) : element
;
2545 if (!isElement(clipperElement
)) {
2547 } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414
2550 return clippingParents
.filter(function (clippingParent
) {
2551 return isElement(clippingParent
) && contains(clippingParent
, clipperElement
) && getNodeName(clippingParent
) !== 'body';
2553 } // Gets the maximum area that the element is visible in due to any number of
2557 function getClippingRect(element
, boundary
, rootBoundary
, strategy
) {
2558 var mainClippingParents
= boundary
=== 'clippingParents' ? getClippingParents(element
) : [].concat(boundary
);
2559 var clippingParents
= [].concat(mainClippingParents
, [rootBoundary
]);
2560 var firstClippingParent
= clippingParents
[0];
2561 var clippingRect
= clippingParents
.reduce(function (accRect
, clippingParent
) {
2562 var rect
= getClientRectFromMixedType(element
, clippingParent
, strategy
);
2563 accRect
.top
= max(rect
.top
, accRect
.top
);
2564 accRect
.right
= min(rect
.right
, accRect
.right
);
2565 accRect
.bottom
= min(rect
.bottom
, accRect
.bottom
);
2566 accRect
.left
= max(rect
.left
, accRect
.left
);
2568 }, getClientRectFromMixedType(element
, firstClippingParent
, strategy
));
2569 clippingRect
.width
= clippingRect
.right
- clippingRect
.left
;
2570 clippingRect
.height
= clippingRect
.bottom
- clippingRect
.top
;
2571 clippingRect
.x
= clippingRect
.left
;
2572 clippingRect
.y
= clippingRect
.top
;
2573 return clippingRect
;
2576 function computeOffsets(_ref
) {
2577 var reference
= _ref
.reference
,
2578 element
= _ref
.element
,
2579 placement
= _ref
.placement
;
2580 var basePlacement
= placement
? getBasePlacement(placement
) : null;
2581 var variation
= placement
? getVariation(placement
) : null;
2582 var commonX
= reference
.x
+ reference
.width
/ 2 - element
.width
/ 2;
2583 var commonY
= reference
.y
+ reference
.height
/ 2 - element
.height
/ 2;
2586 switch (basePlacement
) {
2590 y: reference
.y
- element
.height
2597 y: reference
.y
+ reference
.height
2603 x: reference
.x
+ reference
.width
,
2610 x: reference
.x
- element
.width
,
2622 var mainAxis
= basePlacement
? getMainAxisFromPlacement(basePlacement
) : null;
2624 if (mainAxis
!= null) {
2625 var len
= mainAxis
=== 'y' ? 'height' : 'width';
2627 switch (variation
) {
2629 offsets
[mainAxis
] = offsets
[mainAxis
] - (reference
[len
] / 2 - element
[len
] / 2);
2633 offsets
[mainAxis
] = offsets
[mainAxis
] + (reference
[len
] / 2 - element
[len
] / 2);
2641 function detectOverflow(state
, options
) {
2642 if (options
=== void 0) {
2646 var _options
= options
,
2647 _options
$placement
= _options
.placement
,
2648 placement
= _options
$placement
=== void 0 ? state
.placement : _options
$placement
,
2649 _options
$strategy
= _options
.strategy
,
2650 strategy
= _options
$strategy
=== void 0 ? state
.strategy : _options
$strategy
,
2651 _options
$boundary
= _options
.boundary
,
2652 boundary
= _options
$boundary
=== void 0 ? clippingParents : _options
$boundary
,
2653 _options
$rootBoundary
= _options
.rootBoundary
,
2654 rootBoundary
= _options
$rootBoundary
=== void 0 ? viewport : _options
$rootBoundary
,
2655 _options
$elementConte
= _options
.elementContext
,
2656 elementContext
= _options
$elementConte
=== void 0 ? popper : _options
$elementConte
,
2657 _options
$altBoundary
= _options
.altBoundary
,
2658 altBoundary
= _options
$altBoundary
=== void 0 ? false : _options
$altBoundary
,
2659 _options
$padding
= _options
.padding
,
2660 padding
= _options
$padding
=== void 0 ? 0 : _options
$padding
;
2661 var paddingObject
= mergePaddingObject(typeof padding
!== 'number' ? padding : expandToHashMap(padding
, basePlacements
));
2662 var altContext
= elementContext
=== popper
? reference : popper
;
2663 var popperRect
= state
.rects
.popper
;
2664 var element
= state
.elements
[altBoundary
? altContext : elementContext
];
2665 var clippingClientRect
= getClippingRect(isElement(element
) ? element : element
.contextElement
|| getDocumentElement(state
.elements
.popper
), boundary
, rootBoundary
, strategy
);
2666 var referenceClientRect
= getBoundingClientRect(state
.elements
.reference
);
2667 var popperOffsets
= computeOffsets({
2668 reference: referenceClientRect
,
2669 element: popperRect
,
2670 strategy: 'absolute',
2671 placement: placement
2673 var popperClientRect
= rectToClientRect(Object
.assign({}, popperRect
, popperOffsets
));
2674 var elementClientRect
= elementContext
=== popper
? popperClientRect : referenceClientRect
; // positive = overflowing the clipping rect
2675 // 0 or negative = within the clipping rect
2677 var overflowOffsets
= {
2678 top: clippingClientRect
.top
- elementClientRect
.top
+ paddingObject
.top
,
2679 bottom: elementClientRect
.bottom
- clippingClientRect
.bottom
+ paddingObject
.bottom
,
2680 left: clippingClientRect
.left
- elementClientRect
.left
+ paddingObject
.left
,
2681 right: elementClientRect
.right
- clippingClientRect
.right
+ paddingObject
.right
2683 var offsetData
= state
.modifiersData
.offset
; // Offsets can be applied only to the popper element
2685 if (elementContext
=== popper
&& offsetData
) {
2686 var offset
= offsetData
[placement
];
2687 Object
.keys(overflowOffsets
).forEach(function (key
) {
2688 var multiply
= [right
, bottom
].indexOf(key
) >= 0 ? 1 : -1;
2689 var axis
= [top
, bottom
].indexOf(key
) >= 0 ? 'y' : 'x';
2690 overflowOffsets
[key
] += offset
[axis
] * multiply
;
2694 return overflowOffsets
;
2697 function computeAutoPlacement(state
, options
) {
2698 if (options
=== void 0) {
2702 var _options
= options
,
2703 placement
= _options
.placement
,
2704 boundary
= _options
.boundary
,
2705 rootBoundary
= _options
.rootBoundary
,
2706 padding
= _options
.padding
,
2707 flipVariations
= _options
.flipVariations
,
2708 _options
$allowedAutoP
= _options
.allowedAutoPlacements
,
2709 allowedAutoPlacements
= _options
$allowedAutoP
=== void 0 ? placements : _options
$allowedAutoP
;
2710 var variation
= getVariation(placement
);
2711 var placements
$1 = variation
? flipVariations
? variationPlacements : variationPlacements
.filter(function (placement
) {
2712 return getVariation(placement
) === variation
;
2713 }) : basePlacements
;
2714 var allowedPlacements
= placements
$1.filter(function (placement
) {
2715 return allowedAutoPlacements
.indexOf(placement
) >= 0;
2718 if (allowedPlacements
.length
=== 0) {
2719 allowedPlacements
= placements
$1;
2720 } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...
2723 var overflows
= allowedPlacements
.reduce(function (acc
, placement
) {
2724 acc
[placement
] = detectOverflow(state
, {
2725 placement: placement
,
2727 rootBoundary: rootBoundary
,
2729 })[getBasePlacement(placement
)];
2732 return Object
.keys(overflows
).sort(function (a
, b
) {
2733 return overflows
[a
] - overflows
[b
];
2737 function getExpandedFallbackPlacements(placement
) {
2738 if (getBasePlacement(placement
) === auto
) {
2742 var oppositePlacement
= getOppositePlacement(placement
);
2743 return [getOppositeVariationPlacement(placement
), oppositePlacement
, getOppositeVariationPlacement(oppositePlacement
)];
2746 function flip(_ref
) {
2747 var state
= _ref
.state
,
2748 options
= _ref
.options
,
2751 if (state
.modifiersData
[name
]._skip
) {
2755 var _options
$mainAxis
= options
.mainAxis
,
2756 checkMainAxis
= _options
$mainAxis
=== void 0 ? true : _options
$mainAxis
,
2757 _options
$altAxis
= options
.altAxis
,
2758 checkAltAxis
= _options
$altAxis
=== void 0 ? true : _options
$altAxis
,
2759 specifiedFallbackPlacements
= options
.fallbackPlacements
,
2760 padding
= options
.padding
,
2761 boundary
= options
.boundary
,
2762 rootBoundary
= options
.rootBoundary
,
2763 altBoundary
= options
.altBoundary
,
2764 _options
$flipVariatio
= options
.flipVariations
,
2765 flipVariations
= _options
$flipVariatio
=== void 0 ? true : _options
$flipVariatio
,
2766 allowedAutoPlacements
= options
.allowedAutoPlacements
;
2767 var preferredPlacement
= state
.options
.placement
;
2768 var basePlacement
= getBasePlacement(preferredPlacement
);
2769 var isBasePlacement
= basePlacement
=== preferredPlacement
;
2770 var fallbackPlacements
= specifiedFallbackPlacements
|| (isBasePlacement
|| !flipVariations
? [getOppositePlacement(preferredPlacement
)] : getExpandedFallbackPlacements(preferredPlacement
));
2771 var placements
= [preferredPlacement
].concat(fallbackPlacements
).reduce(function (acc
, placement
) {
2772 return acc
.concat(getBasePlacement(placement
) === auto
? computeAutoPlacement(state
, {
2773 placement: placement
,
2775 rootBoundary: rootBoundary
,
2777 flipVariations: flipVariations
,
2778 allowedAutoPlacements: allowedAutoPlacements
2781 var referenceRect
= state
.rects
.reference
;
2782 var popperRect
= state
.rects
.popper
;
2783 var checksMap
= new Map();
2784 var makeFallbackChecks
= true;
2785 var firstFittingPlacement
= placements
[0];
2787 for (var i
= 0; i
< placements
.length
; i
++) {
2788 var placement
= placements
[i
];
2790 var _basePlacement
= getBasePlacement(placement
);
2792 var isStartVariation
= getVariation(placement
) === start
;
2793 var isVertical
= [top
, bottom
].indexOf(_basePlacement
) >= 0;
2794 var len
= isVertical
? 'width' : 'height';
2795 var overflow
= detectOverflow(state
, {
2796 placement: placement
,
2798 rootBoundary: rootBoundary
,
2799 altBoundary: altBoundary
,
2802 var mainVariationSide
= isVertical
? isStartVariation
? right : left : isStartVariation
? bottom : top
;
2804 if (referenceRect
[len
] > popperRect
[len
]) {
2805 mainVariationSide
= getOppositePlacement(mainVariationSide
);
2808 var altVariationSide
= getOppositePlacement(mainVariationSide
);
2811 if (checkMainAxis
) {
2812 checks
.push(overflow
[_basePlacement
] <= 0);
2816 checks
.push(overflow
[mainVariationSide
] <= 0, overflow
[altVariationSide
] <= 0);
2819 if (checks
.every(function (check
) {
2822 firstFittingPlacement
= placement
;
2823 makeFallbackChecks
= false;
2827 checksMap
.set(placement
, checks
);
2830 if (makeFallbackChecks
) {
2831 // `2` may be desired in some cases – research later
2832 var numberOfChecks
= flipVariations
? 3 : 1;
2834 var _loop
= function _loop(_i
) {
2835 var fittingPlacement
= placements
.find(function (placement
) {
2836 var checks
= checksMap
.get(placement
);
2839 return checks
.slice(0, _i
).every(function (check
) {
2845 if (fittingPlacement
) {
2846 firstFittingPlacement
= fittingPlacement
;
2851 for (var _i
= numberOfChecks
; _i
> 0; _i
--) {
2852 var _ret
= _loop(_i
);
2854 if (_ret
=== "break") break;
2858 if (state
.placement
!== firstFittingPlacement
) {
2859 state
.modifiersData
[name
]._skip
= true;
2860 state
.placement
= firstFittingPlacement
;
2863 } // eslint-disable-next-line import/no-unused-modules
2871 requiresIfExists: ['offset'],
2877 function getSideOffsets(overflow
, rect
, preventedOffsets
) {
2878 if (preventedOffsets
=== void 0) {
2879 preventedOffsets
= {
2886 top: overflow
.top
- rect
.height
- preventedOffsets
.y
,
2887 right: overflow
.right
- rect
.width
+ preventedOffsets
.x
,
2888 bottom: overflow
.bottom
- rect
.height
+ preventedOffsets
.y
,
2889 left: overflow
.left
- rect
.width
- preventedOffsets
.x
2893 function isAnySideFullyClipped(overflow
) {
2894 return [top
, right
, bottom
, left
].some(function (side
) {
2895 return overflow
[side
] >= 0;
2899 function hide(_ref
) {
2900 var state
= _ref
.state
,
2902 var referenceRect
= state
.rects
.reference
;
2903 var popperRect
= state
.rects
.popper
;
2904 var preventedOffsets
= state
.modifiersData
.preventOverflow
;
2905 var referenceOverflow
= detectOverflow(state
, {
2906 elementContext: 'reference'
2908 var popperAltOverflow
= detectOverflow(state
, {
2911 var referenceClippingOffsets
= getSideOffsets(referenceOverflow
, referenceRect
);
2912 var popperEscapeOffsets
= getSideOffsets(popperAltOverflow
, popperRect
, preventedOffsets
);
2913 var isReferenceHidden
= isAnySideFullyClipped(referenceClippingOffsets
);
2914 var hasPopperEscaped
= isAnySideFullyClipped(popperEscapeOffsets
);
2915 state
.modifiersData
[name
] = {
2916 referenceClippingOffsets: referenceClippingOffsets
,
2917 popperEscapeOffsets: popperEscapeOffsets
,
2918 isReferenceHidden: isReferenceHidden
,
2919 hasPopperEscaped: hasPopperEscaped
2921 state
.attributes
.popper
= Object
.assign({}, state
.attributes
.popper
, {
2922 'data-popper-reference-hidden': isReferenceHidden
,
2923 'data-popper-escaped': hasPopperEscaped
2925 } // eslint-disable-next-line import/no-unused-modules
2932 requiresIfExists: ['preventOverflow'],
2936 function distanceAndSkiddingToXY(placement
, rects
, offset
) {
2937 var basePlacement
= getBasePlacement(placement
);
2938 var invertDistance
= [left
, top
].indexOf(basePlacement
) >= 0 ? -1 : 1;
2940 var _ref
= typeof offset
=== 'function' ? offset(Object
.assign({}, rects
, {
2941 placement: placement
2946 skidding
= skidding
|| 0;
2947 distance
= (distance
|| 0) * invertDistance
;
2948 return [left
, right
].indexOf(basePlacement
) >= 0 ? {
2957 function offset(_ref2
) {
2958 var state
= _ref2
.state
,
2959 options
= _ref2
.options
,
2961 var _options
$offset
= options
.offset
,
2962 offset
= _options
$offset
=== void 0 ? [0, 0] : _options
$offset
;
2963 var data
= placements
.reduce(function (acc
, placement
) {
2964 acc
[placement
] = distanceAndSkiddingToXY(placement
, state
.rects
, offset
);
2967 var _data
$state
$placement
= data
[state
.placement
],
2968 x
= _data
$state
$placement
.x
,
2969 y
= _data
$state
$placement
.y
;
2971 if (state
.modifiersData
.popperOffsets
!= null) {
2972 state
.modifiersData
.popperOffsets
.x
+= x
;
2973 state
.modifiersData
.popperOffsets
.y
+= y
;
2976 state
.modifiersData
[name
] = data
;
2977 } // eslint-disable-next-line import/no-unused-modules
2984 requires: ['popperOffsets'],
2988 function popperOffsets(_ref
) {
2989 var state
= _ref
.state
,
2991 // Offsets are the actual position the popper needs to have to be
2992 // properly positioned near its reference element
2993 // This is the most basic placement, and will be adjusted by
2994 // the modifiers in the next step
2995 state
.modifiersData
[name
] = computeOffsets({
2996 reference: state
.rects
.reference
,
2997 element: state
.rects
.popper
,
2998 strategy: 'absolute',
2999 placement: state
.placement
3001 } // eslint-disable-next-line import/no-unused-modules
3004 const popperOffsets
$1 = {
3005 name: 'popperOffsets',
3012 function getAltAxis(axis
) {
3013 return axis
=== 'x' ? 'y' : 'x';
3016 function preventOverflow(_ref
) {
3017 var state
= _ref
.state
,
3018 options
= _ref
.options
,
3020 var _options
$mainAxis
= options
.mainAxis
,
3021 checkMainAxis
= _options
$mainAxis
=== void 0 ? true : _options
$mainAxis
,
3022 _options
$altAxis
= options
.altAxis
,
3023 checkAltAxis
= _options
$altAxis
=== void 0 ? false : _options
$altAxis
,
3024 boundary
= options
.boundary
,
3025 rootBoundary
= options
.rootBoundary
,
3026 altBoundary
= options
.altBoundary
,
3027 padding
= options
.padding
,
3028 _options
$tether
= options
.tether
,
3029 tether
= _options
$tether
=== void 0 ? true : _options
$tether
,
3030 _options
$tetherOffset
= options
.tetherOffset
,
3031 tetherOffset
= _options
$tetherOffset
=== void 0 ? 0 : _options
$tetherOffset
;
3032 var overflow
= detectOverflow(state
, {
3034 rootBoundary: rootBoundary
,
3036 altBoundary: altBoundary
3038 var basePlacement
= getBasePlacement(state
.placement
);
3039 var variation
= getVariation(state
.placement
);
3040 var isBasePlacement
= !variation
;
3041 var mainAxis
= getMainAxisFromPlacement(basePlacement
);
3042 var altAxis
= getAltAxis(mainAxis
);
3043 var popperOffsets
= state
.modifiersData
.popperOffsets
;
3044 var referenceRect
= state
.rects
.reference
;
3045 var popperRect
= state
.rects
.popper
;
3046 var tetherOffsetValue
= typeof tetherOffset
=== 'function' ? tetherOffset(Object
.assign({}, state
.rects
, {
3047 placement: state
.placement
3049 var normalizedTetherOffsetValue
= typeof tetherOffsetValue
=== 'number' ? {
3050 mainAxis: tetherOffsetValue
,
3051 altAxis: tetherOffsetValue
3055 }, tetherOffsetValue
);
3056 var offsetModifierState
= state
.modifiersData
.offset
? state
.modifiersData
.offset
[state
.placement
] : null;
3062 if (!popperOffsets
) {
3066 if (checkMainAxis
) {
3067 var _offsetModifierState
$;
3069 var mainSide
= mainAxis
=== 'y' ? top : left
;
3070 var altSide
= mainAxis
=== 'y' ? bottom : right
;
3071 var len
= mainAxis
=== 'y' ? 'height' : 'width';
3072 var offset
= popperOffsets
[mainAxis
];
3073 var min
$1 = offset
+ overflow
[mainSide
];
3074 var max
$1 = offset
- overflow
[altSide
];
3075 var additive
= tether
? -popperRect
[len
] / 2 : 0;
3076 var minLen
= variation
=== start
? referenceRect
[len
] : popperRect
[len
];
3077 var maxLen
= variation
=== start
? -popperRect
[len
] : -referenceRect
[len
]; // We need to include the arrow in the calculation so the arrow doesn't go
3078 // outside the reference bounds
3080 var arrowElement
= state
.elements
.arrow
;
3081 var arrowRect
= tether
&& arrowElement
? getLayoutRect(arrowElement
) : {
3085 var arrowPaddingObject
= state
.modifiersData
['arrow#persistent'] ? state
.modifiersData
['arrow#persistent'].padding : getFreshSideObject();
3086 var arrowPaddingMin
= arrowPaddingObject
[mainSide
];
3087 var arrowPaddingMax
= arrowPaddingObject
[altSide
]; // If the reference length is smaller than the arrow length, we don't want
3088 // to include its full size in the calculation. If the reference is small
3089 // and near the edge of a boundary, the popper can overflow even if the
3090 // reference is not overflowing as well (e.g. virtual elements with no
3093 var arrowLen
= within(0, referenceRect
[len
], arrowRect
[len
]);
3094 var minOffset
= isBasePlacement
? referenceRect
[len
] / 2 - additive
- arrowLen
- arrowPaddingMin
- normalizedTetherOffsetValue
.mainAxis : minLen
- arrowLen
- arrowPaddingMin
- normalizedTetherOffsetValue
.mainAxis
;
3095 var maxOffset
= isBasePlacement
? -referenceRect
[len
] / 2 + additive
+ arrowLen
+ arrowPaddingMax
+ normalizedTetherOffsetValue
.mainAxis : maxLen
+ arrowLen
+ arrowPaddingMax
+ normalizedTetherOffsetValue
.mainAxis
;
3096 var arrowOffsetParent
= state
.elements
.arrow
&& getOffsetParent(state
.elements
.arrow
);
3097 var clientOffset
= arrowOffsetParent
? mainAxis
=== 'y' ? arrowOffsetParent
.clientTop
|| 0 : arrowOffsetParent
.clientLeft
|| 0 : 0;
3098 var offsetModifierValue
= (_offsetModifierState
$ = offsetModifierState
== null ? void 0 : offsetModifierState
[mainAxis
]) != null ? _offsetModifierState
$ : 0;
3099 var tetherMin
= offset
+ minOffset
- offsetModifierValue
- clientOffset
;
3100 var tetherMax
= offset
+ maxOffset
- offsetModifierValue
;
3101 var preventedOffset
= within(tether
? min(min
$1, tetherMin
) : min
$1, offset
, tether
? max(max
$1, tetherMax
) : max
$1);
3102 popperOffsets
[mainAxis
] = preventedOffset
;
3103 data
[mainAxis
] = preventedOffset
- offset
;
3107 var _offsetModifierState
$2;
3109 var _mainSide
= mainAxis
=== 'x' ? top : left
;
3111 var _altSide
= mainAxis
=== 'x' ? bottom : right
;
3113 var _offset
= popperOffsets
[altAxis
];
3115 var _len
= altAxis
=== 'y' ? 'height' : 'width';
3117 var _min
= _offset
+ overflow
[_mainSide
];
3119 var _max
= _offset
- overflow
[_altSide
];
3121 var isOriginSide
= [top
, left
].indexOf(basePlacement
) !== -1;
3123 var _offsetModifierValue
= (_offsetModifierState
$2 = offsetModifierState
== null ? void 0 : offsetModifierState
[altAxis
]) != null ? _offsetModifierState
$2 : 0;
3125 var _tetherMin
= isOriginSide
? _min : _offset
- referenceRect
[_len
] - popperRect
[_len
] - _offsetModifierValue
+ normalizedTetherOffsetValue
.altAxis
;
3127 var _tetherMax
= isOriginSide
? _offset
+ referenceRect
[_len
] + popperRect
[_len
] - _offsetModifierValue
- normalizedTetherOffsetValue
.altAxis : _max
;
3129 var _preventedOffset
= tether
&& isOriginSide
? withinMaxClamp(_tetherMin
, _offset
, _tetherMax
) : within(tether
? _tetherMin : _min
, _offset
, tether
? _tetherMax : _max
);
3131 popperOffsets
[altAxis
] = _preventedOffset
;
3132 data
[altAxis
] = _preventedOffset
- _offset
;
3135 state
.modifiersData
[name
] = data
;
3136 } // eslint-disable-next-line import/no-unused-modules
3139 const preventOverflow
$1 = {
3140 name: 'preventOverflow',
3143 fn: preventOverflow
,
3144 requiresIfExists: ['offset']
3147 function getHTMLElementScroll(element
) {
3149 scrollLeft: element
.scrollLeft
,
3150 scrollTop: element
.scrollTop
3154 function getNodeScroll(node
) {
3155 if (node
=== getWindow(node
) || !isHTMLElement(node
)) {
3156 return getWindowScroll(node
);
3158 return getHTMLElementScroll(node
);
3162 function isElementScaled(element
) {
3163 var rect
= element
.getBoundingClientRect();
3164 var scaleX
= round(rect
.width
) / element
.offsetWidth
|| 1;
3165 var scaleY
= round(rect
.height
) / element
.offsetHeight
|| 1;
3166 return scaleX
!== 1 || scaleY
!== 1;
3167 } // Returns the composite rect of an element relative to its offsetParent.
3168 // Composite means it takes into account transforms as well as layout.
3171 function getCompositeRect(elementOrVirtualElement
, offsetParent
, isFixed
) {
3172 if (isFixed
=== void 0) {
3176 var isOffsetParentAnElement
= isHTMLElement(offsetParent
);
3177 var offsetParentIsScaled
= isHTMLElement(offsetParent
) && isElementScaled(offsetParent
);
3178 var documentElement
= getDocumentElement(offsetParent
);
3179 var rect
= getBoundingClientRect(elementOrVirtualElement
, offsetParentIsScaled
, isFixed
);
3189 if (isOffsetParentAnElement
|| !isOffsetParentAnElement
&& !isFixed
) {
3190 if (getNodeName(offsetParent
) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078
3191 isScrollParent(documentElement
)) {
3192 scroll
= getNodeScroll(offsetParent
);
3195 if (isHTMLElement(offsetParent
)) {
3196 offsets
= getBoundingClientRect(offsetParent
, true);
3197 offsets
.x
+= offsetParent
.clientLeft
;
3198 offsets
.y
+= offsetParent
.clientTop
;
3199 } else if (documentElement
) {
3200 offsets
.x
= getWindowScrollBarX(documentElement
);
3205 x: rect
.left
+ scroll
.scrollLeft
- offsets
.x
,
3206 y: rect
.top
+ scroll
.scrollTop
- offsets
.y
,
3212 function order(modifiers
) {
3213 var map
= new Map();
3214 var visited
= new Set();
3216 modifiers
.forEach(function (modifier
) {
3217 map
.set(modifier
.name
, modifier
);
3218 }); // On visiting object, check for its dependencies and visit them recursively
3220 function sort(modifier
) {
3221 visited
.add(modifier
.name
);
3222 var requires
= [].concat(modifier
.requires
|| [], modifier
.requiresIfExists
|| []);
3223 requires
.forEach(function (dep
) {
3224 if (!visited
.has(dep
)) {
3225 var depModifier
= map
.get(dep
);
3232 result
.push(modifier
);
3235 modifiers
.forEach(function (modifier
) {
3236 if (!visited
.has(modifier
.name
)) {
3237 // check for visited object
3244 function orderModifiers(modifiers
) {
3245 // order based on dependencies
3246 var orderedModifiers
= order(modifiers
); // order based on phase
3248 return modifierPhases
.reduce(function (acc
, phase
) {
3249 return acc
.concat(orderedModifiers
.filter(function (modifier
) {
3250 return modifier
.phase
=== phase
;
3255 function debounce(fn
) {
3257 return function () {
3259 pending
= new Promise(function (resolve
) {
3260 Promise
.resolve().then(function () {
3261 pending
= undefined;
3271 function mergeByName(modifiers
) {
3272 var merged
= modifiers
.reduce(function (merged
, current
) {
3273 var existing
= merged
[current
.name
];
3274 merged
[current
.name
] = existing
? Object
.assign({}, existing
, current
, {
3275 options: Object
.assign({}, existing
.options
, current
.options
),
3276 data: Object
.assign({}, existing
.data
, current
.data
)
3279 }, {}); // IE11 does not support Object.values
3281 return Object
.keys(merged
).map(function (key
) {
3286 var DEFAULT_OPTIONS
= {
3287 placement: 'bottom',
3289 strategy: 'absolute'
3292 function areValidElements() {
3293 for (var _len
= arguments
.length
, args
= new Array(_len
), _key
= 0; _key
< _len
; _key
++) {
3294 args
[_key
] = arguments
[_key
];
3297 return !args
.some(function (element
) {
3298 return !(element
&& typeof element
.getBoundingClientRect
=== 'function');
3302 function popperGenerator(generatorOptions
) {
3303 if (generatorOptions
=== void 0) {
3304 generatorOptions
= {};
3307 var _generatorOptions
= generatorOptions
,
3308 _generatorOptions
$def
= _generatorOptions
.defaultModifiers
,
3309 defaultModifiers
= _generatorOptions
$def
=== void 0 ? [] : _generatorOptions
$def
,
3310 _generatorOptions
$def2
= _generatorOptions
.defaultOptions
,
3311 defaultOptions
= _generatorOptions
$def2
=== void 0 ? DEFAULT_OPTIONS : _generatorOptions
$def2
;
3312 return function createPopper(reference
, popper
, options
) {
3313 if (options
=== void 0) {
3314 options
= defaultOptions
;
3318 placement: 'bottom',
3319 orderedModifiers: [],
3320 options: Object
.assign({}, DEFAULT_OPTIONS
, defaultOptions
),
3323 reference: reference
,
3329 var effectCleanupFns
= [];
3330 var isDestroyed
= false;
3333 setOptions: function setOptions(setOptionsAction
) {
3334 var options
= typeof setOptionsAction
=== 'function' ? setOptionsAction(state
.options
) : setOptionsAction
;
3335 cleanupModifierEffects();
3336 state
.options
= Object
.assign({}, defaultOptions
, state
.options
, options
);
3337 state
.scrollParents
= {
3338 reference: isElement(reference
) ? listScrollParents(reference
) : reference
.contextElement
? listScrollParents(reference
.contextElement
) : [],
3339 popper: listScrollParents(popper
)
3340 }; // Orders the modifiers based on their dependencies and `phase`
3343 var orderedModifiers
= orderModifiers(mergeByName([].concat(defaultModifiers
, state
.options
.modifiers
))); // Strip out disabled modifiers
3345 state
.orderedModifiers
= orderedModifiers
.filter(function (m
) {
3348 runModifierEffects();
3349 return instance
.update();
3351 // Sync update – it will always be executed, even if not necessary. This
3352 // is useful for low frequency updates where sync behavior simplifies the
3354 // For high frequency updates (e.g. `resize` and `scroll` events), always
3355 // prefer the async Popper#update method
3356 forceUpdate: function forceUpdate() {
3361 var _state
$elements
= state
.elements
,
3362 reference
= _state
$elements
.reference
,
3363 popper
= _state
$elements
.popper
; // Don't proceed if `reference` or `popper` are not valid elements
3366 if (!areValidElements(reference
, popper
)) {
3368 } // Store the reference and popper rects to be read by modifiers
3372 reference: getCompositeRect(reference
, getOffsetParent(popper
), state
.options
.strategy
=== 'fixed'),
3373 popper: getLayoutRect(popper
)
3374 }; // Modifiers have the ability to reset the current update cycle. The
3375 // most common use case for this is the `flip` modifier changing the
3376 // placement, which then needs to re-run all the modifiers, because the
3377 // logic was previously ran for the previous placement and is therefore
3380 state
.reset
= false;
3381 state
.placement
= state
.options
.placement
; // On each update cycle, the `modifiersData` property for each modifier
3382 // is filled with the initial data specified by the modifier. This means
3383 // it doesn't persist and is fresh on each update.
3384 // To ensure persistent data, use `${name}#persistent`
3386 state
.orderedModifiers
.forEach(function (modifier
) {
3387 return state
.modifiersData
[modifier
.name
] = Object
.assign({}, modifier
.data
);
3390 for (var index
= 0; index
< state
.orderedModifiers
.length
; index
++) {
3391 if (state
.reset
=== true) {
3392 state
.reset
= false;
3397 var _state
$orderedModifie
= state
.orderedModifiers
[index
],
3398 fn
= _state
$orderedModifie
.fn
,
3399 _state
$orderedModifie2
= _state
$orderedModifie
.options
,
3400 _options
= _state
$orderedModifie2
=== void 0 ? {} : _state
$orderedModifie2
,
3401 name
= _state
$orderedModifie
.name
;
3403 if (typeof fn
=== 'function') {
3413 // Async and optimistically optimized update – it will not be executed if
3414 // not necessary (debounced to run at most once-per-tick)
3415 update: debounce(function () {
3416 return new Promise(function (resolve
) {
3417 instance
.forceUpdate();
3421 destroy: function destroy() {
3422 cleanupModifierEffects();
3427 if (!areValidElements(reference
, popper
)) {
3431 instance
.setOptions(options
).then(function (state
) {
3432 if (!isDestroyed
&& options
.onFirstUpdate
) {
3433 options
.onFirstUpdate(state
);
3435 }); // Modifiers have the ability to execute arbitrary code before the first
3436 // update cycle runs. They will be executed in the same order as the update
3437 // cycle. This is useful when a modifier adds some persistent data that
3438 // other modifiers need to use, but the modifier is run after the dependent
3441 function runModifierEffects() {
3442 state
.orderedModifiers
.forEach(function (_ref
) {
3443 var name
= _ref
.name
,
3444 _ref
$options
= _ref
.options
,
3445 options
= _ref
$options
=== void 0 ? {} : _ref
$options
,
3446 effect
= _ref
.effect
;
3448 if (typeof effect
=== 'function') {
3449 var cleanupFn
= effect({
3456 var noopFn
= function noopFn() {};
3458 effectCleanupFns
.push(cleanupFn
|| noopFn
);
3463 function cleanupModifierEffects() {
3464 effectCleanupFns
.forEach(function (fn
) {
3467 effectCleanupFns
= [];
3473 var createPopper
$2 = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules
3475 var defaultModifiers
$1 = [eventListeners
, popperOffsets
$1, computeStyles
$1, applyStyles
$1];
3476 var createPopper
$1 = /*#__PURE__*/popperGenerator({
3477 defaultModifiers: defaultModifiers
$1
3478 }); // eslint-disable-next-line import/no-unused-modules
3480 var defaultModifiers
= [eventListeners
, popperOffsets
$1, computeStyles
$1, applyStyles
$1, offset
$1, flip
$1, preventOverflow
$1, arrow
$1, hide
$1];
3481 var createPopper
= /*#__PURE__*/popperGenerator({
3482 defaultModifiers: defaultModifiers
3483 }); // eslint-disable-next-line import/no-unused-modules
3485 const Popper
= /*#__PURE__*/Object
.freeze(/*#__PURE__*/Object
.defineProperty({
3490 applyStyles: applyStyles
$1,
3499 computeStyles: computeStyles
$1,
3501 createPopperBase: createPopper
$2,
3502 createPopperLite: createPopper
$1,
3515 popperOffsets: popperOffsets
$1,
3516 preventOverflow: preventOverflow
$1,
3522 variationPlacements
,
3525 }, Symbol
.toStringTag
, { value: 'Module' }));
3528 * --------------------------------------------------------------------------
3529 * Bootstrap dropdown.js
3530 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
3531 * --------------------------------------------------------------------------
3539 const NAME
$a
= 'dropdown';
3540 const DATA_KEY
$6 = 'bs.dropdown';
3541 const EVENT_KEY
$6 = `.${DATA_KEY$6}`;
3542 const DATA_API_KEY
$3 = '.data-api';
3543 const ESCAPE_KEY
$2 = 'Escape';
3544 const TAB_KEY
$1 = 'Tab';
3545 const ARROW_UP_KEY
$1 = 'ArrowUp';
3546 const ARROW_DOWN_KEY
$1 = 'ArrowDown';
3547 const RIGHT_MOUSE_BUTTON
= 2; // MouseEvent.button value for the secondary button, usually the right button
3549 const EVENT_HIDE
$5 = `hide${EVENT_KEY$6}`;
3550 const EVENT_HIDDEN
$5 = `hidden${EVENT_KEY$6}`;
3551 const EVENT_SHOW
$5 = `show${EVENT_KEY$6}`;
3552 const EVENT_SHOWN
$5 = `shown${EVENT_KEY$6}`;
3553 const EVENT_CLICK_DATA_API
$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;
3554 const EVENT_KEYDOWN_DATA_API
= `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`;
3555 const EVENT_KEYUP_DATA_API
= `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`;
3556 const CLASS_NAME_SHOW
$6 = 'show';
3557 const CLASS_NAME_DROPUP
= 'dropup';
3558 const CLASS_NAME_DROPEND
= 'dropend';
3559 const CLASS_NAME_DROPSTART
= 'dropstart';
3560 const CLASS_NAME_DROPUP_CENTER
= 'dropup-center';
3561 const CLASS_NAME_DROPDOWN_CENTER
= 'dropdown-center';
3562 const SELECTOR_DATA_TOGGLE
$3 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)';
3563 const SELECTOR_DATA_TOGGLE_SHOWN
= `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`;
3564 const SELECTOR_MENU
= '.dropdown-menu';
3565 const SELECTOR_NAVBAR
= '.navbar';
3566 const SELECTOR_NAVBAR_NAV
= '.navbar-nav';
3567 const SELECTOR_VISIBLE_ITEMS
= '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
3568 const PLACEMENT_TOP
= isRTL() ? 'top-end' : 'top-start';
3569 const PLACEMENT_TOPEND
= isRTL() ? 'top-start' : 'top-end';
3570 const PLACEMENT_BOTTOM
= isRTL() ? 'bottom-end' : 'bottom-start';
3571 const PLACEMENT_BOTTOMEND
= isRTL() ? 'bottom-start' : 'bottom-end';
3572 const PLACEMENT_RIGHT
= isRTL() ? 'left-start' : 'right-start';
3573 const PLACEMENT_LEFT
= isRTL() ? 'right-start' : 'left-start';
3574 const PLACEMENT_TOPCENTER
= 'top';
3575 const PLACEMENT_BOTTOMCENTER
= 'bottom';
3578 boundary: 'clippingParents',
3584 const DefaultType
$9 = {
3585 autoClose: '(boolean|string)',
3586 boundary: '(string|element)',
3588 offset: '(array|string|function)',
3589 popperConfig: '(null|object|function)',
3590 reference: '(string|element|object)'
3597 class Dropdown
extends BaseComponent
{
3598 constructor(element
, config
) {
3599 super(element
, config
);
3600 this._popper
= null;
3601 this._parent
= this._element
.parentNode
; // dropdown wrapper
3602 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
3603 this._menu
= SelectorEngine
.next(this._element
, SELECTOR_MENU
)[0] || SelectorEngine
.prev(this._element
, SELECTOR_MENU
)[0] || SelectorEngine
.findOne(SELECTOR_MENU
, this._parent
);
3604 this._inNavbar
= this._detectNavbar();
3608 static get Default() {
3611 static get DefaultType() {
3612 return DefaultType
$9;
3620 return this._isShown() ? this.hide() : this.show();
3623 if (isDisabled(this._element
) || this._isShown()) {
3626 const relatedTarget
= {
3627 relatedTarget: this._element
3629 const showEvent
= EventHandler
.trigger(this._element
, EVENT_SHOW
$5, relatedTarget
);
3630 if (showEvent
.defaultPrevented
) {
3633 this._createPopper();
3635 // If this is a touch-enabled device we add extra
3636 // empty mouseover listeners to the body's immediate children;
3637 // only needed because of broken event delegation on iOS
3638 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
3639 if ('ontouchstart' in document
.documentElement
&& !this._parent
.closest(SELECTOR_NAVBAR_NAV
)) {
3640 for (const element
of [].concat(...document
.body
.children
)) {
3641 EventHandler
.on(element
, 'mouseover', noop
);
3644 this._element
.focus();
3645 this._element
.setAttribute('aria-expanded', true);
3646 this._menu
.classList
.add(CLASS_NAME_SHOW
$6);
3647 this._element
.classList
.add(CLASS_NAME_SHOW
$6);
3648 EventHandler
.trigger(this._element
, EVENT_SHOWN
$5, relatedTarget
);
3651 if (isDisabled(this._element
) || !this._isShown()) {
3654 const relatedTarget
= {
3655 relatedTarget: this._element
3657 this._completeHide(relatedTarget
);
3661 this._popper
.destroy();
3666 this._inNavbar
= this._detectNavbar();
3668 this._popper
.update();
3673 _completeHide(relatedTarget
) {
3674 const hideEvent
= EventHandler
.trigger(this._element
, EVENT_HIDE
$5, relatedTarget
);
3675 if (hideEvent
.defaultPrevented
) {
3679 // If this is a touch-enabled device we remove the extra
3680 // empty mouseover listeners we added for iOS support
3681 if ('ontouchstart' in document
.documentElement
) {
3682 for (const element
of [].concat(...document
.body
.children
)) {
3683 EventHandler
.off(element
, 'mouseover', noop
);
3687 this._popper
.destroy();
3689 this._menu
.classList
.remove(CLASS_NAME_SHOW
$6);
3690 this._element
.classList
.remove(CLASS_NAME_SHOW
$6);
3691 this._element
.setAttribute('aria-expanded', 'false');
3692 Manipulator
.removeDataAttribute(this._menu
, 'popper');
3693 EventHandler
.trigger(this._element
, EVENT_HIDDEN
$5, relatedTarget
);
3695 _getConfig(config
) {
3696 config
= super._getConfig(config
);
3697 if (typeof config
.reference
=== 'object' && !isElement
$1(config
.reference
) && typeof config
.reference
.getBoundingClientRect
!== 'function') {
3698 // Popper virtual elements require a getBoundingClientRect method
3699 throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);
3704 if (typeof Popper
=== 'undefined') {
3705 throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)');
3707 let referenceElement
= this._element
;
3708 if (this._config
.reference
=== 'parent') {
3709 referenceElement
= this._parent
;
3710 } else if (isElement
$1(this._config
.reference
)) {
3711 referenceElement
= getElement(this._config
.reference
);
3712 } else if (typeof this._config
.reference
=== 'object') {
3713 referenceElement
= this._config
.reference
;
3715 const popperConfig
= this._getPopperConfig();
3716 this._popper
= createPopper(referenceElement
, this._menu
, popperConfig
);
3719 return this._menu
.classList
.contains(CLASS_NAME_SHOW
$6);
3722 const parentDropdown
= this._parent
;
3723 if (parentDropdown
.classList
.contains(CLASS_NAME_DROPEND
)) {
3724 return PLACEMENT_RIGHT
;
3726 if (parentDropdown
.classList
.contains(CLASS_NAME_DROPSTART
)) {
3727 return PLACEMENT_LEFT
;
3729 if (parentDropdown
.classList
.contains(CLASS_NAME_DROPUP_CENTER
)) {
3730 return PLACEMENT_TOPCENTER
;
3732 if (parentDropdown
.classList
.contains(CLASS_NAME_DROPDOWN_CENTER
)) {
3733 return PLACEMENT_BOTTOMCENTER
;
3736 // We need to trim the value because custom properties can also include spaces
3737 const isEnd
= getComputedStyle(this._menu
).getPropertyValue('--bs-position').trim() === 'end';
3738 if (parentDropdown
.classList
.contains(CLASS_NAME_DROPUP
)) {
3739 return isEnd
? PLACEMENT_TOPEND : PLACEMENT_TOP
;
3741 return isEnd
? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM
;
3744 return this._element
.closest(SELECTOR_NAVBAR
) !== null;
3750 if (typeof offset
=== 'string') {
3751 return offset
.split(',').map(value
=> Number
.parseInt(value
, 10));
3753 if (typeof offset
=== 'function') {
3754 return popperData
=> offset(popperData
, this._element
);
3758 _getPopperConfig() {
3759 const defaultBsPopperConfig
= {
3760 placement: this._getPlacement(),
3762 name: 'preventOverflow',
3764 boundary: this._config
.boundary
3769 offset: this._getOffset()
3774 // Disable Popper if we have a static display or Dropdown is in Navbar
3775 if (this._inNavbar
|| this._config
.display
=== 'static') {
3776 Manipulator
.setDataAttribute(this._menu
, 'popper', 'static'); // TODO: v6 remove
3777 defaultBsPopperConfig
.modifiers
= [{
3778 name: 'applyStyles',
3783 ...defaultBsPopperConfig
,
3784 ...execute(this._config
.popperConfig
, [defaultBsPopperConfig
])
3791 const items
= SelectorEngine
.find(SELECTOR_VISIBLE_ITEMS
, this._menu
).filter(element
=> isVisible(element
));
3792 if (!items
.length
) {
3796 // if target isn't included in items (e.g. when expanding the dropdown)
3797 // allow cycling to get the last item in case key equals ARROW_UP_KEY
3798 getNextActiveElement(items
, target
, key
=== ARROW_DOWN_KEY
$1, !items
.includes(target
)).focus();
3802 static jQueryInterface(config
) {
3803 return this.each(function () {
3804 const data
= Dropdown
.getOrCreateInstance(this, config
);
3805 if (typeof config
!== 'string') {
3808 if (typeof data
[config
] === 'undefined') {
3809 throw new TypeError(`No method named "${config}"`);
3814 static clearMenus(event
) {
3815 if (event
.button
=== RIGHT_MOUSE_BUTTON
|| event
.type
=== 'keyup' && event
.key
!== TAB_KEY
$1) {
3818 const openToggles
= SelectorEngine
.find(SELECTOR_DATA_TOGGLE_SHOWN
);
3819 for (const toggle
of openToggles
) {
3820 const context
= Dropdown
.getInstance(toggle
);
3821 if (!context
|| context
._config
.autoClose
=== false) {
3824 const composedPath
= event
.composedPath();
3825 const isMenuTarget
= composedPath
.includes(context
._menu
);
3826 if (composedPath
.includes(context
._element
) || context
._config
.autoClose
=== 'inside' && !isMenuTarget
|| context
._config
.autoClose
=== 'outside' && isMenuTarget
) {
3830 // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
3831 if (context
._menu
.contains(event
.target
) && (event
.type
=== 'keyup' && event
.key
=== TAB_KEY
$1 || /input|select|option|textarea|form/i.test(event
.target
.tagName
))) {
3834 const relatedTarget
= {
3835 relatedTarget: context
._element
3837 if (event
.type
=== 'click') {
3838 relatedTarget
.clickEvent
= event
;
3840 context
._completeHide(relatedTarget
);
3843 static dataApiKeydownHandler(event
) {
3844 // If not an UP | DOWN | ESCAPE key => not a dropdown command
3845 // If input/textarea && if key is other than ESCAPE => not a dropdown command
3847 const isInput
= /input|textarea/i.test(event
.target
.tagName
);
3848 const isEscapeEvent
= event
.key
=== ESCAPE_KEY
$2;
3849 const isUpOrDownEvent
= [ARROW_UP_KEY
$1, ARROW_DOWN_KEY
$1].includes(event
.key
);
3850 if (!isUpOrDownEvent
&& !isEscapeEvent
) {
3853 if (isInput
&& !isEscapeEvent
) {
3856 event
.preventDefault();
3858 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
3859 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
);
3860 const instance
= Dropdown
.getOrCreateInstance(getToggleButton
);
3861 if (isUpOrDownEvent
) {
3862 event
.stopPropagation();
3864 instance
._selectMenuItem(event
);
3867 if (instance
._isShown()) {
3868 // else is escape and we check if it is shown
3869 event
.stopPropagation();
3871 getToggleButton
.focus();
3877 * Data API implementation
3880 EventHandler
.on(document
, EVENT_KEYDOWN_DATA_API
, SELECTOR_DATA_TOGGLE
$3, Dropdown
.dataApiKeydownHandler
);
3881 EventHandler
.on(document
, EVENT_KEYDOWN_DATA_API
, SELECTOR_MENU
, Dropdown
.dataApiKeydownHandler
);
3882 EventHandler
.on(document
, EVENT_CLICK_DATA_API
$3, Dropdown
.clearMenus
);
3883 EventHandler
.on(document
, EVENT_KEYUP_DATA_API
, Dropdown
.clearMenus
);
3884 EventHandler
.on(document
, EVENT_CLICK_DATA_API
$3, SELECTOR_DATA_TOGGLE
$3, function (event
) {
3885 event
.preventDefault();
3886 Dropdown
.getOrCreateInstance(this).toggle();
3893 defineJQueryPlugin(Dropdown
);
3896 * --------------------------------------------------------------------------
3897 * Bootstrap util/backdrop.js
3898 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
3899 * --------------------------------------------------------------------------
3907 const NAME
$9 = 'backdrop';
3908 const CLASS_NAME_FADE
$4 = 'fade';
3909 const CLASS_NAME_SHOW
$5 = 'show';
3910 const EVENT_MOUSEDOWN
= `mousedown.bs.${NAME$9}`;
3912 className: 'modal-backdrop',
3913 clickCallback: null,
3916 // if false, we use the backdrop helper without adding any element to the dom
3917 rootElement: 'body' // give the choice to place backdrop under different elements
3920 const DefaultType
$8 = {
3921 className: 'string',
3922 clickCallback: '(function|null)',
3923 isAnimated: 'boolean',
3924 isVisible: 'boolean',
3925 rootElement: '(element|string)'
3932 class Backdrop
extends Config
{
3933 constructor(config
) {
3935 this._config
= this._getConfig(config
);
3936 this._isAppended
= false;
3937 this._element
= null;
3941 static get Default() {
3944 static get DefaultType() {
3945 return DefaultType
$8;
3953 if (!this._config
.isVisible
) {
3958 const element
= this._getElement();
3959 if (this._config
.isAnimated
) {
3962 element
.classList
.add(CLASS_NAME_SHOW
$5);
3963 this._emulateAnimation(() => {
3968 if (!this._config
.isVisible
) {
3972 this._getElement().classList
.remove(CLASS_NAME_SHOW
$5);
3973 this._emulateAnimation(() => {
3979 if (!this._isAppended
) {
3982 EventHandler
.off(this._element
, EVENT_MOUSEDOWN
);
3983 this._element
.remove();
3984 this._isAppended
= false;
3989 if (!this._element
) {
3990 const backdrop
= document
.createElement('div');
3991 backdrop
.className
= this._config
.className
;
3992 if (this._config
.isAnimated
) {
3993 backdrop
.classList
.add(CLASS_NAME_FADE
$4);
3995 this._element
= backdrop
;
3997 return this._element
;
3999 _configAfterMerge(config
) {
4000 // use getElement() with the default "body" to get a fresh Element on each instantiation
4001 config
.rootElement
= getElement(config
.rootElement
);
4005 if (this._isAppended
) {
4008 const element
= this._getElement();
4009 this._config
.rootElement
.append(element
);
4010 EventHandler
.on(element
, EVENT_MOUSEDOWN
, () => {
4011 execute(this._config
.clickCallback
);
4013 this._isAppended
= true;
4015 _emulateAnimation(callback
) {
4016 executeAfterTransition(callback
, this._getElement(), this._config
.isAnimated
);
4021 * --------------------------------------------------------------------------
4022 * Bootstrap util/focustrap.js
4023 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4024 * --------------------------------------------------------------------------
4032 const NAME
$8 = 'focustrap';
4033 const DATA_KEY
$5 = 'bs.focustrap';
4034 const EVENT_KEY
$5 = `.${DATA_KEY$5}`;
4035 const EVENT_FOCUSIN
$2 = `focusin${EVENT_KEY$5}`;
4036 const EVENT_KEYDOWN_TAB
= `keydown.tab${EVENT_KEY$5}`;
4037 const TAB_KEY
= 'Tab';
4038 const TAB_NAV_FORWARD
= 'forward';
4039 const TAB_NAV_BACKWARD
= 'backward';
4042 trapElement: null // The element to trap focus inside of
4045 const DefaultType
$7 = {
4046 autofocus: 'boolean',
4047 trapElement: 'element'
4054 class FocusTrap
extends Config
{
4055 constructor(config
) {
4057 this._config
= this._getConfig(config
);
4058 this._isActive
= false;
4059 this._lastTabNavDirection
= null;
4063 static get Default() {
4066 static get DefaultType() {
4067 return DefaultType
$7;
4075 if (this._isActive
) {
4078 if (this._config
.autofocus
) {
4079 this._config
.trapElement
.focus();
4081 EventHandler
.off(document
, EVENT_KEY
$5); // guard against infinite focus loop
4082 EventHandler
.on(document
, EVENT_FOCUSIN
$2, event
=> this._handleFocusin(event
));
4083 EventHandler
.on(document
, EVENT_KEYDOWN_TAB
, event
=> this._handleKeydown(event
));
4084 this._isActive
= true;
4087 if (!this._isActive
) {
4090 this._isActive
= false;
4091 EventHandler
.off(document
, EVENT_KEY
$5);
4095 _handleFocusin(event
) {
4099 if (event
.target
=== document
|| event
.target
=== trapElement
|| trapElement
.contains(event
.target
)) {
4102 const elements
= SelectorEngine
.focusableChildren(trapElement
);
4103 if (elements
.length
=== 0) {
4104 trapElement
.focus();
4105 } else if (this._lastTabNavDirection
=== TAB_NAV_BACKWARD
) {
4106 elements
[elements
.length
- 1].focus();
4108 elements
[0].focus();
4111 _handleKeydown(event
) {
4112 if (event
.key
!== TAB_KEY
) {
4115 this._lastTabNavDirection
= event
.shiftKey
? TAB_NAV_BACKWARD : TAB_NAV_FORWARD
;
4120 * --------------------------------------------------------------------------
4121 * Bootstrap util/scrollBar.js
4122 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4123 * --------------------------------------------------------------------------
4131 const SELECTOR_FIXED_CONTENT
= '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
4132 const SELECTOR_STICKY_CONTENT
= '.sticky-top';
4133 const PROPERTY_PADDING
= 'padding-right';
4134 const PROPERTY_MARGIN
= 'margin-right';
4140 class ScrollBarHelper
{
4142 this._element
= document
.body
;
4147 // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
4148 const documentWidth
= document
.documentElement
.clientWidth
;
4149 return Math
.abs(window
.innerWidth
- documentWidth
);
4152 const width
= this.getWidth();
4153 this._disableOverFlow();
4154 // give padding to element to balance the hidden scrollbar width
4155 this._setElementAttributes(this._element
, PROPERTY_PADDING
, calculatedValue
=> calculatedValue
+ width
);
4156 // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
4157 this._setElementAttributes(SELECTOR_FIXED_CONTENT
, PROPERTY_PADDING
, calculatedValue
=> calculatedValue
+ width
);
4158 this._setElementAttributes(SELECTOR_STICKY_CONTENT
, PROPERTY_MARGIN
, calculatedValue
=> calculatedValue
- width
);
4161 this._resetElementAttributes(this._element
, 'overflow');
4162 this._resetElementAttributes(this._element
, PROPERTY_PADDING
);
4163 this._resetElementAttributes(SELECTOR_FIXED_CONTENT
, PROPERTY_PADDING
);
4164 this._resetElementAttributes(SELECTOR_STICKY_CONTENT
, PROPERTY_MARGIN
);
4167 return this.getWidth() > 0;
4171 _disableOverFlow() {
4172 this._saveInitialAttribute(this._element
, 'overflow');
4173 this._element
.style
.overflow
= 'hidden';
4175 _setElementAttributes(selector
, styleProperty
, callback
) {
4176 const scrollbarWidth
= this.getWidth();
4177 const manipulationCallBack
= element
=> {
4178 if (element
!== this._element
&& window
.innerWidth
> element
.clientWidth
+ scrollbarWidth
) {
4181 this._saveInitialAttribute(element
, styleProperty
);
4182 const calculatedValue
= window
.getComputedStyle(element
).getPropertyValue(styleProperty
);
4183 element
.style
.setProperty(styleProperty
, `${callback(Number.parseFloat(calculatedValue))}px`);
4185 this._applyManipulationCallback(selector
, manipulationCallBack
);
4187 _saveInitialAttribute(element
, styleProperty
) {
4188 const actualValue
= element
.style
.getPropertyValue(styleProperty
);
4190 Manipulator
.setDataAttribute(element
, styleProperty
, actualValue
);
4193 _resetElementAttributes(selector
, styleProperty
) {
4194 const manipulationCallBack
= element
=> {
4195 const value
= Manipulator
.getDataAttribute(element
, styleProperty
);
4196 // We only want to remove the property if the value is `null`; the value can also be zero
4197 if (value
=== null) {
4198 element
.style
.removeProperty(styleProperty
);
4201 Manipulator
.removeDataAttribute(element
, styleProperty
);
4202 element
.style
.setProperty(styleProperty
, value
);
4204 this._applyManipulationCallback(selector
, manipulationCallBack
);
4206 _applyManipulationCallback(selector
, callBack
) {
4207 if (isElement
$1(selector
)) {
4211 for (const sel
of SelectorEngine
.find(selector
, this._element
)) {
4218 * --------------------------------------------------------------------------
4219 * Bootstrap modal.js
4220 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4221 * --------------------------------------------------------------------------
4229 const NAME
$7 = 'modal';
4230 const DATA_KEY
$4 = 'bs.modal';
4231 const EVENT_KEY
$4 = `.${DATA_KEY$4}`;
4232 const DATA_API_KEY
$2 = '.data-api';
4233 const ESCAPE_KEY
$1 = 'Escape';
4234 const EVENT_HIDE
$4 = `hide${EVENT_KEY$4}`;
4235 const EVENT_HIDE_PREVENTED
$1 = `hidePrevented${EVENT_KEY$4}`;
4236 const EVENT_HIDDEN
$4 = `hidden${EVENT_KEY$4}`;
4237 const EVENT_SHOW
$4 = `show${EVENT_KEY$4}`;
4238 const EVENT_SHOWN
$4 = `shown${EVENT_KEY$4}`;
4239 const EVENT_RESIZE
$1 = `resize${EVENT_KEY$4}`;
4240 const EVENT_CLICK_DISMISS
= `click.dismiss${EVENT_KEY$4}`;
4241 const EVENT_MOUSEDOWN_DISMISS
= `mousedown.dismiss${EVENT_KEY$4}`;
4242 const EVENT_KEYDOWN_DISMISS
$1 = `keydown.dismiss${EVENT_KEY$4}`;
4243 const EVENT_CLICK_DATA_API
$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`;
4244 const CLASS_NAME_OPEN
= 'modal-open';
4245 const CLASS_NAME_FADE
$3 = 'fade';
4246 const CLASS_NAME_SHOW
$4 = 'show';
4247 const CLASS_NAME_STATIC
= 'modal-static';
4248 const OPEN_SELECTOR
$1 = '.modal.show';
4249 const SELECTOR_DIALOG
= '.modal-dialog';
4250 const SELECTOR_MODAL_BODY
= '.modal-body';
4251 const SELECTOR_DATA_TOGGLE
$2 = '[data-bs-toggle="modal"]';
4257 const DefaultType
$6 = {
4258 backdrop: '(boolean|string)',
4267 class Modal
extends BaseComponent
{
4268 constructor(element
, config
) {
4269 super(element
, config
);
4270 this._dialog
= SelectorEngine
.findOne(SELECTOR_DIALOG
, this._element
);
4271 this._backdrop
= this._initializeBackDrop();
4272 this._focustrap
= this._initializeFocusTrap();
4273 this._isShown
= false;
4274 this._isTransitioning
= false;
4275 this._scrollBar
= new ScrollBarHelper();
4276 this._addEventListeners();
4280 static get Default() {
4283 static get DefaultType() {
4284 return DefaultType
$6;
4291 toggle(relatedTarget
) {
4292 return this._isShown
? this.hide() : this.show(relatedTarget
);
4294 show(relatedTarget
) {
4295 if (this._isShown
|| this._isTransitioning
) {
4298 const showEvent
= EventHandler
.trigger(this._element
, EVENT_SHOW
$4, {
4301 if (showEvent
.defaultPrevented
) {
4304 this._isShown
= true;
4305 this._isTransitioning
= true;
4306 this._scrollBar
.hide();
4307 document
.body
.classList
.add(CLASS_NAME_OPEN
);
4308 this._adjustDialog();
4309 this._backdrop
.show(() => this._showElement(relatedTarget
));
4312 if (!this._isShown
|| this._isTransitioning
) {
4315 const hideEvent
= EventHandler
.trigger(this._element
, EVENT_HIDE
$4);
4316 if (hideEvent
.defaultPrevented
) {
4319 this._isShown
= false;
4320 this._isTransitioning
= true;
4321 this._focustrap
.deactivate();
4322 this._element
.classList
.remove(CLASS_NAME_SHOW
$4);
4323 this._queueCallback(() => this._hideModal(), this._element
, this._isAnimated());
4326 EventHandler
.off(window
, EVENT_KEY
$4);
4327 EventHandler
.off(this._dialog
, EVENT_KEY
$4);
4328 this._backdrop
.dispose();
4329 this._focustrap
.deactivate();
4333 this._adjustDialog();
4337 _initializeBackDrop() {
4338 return new Backdrop({
4339 isVisible: Boolean(this._config
.backdrop
),
4340 // 'static' option will be translated to true, and booleans will keep their value,
4341 isAnimated: this._isAnimated()
4344 _initializeFocusTrap() {
4345 return new FocusTrap({
4346 trapElement: this._element
4349 _showElement(relatedTarget
) {
4350 // try to append dynamic modal
4351 if (!document
.body
.contains(this._element
)) {
4352 document
.body
.append(this._element
);
4354 this._element
.style
.display
= 'block';
4355 this._element
.removeAttribute('aria-hidden');
4356 this._element
.setAttribute('aria-modal', true);
4357 this._element
.setAttribute('role', 'dialog');
4358 this._element
.scrollTop
= 0;
4359 const modalBody
= SelectorEngine
.findOne(SELECTOR_MODAL_BODY
, this._dialog
);
4361 modalBody
.scrollTop
= 0;
4363 reflow(this._element
);
4364 this._element
.classList
.add(CLASS_NAME_SHOW
$4);
4365 const transitionComplete
= () => {
4366 if (this._config
.focus
) {
4367 this._focustrap
.activate();
4369 this._isTransitioning
= false;
4370 EventHandler
.trigger(this._element
, EVENT_SHOWN
$4, {
4374 this._queueCallback(transitionComplete
, this._dialog
, this._isAnimated());
4376 _addEventListeners() {
4377 EventHandler
.on(this._element
, EVENT_KEYDOWN_DISMISS
$1, event
=> {
4378 if (event
.key
!== ESCAPE_KEY
$1) {
4381 if (this._config
.keyboard
) {
4385 this._triggerBackdropTransition();
4387 EventHandler
.on(window
, EVENT_RESIZE
$1, () => {
4388 if (this._isShown
&& !this._isTransitioning
) {
4389 this._adjustDialog();
4392 EventHandler
.on(this._element
, EVENT_MOUSEDOWN_DISMISS
, event
=> {
4393 // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks
4394 EventHandler
.one(this._element
, EVENT_CLICK_DISMISS
, event2
=> {
4395 if (this._element
!== event
.target
|| this._element
!== event2
.target
) {
4398 if (this._config
.backdrop
=== 'static') {
4399 this._triggerBackdropTransition();
4402 if (this._config
.backdrop
) {
4409 this._element
.style
.display
= 'none';
4410 this._element
.setAttribute('aria-hidden', true);
4411 this._element
.removeAttribute('aria-modal');
4412 this._element
.removeAttribute('role');
4413 this._isTransitioning
= false;
4414 this._backdrop
.hide(() => {
4415 document
.body
.classList
.remove(CLASS_NAME_OPEN
);
4416 this._resetAdjustments();
4417 this._scrollBar
.reset();
4418 EventHandler
.trigger(this._element
, EVENT_HIDDEN
$4);
4422 return this._element
.classList
.contains(CLASS_NAME_FADE
$3);
4424 _triggerBackdropTransition() {
4425 const hideEvent
= EventHandler
.trigger(this._element
, EVENT_HIDE_PREVENTED
$1);
4426 if (hideEvent
.defaultPrevented
) {
4429 const isModalOverflowing
= this._element
.scrollHeight
> document
.documentElement
.clientHeight
;
4430 const initialOverflowY
= this._element
.style
.overflowY
;
4431 // return if the following background transition hasn't yet completed
4432 if (initialOverflowY
=== 'hidden' || this._element
.classList
.contains(CLASS_NAME_STATIC
)) {
4435 if (!isModalOverflowing
) {
4436 this._element
.style
.overflowY
= 'hidden';
4438 this._element
.classList
.add(CLASS_NAME_STATIC
);
4439 this._queueCallback(() => {
4440 this._element
.classList
.remove(CLASS_NAME_STATIC
);
4441 this._queueCallback(() => {
4442 this._element
.style
.overflowY
= initialOverflowY
;
4445 this._element
.focus();
4449 * The following methods are used to handle overflowing modals
4453 const isModalOverflowing
= this._element
.scrollHeight
> document
.documentElement
.clientHeight
;
4454 const scrollbarWidth
= this._scrollBar
.getWidth();
4455 const isBodyOverflowing
= scrollbarWidth
> 0;
4456 if (isBodyOverflowing
&& !isModalOverflowing
) {
4457 const property
= isRTL() ? 'paddingLeft' : 'paddingRight';
4458 this._element
.style
[property
] = `${scrollbarWidth}px`;
4460 if (!isBodyOverflowing
&& isModalOverflowing
) {
4461 const property
= isRTL() ? 'paddingRight' : 'paddingLeft';
4462 this._element
.style
[property
] = `${scrollbarWidth}px`;
4465 _resetAdjustments() {
4466 this._element
.style
.paddingLeft
= '';
4467 this._element
.style
.paddingRight
= '';
4471 static jQueryInterface(config
, relatedTarget
) {
4472 return this.each(function () {
4473 const data
= Modal
.getOrCreateInstance(this, config
);
4474 if (typeof config
!== 'string') {
4477 if (typeof data
[config
] === 'undefined') {
4478 throw new TypeError(`No method named "${config}"`);
4480 data
[config
](relatedTarget
);
4486 * Data API implementation
4489 EventHandler
.on(document
, EVENT_CLICK_DATA_API
$2, SELECTOR_DATA_TOGGLE
$2, function (event
) {
4490 const target
= SelectorEngine
.getElementFromSelector(this);
4491 if (['A', 'AREA'].includes(this.tagName
)) {
4492 event
.preventDefault();
4494 EventHandler
.one(target
, EVENT_SHOW
$4, showEvent
=> {
4495 if (showEvent
.defaultPrevented
) {
4496 // only register focus restorer if modal will actually get shown
4499 EventHandler
.one(target
, EVENT_HIDDEN
$4, () => {
4500 if (isVisible(this)) {
4506 // avoid conflict when clicking modal toggler while another one is open
4507 const alreadyOpen
= SelectorEngine
.findOne(OPEN_SELECTOR
$1);
4509 Modal
.getInstance(alreadyOpen
).hide();
4511 const data
= Modal
.getOrCreateInstance(target
);
4514 enableDismissTrigger(Modal
);
4520 defineJQueryPlugin(Modal
);
4523 * --------------------------------------------------------------------------
4524 * Bootstrap offcanvas.js
4525 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4526 * --------------------------------------------------------------------------
4534 const NAME
$6 = 'offcanvas';
4535 const DATA_KEY
$3 = 'bs.offcanvas';
4536 const EVENT_KEY
$3 = `.${DATA_KEY$3}`;
4537 const DATA_API_KEY
$1 = '.data-api';
4538 const EVENT_LOAD_DATA_API
$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`;
4539 const ESCAPE_KEY
= 'Escape';
4540 const CLASS_NAME_SHOW
$3 = 'show';
4541 const CLASS_NAME_SHOWING
$1 = 'showing';
4542 const CLASS_NAME_HIDING
= 'hiding';
4543 const CLASS_NAME_BACKDROP
= 'offcanvas-backdrop';
4544 const OPEN_SELECTOR
= '.offcanvas.show';
4545 const EVENT_SHOW
$3 = `show${EVENT_KEY$3}`;
4546 const EVENT_SHOWN
$3 = `shown${EVENT_KEY$3}`;
4547 const EVENT_HIDE
$3 = `hide${EVENT_KEY$3}`;
4548 const EVENT_HIDE_PREVENTED
= `hidePrevented${EVENT_KEY$3}`;
4549 const EVENT_HIDDEN
$3 = `hidden${EVENT_KEY$3}`;
4550 const EVENT_RESIZE
= `resize${EVENT_KEY$3}`;
4551 const EVENT_CLICK_DATA_API
$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`;
4552 const EVENT_KEYDOWN_DISMISS
= `keydown.dismiss${EVENT_KEY$3}`;
4553 const SELECTOR_DATA_TOGGLE
$1 = '[data-bs-toggle="offcanvas"]';
4559 const DefaultType
$5 = {
4560 backdrop: '(boolean|string)',
4561 keyboard: 'boolean',
4569 class Offcanvas
extends BaseComponent
{
4570 constructor(element
, config
) {
4571 super(element
, config
);
4572 this._isShown
= false;
4573 this._backdrop
= this._initializeBackDrop();
4574 this._focustrap
= this._initializeFocusTrap();
4575 this._addEventListeners();
4579 static get Default() {
4582 static get DefaultType() {
4583 return DefaultType
$5;
4590 toggle(relatedTarget
) {
4591 return this._isShown
? this.hide() : this.show(relatedTarget
);
4593 show(relatedTarget
) {
4594 if (this._isShown
) {
4597 const showEvent
= EventHandler
.trigger(this._element
, EVENT_SHOW
$3, {
4600 if (showEvent
.defaultPrevented
) {
4603 this._isShown
= true;
4604 this._backdrop
.show();
4605 if (!this._config
.scroll
) {
4606 new ScrollBarHelper().hide();
4608 this._element
.setAttribute('aria-modal', true);
4609 this._element
.setAttribute('role', 'dialog');
4610 this._element
.classList
.add(CLASS_NAME_SHOWING
$1);
4611 const completeCallBack
= () => {
4612 if (!this._config
.scroll
|| this._config
.backdrop
) {
4613 this._focustrap
.activate();
4615 this._element
.classList
.add(CLASS_NAME_SHOW
$3);
4616 this._element
.classList
.remove(CLASS_NAME_SHOWING
$1);
4617 EventHandler
.trigger(this._element
, EVENT_SHOWN
$3, {
4621 this._queueCallback(completeCallBack
, this._element
, true);
4624 if (!this._isShown
) {
4627 const hideEvent
= EventHandler
.trigger(this._element
, EVENT_HIDE
$3);
4628 if (hideEvent
.defaultPrevented
) {
4631 this._focustrap
.deactivate();
4632 this._element
.blur();
4633 this._isShown
= false;
4634 this._element
.classList
.add(CLASS_NAME_HIDING
);
4635 this._backdrop
.hide();
4636 const completeCallback
= () => {
4637 this._element
.classList
.remove(CLASS_NAME_SHOW
$3, CLASS_NAME_HIDING
);
4638 this._element
.removeAttribute('aria-modal');
4639 this._element
.removeAttribute('role');
4640 if (!this._config
.scroll
) {
4641 new ScrollBarHelper().reset();
4643 EventHandler
.trigger(this._element
, EVENT_HIDDEN
$3);
4645 this._queueCallback(completeCallback
, this._element
, true);
4648 this._backdrop
.dispose();
4649 this._focustrap
.deactivate();
4654 _initializeBackDrop() {
4655 const clickCallback
= () => {
4656 if (this._config
.backdrop
=== 'static') {
4657 EventHandler
.trigger(this._element
, EVENT_HIDE_PREVENTED
);
4663 // 'static' option will be translated to true, and booleans will keep their value
4664 const isVisible
= Boolean(this._config
.backdrop
);
4665 return new Backdrop({
4666 className: CLASS_NAME_BACKDROP
,
4669 rootElement: this._element
.parentNode
,
4670 clickCallback: isVisible
? clickCallback : null
4673 _initializeFocusTrap() {
4674 return new FocusTrap({
4675 trapElement: this._element
4678 _addEventListeners() {
4679 EventHandler
.on(this._element
, EVENT_KEYDOWN_DISMISS
, event
=> {
4680 if (event
.key
!== ESCAPE_KEY
) {
4683 if (this._config
.keyboard
) {
4687 EventHandler
.trigger(this._element
, EVENT_HIDE_PREVENTED
);
4692 static jQueryInterface(config
) {
4693 return this.each(function () {
4694 const data
= Offcanvas
.getOrCreateInstance(this, config
);
4695 if (typeof config
!== 'string') {
4698 if (data
[config
] === undefined || config
.startsWith('_') || config
=== 'constructor') {
4699 throw new TypeError(`No method named "${config}"`);
4707 * Data API implementation
4710 EventHandler
.on(document
, EVENT_CLICK_DATA_API
$1, SELECTOR_DATA_TOGGLE
$1, function (event
) {
4711 const target
= SelectorEngine
.getElementFromSelector(this);
4712 if (['A', 'AREA'].includes(this.tagName
)) {
4713 event
.preventDefault();
4715 if (isDisabled(this)) {
4718 EventHandler
.one(target
, EVENT_HIDDEN
$3, () => {
4719 // focus on trigger when it is closed
4720 if (isVisible(this)) {
4725 // avoid conflict when clicking a toggler of an offcanvas, while another is open
4726 const alreadyOpen
= SelectorEngine
.findOne(OPEN_SELECTOR
);
4727 if (alreadyOpen
&& alreadyOpen
!== target
) {
4728 Offcanvas
.getInstance(alreadyOpen
).hide();
4730 const data
= Offcanvas
.getOrCreateInstance(target
);
4733 EventHandler
.on(window
, EVENT_LOAD_DATA_API
$2, () => {
4734 for (const selector
of SelectorEngine
.find(OPEN_SELECTOR
)) {
4735 Offcanvas
.getOrCreateInstance(selector
).show();
4738 EventHandler
.on(window
, EVENT_RESIZE
, () => {
4739 for (const element
of SelectorEngine
.find('[aria-modal][class*=show][class*=offcanvas-]')) {
4740 if (getComputedStyle(element
).position
!== 'fixed') {
4741 Offcanvas
.getOrCreateInstance(element
).hide();
4745 enableDismissTrigger(Offcanvas
);
4751 defineJQueryPlugin(Offcanvas
);
4754 * --------------------------------------------------------------------------
4755 * Bootstrap util/sanitizer.js
4756 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4757 * --------------------------------------------------------------------------
4760 // js-docs-start allow-list
4761 const ARIA_ATTRIBUTE_PATTERN
= /^aria-[\w-]*$/i;
4762 const DefaultAllowlist
= {
4763 // Global attributes allowed on any supplied element below.
4764 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN
],
4765 a: ['target', 'href', 'title', 'rel'],
4781 img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
4795 // js-docs-end allow-list
4797 const uriAttributes
= new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);
4800 * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation
4803 * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
4805 // eslint-disable-next-line unicorn/better-regex
4806 const SAFE_URL_PATTERN
= /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;
4807 const allowedAttribute
= (attribute
, allowedAttributeList
) => {
4808 const attributeName
= attribute
.nodeName
.toLowerCase();
4809 if (allowedAttributeList
.includes(attributeName
)) {
4810 if (uriAttributes
.has(attributeName
)) {
4811 return Boolean(SAFE_URL_PATTERN
.test(attribute
.nodeValue
));
4816 // Check if a regular expression validates the attribute.
4817 return allowedAttributeList
.filter(attributeRegex
=> attributeRegex
instanceof RegExp
).some(regex
=> regex
.test(attributeName
));
4819 function sanitizeHtml(unsafeHtml
, allowList
, sanitizeFunction
) {
4820 if (!unsafeHtml
.length
) {
4823 if (sanitizeFunction
&& typeof sanitizeFunction
=== 'function') {
4824 return sanitizeFunction(unsafeHtml
);
4826 const domParser
= new window
.DOMParser();
4827 const createdDocument
= domParser
.parseFromString(unsafeHtml
, 'text/html');
4828 const elements
= [].concat(...createdDocument
.body
.querySelectorAll('*'));
4829 for (const element
of elements
) {
4830 const elementName
= element
.nodeName
.toLowerCase();
4831 if (!Object
.keys(allowList
).includes(elementName
)) {
4835 const attributeList
= [].concat(...element
.attributes
);
4836 const allowedAttributes
= [].concat(allowList
['*'] || [], allowList
[elementName
] || []);
4837 for (const attribute
of attributeList
) {
4838 if (!allowedAttribute(attribute
, allowedAttributes
)) {
4839 element
.removeAttribute(attribute
.nodeName
);
4843 return createdDocument
.body
.innerHTML
;
4847 * --------------------------------------------------------------------------
4848 * Bootstrap util/template-factory.js
4849 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4850 * --------------------------------------------------------------------------
4858 const NAME
$5 = 'TemplateFactory';
4860 allowList: DefaultAllowlist
,
4862 // { selector : text , selector2 : text2 , }
4867 template: '<div></div>'
4869 const DefaultType
$4 = {
4870 allowList: 'object',
4872 extraClass: '(string|function)',
4874 sanitize: 'boolean',
4875 sanitizeFn: '(null|function)',
4878 const DefaultContentType
= {
4879 entry: '(string|element|function|null)',
4880 selector: '(string|element)'
4887 class TemplateFactory
extends Config
{
4888 constructor(config
) {
4890 this._config
= this._getConfig(config
);
4894 static get Default() {
4897 static get DefaultType() {
4898 return DefaultType
$4;
4906 return Object
.values(this._config
.content
).map(config
=> this._resolvePossibleFunction(config
)).filter(Boolean
);
4909 return this.getContent().length
> 0;
4911 changeContent(content
) {
4912 this._checkContent(content
);
4913 this._config
.content
= {
4914 ...this._config
.content
,
4920 const templateWrapper
= document
.createElement('div');
4921 templateWrapper
.innerHTML
= this._maybeSanitize(this._config
.template
);
4922 for (const [selector
, text
] of Object
.entries(this._config
.content
)) {
4923 this._setContent(templateWrapper
, text
, selector
);
4925 const template
= templateWrapper
.children
[0];
4926 const extraClass
= this._resolvePossibleFunction(this._config
.extraClass
);
4928 template
.classList
.add(...extraClass
.split(' '));
4934 _typeCheckConfig(config
) {
4935 super._typeCheckConfig(config
);
4936 this._checkContent(config
.content
);
4938 _checkContent(arg
) {
4939 for (const [selector
, content
] of Object
.entries(arg
)) {
4940 super._typeCheckConfig({
4943 }, DefaultContentType
);
4946 _setContent(template
, content
, selector
) {
4947 const templateElement
= SelectorEngine
.findOne(selector
, template
);
4948 if (!templateElement
) {
4951 content
= this._resolvePossibleFunction(content
);
4953 templateElement
.remove();
4956 if (isElement
$1(content
)) {
4957 this._putElementInTemplate(getElement(content
), templateElement
);
4960 if (this._config
.html
) {
4961 templateElement
.innerHTML
= this._maybeSanitize(content
);
4964 templateElement
.textContent
= content
;
4966 _maybeSanitize(arg
) {
4967 return this._config
.sanitize
? sanitizeHtml(arg
, this._config
.allowList
, this._config
.sanitizeFn
) : arg
;
4969 _resolvePossibleFunction(arg
) {
4970 return execute(arg
, [this]);
4972 _putElementInTemplate(element
, templateElement
) {
4973 if (this._config
.html
) {
4974 templateElement
.innerHTML
= '';
4975 templateElement
.append(element
);
4978 templateElement
.textContent
= element
.textContent
;
4983 * --------------------------------------------------------------------------
4984 * Bootstrap tooltip.js
4985 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4986 * --------------------------------------------------------------------------
4994 const NAME
$4 = 'tooltip';
4995 const DISALLOWED_ATTRIBUTES
= new Set(['sanitize', 'allowList', 'sanitizeFn']);
4996 const CLASS_NAME_FADE
$2 = 'fade';
4997 const CLASS_NAME_MODAL
= 'modal';
4998 const CLASS_NAME_SHOW
$2 = 'show';
4999 const SELECTOR_TOOLTIP_INNER
= '.tooltip-inner';
5000 const SELECTOR_MODAL
= `.${CLASS_NAME_MODAL}`;
5001 const EVENT_MODAL_HIDE
= 'hide.bs.modal';
5002 const TRIGGER_HOVER
= 'hover';
5003 const TRIGGER_FOCUS
= 'focus';
5004 const TRIGGER_CLICK
= 'click';
5005 const TRIGGER_MANUAL
= 'manual';
5006 const EVENT_HIDE
$2 = 'hide';
5007 const EVENT_HIDDEN
$2 = 'hidden';
5008 const EVENT_SHOW
$2 = 'show';
5009 const EVENT_SHOWN
$2 = 'shown';
5010 const EVENT_INSERTED
= 'inserted';
5011 const EVENT_CLICK
$1 = 'click';
5012 const EVENT_FOCUSIN
$1 = 'focusin';
5013 const EVENT_FOCUSOUT
$1 = 'focusout';
5014 const EVENT_MOUSEENTER
= 'mouseenter';
5015 const EVENT_MOUSELEAVE
= 'mouseleave';
5016 const AttachmentMap
= {
5019 RIGHT: isRTL() ? 'left' : 'right',
5021 LEFT: isRTL() ? 'right' : 'left'
5024 allowList: DefaultAllowlist
,
5026 boundary: 'clippingParents',
5030 fallbackPlacements: ['top', 'right', 'bottom', 'left'],
5038 template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>',
5040 trigger: 'hover focus'
5042 const DefaultType
$3 = {
5043 allowList: 'object',
5044 animation: 'boolean',
5045 boundary: '(string|element)',
5046 container: '(string|element|boolean)',
5047 customClass: '(string|function)',
5048 delay: '(number|object)',
5049 fallbackPlacements: 'array',
5051 offset: '(array|string|function)',
5052 placement: '(string|function)',
5053 popperConfig: '(null|object|function)',
5054 sanitize: 'boolean',
5055 sanitizeFn: '(null|function)',
5056 selector: '(string|boolean)',
5058 title: '(string|element|function)',
5066 class Tooltip
extends BaseComponent
{
5067 constructor(element
, config
) {
5068 if (typeof Popper
=== 'undefined') {
5069 throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)');
5071 super(element
, config
);
5074 this._isEnabled
= true;
5076 this._isHovered
= null;
5077 this._activeTrigger
= {};
5078 this._popper
= null;
5079 this._templateFactory
= null;
5080 this._newContent
= null;
5084 this._setListeners();
5085 if (!this._config
.selector
) {
5091 static get Default() {
5094 static get DefaultType() {
5095 return DefaultType
$3;
5103 this._isEnabled
= true;
5106 this._isEnabled
= false;
5109 this._isEnabled
= !this._isEnabled
;
5112 if (!this._isEnabled
) {
5115 this._activeTrigger
.click
= !this._activeTrigger
.click
;
5116 if (this._isShown()) {
5123 clearTimeout(this._timeout
);
5124 EventHandler
.off(this._element
.closest(SELECTOR_MODAL
), EVENT_MODAL_HIDE
, this._hideModalHandler
);
5125 if (this._element
.getAttribute('data-bs-original-title')) {
5126 this._element
.setAttribute('title', this._element
.getAttribute('data-bs-original-title'));
5128 this._disposePopper();
5132 if (this._element
.style
.display
=== 'none') {
5133 throw new Error('Please use show on visible elements');
5135 if (!(this._isWithContent() && this._isEnabled
)) {
5138 const showEvent
= EventHandler
.trigger(this._element
, this.constructor.eventName(EVENT_SHOW
$2));
5139 const shadowRoot
= findShadowRoot(this._element
);
5140 const isInTheDom
= (shadowRoot
|| this._element
.ownerDocument
.documentElement
).contains(this._element
);
5141 if (showEvent
.defaultPrevented
|| !isInTheDom
) {
5145 // TODO: v6 remove this or make it optional
5146 this._disposePopper();
5147 const tip
= this._getTipElement();
5148 this._element
.setAttribute('aria-describedby', tip
.getAttribute('id'));
5152 if (!this._element
.ownerDocument
.documentElement
.contains(this.tip
)) {
5153 container
.append(tip
);
5154 EventHandler
.trigger(this._element
, this.constructor.eventName(EVENT_INSERTED
));
5156 this._popper
= this._createPopper(tip
);
5157 tip
.classList
.add(CLASS_NAME_SHOW
$2);
5159 // If this is a touch-enabled device we add extra
5160 // empty mouseover listeners to the body's immediate children;
5161 // only needed because of broken event delegation on iOS
5162 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
5163 if ('ontouchstart' in document
.documentElement
) {
5164 for (const element
of [].concat(...document
.body
.children
)) {
5165 EventHandler
.on(element
, 'mouseover', noop
);
5168 const complete
= () => {
5169 EventHandler
.trigger(this._element
, this.constructor.eventName(EVENT_SHOWN
$2));
5170 if (this._isHovered
=== false) {
5173 this._isHovered
= false;
5175 this._queueCallback(complete
, this.tip
, this._isAnimated());
5178 if (!this._isShown()) {
5181 const hideEvent
= EventHandler
.trigger(this._element
, this.constructor.eventName(EVENT_HIDE
$2));
5182 if (hideEvent
.defaultPrevented
) {
5185 const tip
= this._getTipElement();
5186 tip
.classList
.remove(CLASS_NAME_SHOW
$2);
5188 // If this is a touch-enabled device we remove the extra
5189 // empty mouseover listeners we added for iOS support
5190 if ('ontouchstart' in document
.documentElement
) {
5191 for (const element
of [].concat(...document
.body
.children
)) {
5192 EventHandler
.off(element
, 'mouseover', noop
);
5195 this._activeTrigger
[TRIGGER_CLICK
] = false;
5196 this._activeTrigger
[TRIGGER_FOCUS
] = false;
5197 this._activeTrigger
[TRIGGER_HOVER
] = false;
5198 this._isHovered
= null; // it is a trick to support manual triggering
5200 const complete
= () => {
5201 if (this._isWithActiveTrigger()) {
5204 if (!this._isHovered
) {
5205 this._disposePopper();
5207 this._element
.removeAttribute('aria-describedby');
5208 EventHandler
.trigger(this._element
, this.constructor.eventName(EVENT_HIDDEN
$2));
5210 this._queueCallback(complete
, this.tip
, this._isAnimated());
5214 this._popper
.update();
5220 return Boolean(this._getTitle());
5224 this.tip
= this._createTipElement(this._newContent
|| this._getContentForTemplate());
5228 _createTipElement(content
) {
5229 const tip
= this._getTemplateFactory(content
).toHtml();
5231 // TODO: remove this check in v6
5235 tip
.classList
.remove(CLASS_NAME_FADE
$2, CLASS_NAME_SHOW
$2);
5236 // TODO: v6 the following can be achieved with CSS only
5237 tip
.classList
.add(`bs-${this.constructor.NAME}-auto`);
5238 const tipId
= getUID(this.constructor.NAME
).toString();
5239 tip
.setAttribute('id', tipId
);
5240 if (this._isAnimated()) {
5241 tip
.classList
.add(CLASS_NAME_FADE
$2);
5245 setContent(content
) {
5246 this._newContent
= content
;
5247 if (this._isShown()) {
5248 this._disposePopper();
5252 _getTemplateFactory(content
) {
5253 if (this._templateFactory
) {
5254 this._templateFactory
.changeContent(content
);
5256 this._templateFactory
= new TemplateFactory({
5258 // the `content` var has to be after `this._config`
5259 // to override config.content in case of popover
5261 extraClass: this._resolvePossibleFunction(this._config
.customClass
)
5264 return this._templateFactory
;
5266 _getContentForTemplate() {
5268 [SELECTOR_TOOLTIP_INNER
]: this._getTitle()
5272 return this._resolvePossibleFunction(this._config
.title
) || this._element
.getAttribute('data-bs-original-title');
5276 _initializeOnDelegatedTarget(event
) {
5277 return this.constructor.getOrCreateInstance(event
.delegateTarget
, this._getDelegateConfig());
5280 return this._config
.animation
|| this.tip
&& this.tip
.classList
.contains(CLASS_NAME_FADE
$2);
5283 return this.tip
&& this.tip
.classList
.contains(CLASS_NAME_SHOW
$2);
5285 _createPopper(tip
) {
5286 const placement
= execute(this._config
.placement
, [this, tip
, this._element
]);
5287 const attachment
= AttachmentMap
[placement
.toUpperCase()];
5288 return createPopper(this._element
, tip
, this._getPopperConfig(attachment
));
5294 if (typeof offset
=== 'string') {
5295 return offset
.split(',').map(value
=> Number
.parseInt(value
, 10));
5297 if (typeof offset
=== 'function') {
5298 return popperData
=> offset(popperData
, this._element
);
5302 _resolvePossibleFunction(arg
) {
5303 return execute(arg
, [this._element
]);
5305 _getPopperConfig(attachment
) {
5306 const defaultBsPopperConfig
= {
5307 placement: attachment
,
5311 fallbackPlacements: this._config
.fallbackPlacements
5316 offset: this._getOffset()
5319 name: 'preventOverflow',
5321 boundary: this._config
.boundary
5326 element: `.${this.constructor.NAME}-arrow`
5329 name: 'preSetPlacement',
5331 phase: 'beforeMain',
5333 // Pre-set Popper's placement attribute in order to read the arrow sizes properly.
5334 // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement
5335 this._getTipElement().setAttribute('data-popper-placement', data
.state
.placement
);
5340 ...defaultBsPopperConfig
,
5341 ...execute(this._config
.popperConfig
, [defaultBsPopperConfig
])
5345 const triggers
= this._config
.trigger
.split(' ');
5346 for (const trigger
of triggers
) {
5347 if (trigger
=== 'click') {
5348 EventHandler
.on(this._element
, this.constructor.eventName(EVENT_CLICK
$1), this._config
.selector
, event
=> {
5349 const context
= this._initializeOnDelegatedTarget(event
);
5352 } else if (trigger
!== TRIGGER_MANUAL
) {
5353 const eventIn
= trigger
=== TRIGGER_HOVER
? this.constructor.eventName(EVENT_MOUSEENTER
) : this.constructor.eventName(EVENT_FOCUSIN
$1);
5354 const eventOut
= trigger
=== TRIGGER_HOVER
? this.constructor.eventName(EVENT_MOUSELEAVE
) : this.constructor.eventName(EVENT_FOCUSOUT
$1);
5355 EventHandler
.on(this._element
, eventIn
, this._config
.selector
, event
=> {
5356 const context
= this._initializeOnDelegatedTarget(event
);
5357 context
._activeTrigger
[event
.type
=== 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER
] = true;
5360 EventHandler
.on(this._element
, eventOut
, this._config
.selector
, event
=> {
5361 const context
= this._initializeOnDelegatedTarget(event
);
5362 context
._activeTrigger
[event
.type
=== 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER
] = context
._element
.contains(event
.relatedTarget
);
5367 this._hideModalHandler
= () => {
5368 if (this._element
) {
5372 EventHandler
.on(this._element
.closest(SELECTOR_MODAL
), EVENT_MODAL_HIDE
, this._hideModalHandler
);
5375 const title
= this._element
.getAttribute('title');
5379 if (!this._element
.getAttribute('aria-label') && !this._element
.textContent
.trim()) {
5380 this._element
.setAttribute('aria-label', title
);
5382 this._element
.setAttribute('data-bs-original-title', title
); // DO NOT USE IT. Is only for backwards compatibility
5383 this._element
.removeAttribute('title');
5386 if (this._isShown() || this._isHovered
) {
5387 this._isHovered
= true;
5390 this._isHovered
= true;
5391 this._setTimeout(() => {
5392 if (this._isHovered
) {
5395 }, this._config
.delay
.show
);
5398 if (this._isWithActiveTrigger()) {
5401 this._isHovered
= false;
5402 this._setTimeout(() => {
5403 if (!this._isHovered
) {
5406 }, this._config
.delay
.hide
);
5408 _setTimeout(handler
, timeout
) {
5409 clearTimeout(this._timeout
);
5410 this._timeout
= setTimeout(handler
, timeout
);
5412 _isWithActiveTrigger() {
5413 return Object
.values(this._activeTrigger
).includes(true);
5415 _getConfig(config
) {
5416 const dataAttributes
= Manipulator
.getDataAttributes(this._element
);
5417 for (const dataAttribute
of Object
.keys(dataAttributes
)) {
5418 if (DISALLOWED_ATTRIBUTES
.has(dataAttribute
)) {
5419 delete dataAttributes
[dataAttribute
];
5424 ...(typeof config
=== 'object' && config
? config : {})
5426 config
= this._mergeConfigObj(config
);
5427 config
= this._configAfterMerge(config
);
5428 this._typeCheckConfig(config
);
5431 _configAfterMerge(config
) {
5432 config
.container
= config
.container
=== false ? document
.body : getElement(config
.container
);
5433 if (typeof config
.delay
=== 'number') {
5439 if (typeof config
.title
=== 'number') {
5440 config
.title
= config
.title
.toString();
5442 if (typeof config
.content
=== 'number') {
5443 config
.content
= config
.content
.toString();
5447 _getDelegateConfig() {
5449 for (const [key
, value
] of Object
.entries(this._config
)) {
5450 if (this.constructor.Default
[key
] !== value
) {
5451 config
[key
] = value
;
5454 config
.selector
= false;
5455 config
.trigger
= 'manual';
5457 // In the future can be replaced with:
5458 // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])
5459 // `Object.fromEntries(keysWithDifferentValues)`
5464 this._popper
.destroy();
5465 this._popper
= null;
5474 static jQueryInterface(config
) {
5475 return this.each(function () {
5476 const data
= Tooltip
.getOrCreateInstance(this, config
);
5477 if (typeof config
!== 'string') {
5480 if (typeof data
[config
] === 'undefined') {
5481 throw new TypeError(`No method named "${config}"`);
5492 defineJQueryPlugin(Tooltip
);
5495 * --------------------------------------------------------------------------
5496 * Bootstrap popover.js
5497 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5498 * --------------------------------------------------------------------------
5506 const NAME
$3 = 'popover';
5507 const SELECTOR_TITLE
= '.popover-header';
5508 const SELECTOR_CONTENT
= '.popover-body';
5514 template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div>' + '</div>',
5517 const DefaultType
$2 = {
5518 ...Tooltip
.DefaultType
,
5519 content: '(null|string|element|function)'
5526 class Popover
extends Tooltip
{
5528 static get Default() {
5531 static get DefaultType() {
5532 return DefaultType
$2;
5540 return this._getTitle() || this._getContent();
5544 _getContentForTemplate() {
5546 [SELECTOR_TITLE
]: this._getTitle(),
5547 [SELECTOR_CONTENT
]: this._getContent()
5551 return this._resolvePossibleFunction(this._config
.content
);
5555 static jQueryInterface(config
) {
5556 return this.each(function () {
5557 const data
= Popover
.getOrCreateInstance(this, config
);
5558 if (typeof config
!== 'string') {
5561 if (typeof data
[config
] === 'undefined') {
5562 throw new TypeError(`No method named "${config}"`);
5573 defineJQueryPlugin(Popover
);
5576 * --------------------------------------------------------------------------
5577 * Bootstrap scrollspy.js
5578 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5579 * --------------------------------------------------------------------------
5587 const NAME
$2 = 'scrollspy';
5588 const DATA_KEY
$2 = 'bs.scrollspy';
5589 const EVENT_KEY
$2 = `.${DATA_KEY$2}`;
5590 const DATA_API_KEY
= '.data-api';
5591 const EVENT_ACTIVATE
= `activate${EVENT_KEY$2}`;
5592 const EVENT_CLICK
= `click${EVENT_KEY$2}`;
5593 const EVENT_LOAD_DATA_API
$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`;
5594 const CLASS_NAME_DROPDOWN_ITEM
= 'dropdown-item';
5595 const CLASS_NAME_ACTIVE
$1 = 'active';
5596 const SELECTOR_DATA_SPY
= '[data-bs-spy="scroll"]';
5597 const SELECTOR_TARGET_LINKS
= '[href]';
5598 const SELECTOR_NAV_LIST_GROUP
= '.nav, .list-group';
5599 const SELECTOR_NAV_LINKS
= '.nav-link';
5600 const SELECTOR_NAV_ITEMS
= '.nav-item';
5601 const SELECTOR_LIST_ITEMS
= '.list-group-item';
5602 const SELECTOR_LINK_ITEMS
= `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;
5603 const SELECTOR_DROPDOWN
= '.dropdown';
5604 const SELECTOR_DROPDOWN_TOGGLE
$1 = '.dropdown-toggle';
5607 // TODO: v6 @deprecated, keep it for backwards compatibility reasons
5608 rootMargin: '0px 0px -25%',
5609 smoothScroll: false,
5611 threshold: [0.1, 0.5, 1]
5613 const DefaultType
$1 = {
5614 offset: '(number|null)',
5615 // TODO v6 @deprecated, keep it for backwards compatibility reasons
5616 rootMargin: 'string',
5617 smoothScroll: 'boolean',
5626 class ScrollSpy
extends BaseComponent
{
5627 constructor(element
, config
) {
5628 super(element
, config
);
5630 // this._element is the observablesContainer and config.target the menu links wrapper
5631 this._targetLinks
= new Map();
5632 this._observableSections
= new Map();
5633 this._rootElement
= getComputedStyle(this._element
).overflowY
=== 'visible' ? null : this._element
;
5634 this._activeTarget
= null;
5635 this._observer
= null;
5636 this._previousScrollData
= {
5640 this.refresh(); // initialize
5644 static get Default() {
5647 static get DefaultType() {
5648 return DefaultType
$1;
5656 this._initializeTargetsAndObservables();
5657 this._maybeEnableSmoothScroll();
5658 if (this._observer
) {
5659 this._observer
.disconnect();
5661 this._observer
= this._getNewObserver();
5663 for (const section
of this._observableSections
.values()) {
5664 this._observer
.observe(section
);
5668 this._observer
.disconnect();
5673 _configAfterMerge(config
) {
5674 // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case
5675 config
.target
= getElement(config
.target
) || document
.body
;
5677 // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only
5678 config
.rootMargin
= config
.offset
? `${config.offset}px 0px -30%` : config
.rootMargin
;
5679 if (typeof config
.threshold
=== 'string') {
5680 config
.threshold
= config
.threshold
.split(',').map(value
=> Number
.parseFloat(value
));
5684 _maybeEnableSmoothScroll() {
5685 if (!this._config
.smoothScroll
) {
5689 // unregister any previous listeners
5690 EventHandler
.off(this._config
.target
, EVENT_CLICK
);
5691 EventHandler
.on(this._config
.target
, EVENT_CLICK
, SELECTOR_TARGET_LINKS
, event
=> {
5692 const observableSection
= this._observableSections
.get(event
.target
.hash
);
5693 if (observableSection
) {
5694 event
.preventDefault();
5695 const root
= this._rootElement
|| window
;
5696 const height
= observableSection
.offsetTop
- this._element
.offsetTop
;
5697 if (root
.scrollTo
) {
5705 // Chrome 60 doesn't support `scrollTo`
5706 root
.scrollTop
= height
;
5712 root: this._rootElement
,
5713 threshold: this._config
.threshold
,
5714 rootMargin: this._config
.rootMargin
5716 return new IntersectionObserver(entries
=> this._observerCallback(entries
), options
);
5719 // The logic of selection
5720 _observerCallback(entries
) {
5721 const targetElement
= entry
=> this._targetLinks
.get(`#${entry.target.id}`);
5722 const activate
= entry
=> {
5723 this._previousScrollData
.visibleEntryTop
= entry
.target
.offsetTop
;
5724 this._process(targetElement(entry
));
5726 const parentScrollTop
= (this._rootElement
|| document
.documentElement
).scrollTop
;
5727 const userScrollsDown
= parentScrollTop
>= this._previousScrollData
.parentScrollTop
;
5728 this._previousScrollData
.parentScrollTop
= parentScrollTop
;
5729 for (const entry
of entries
) {
5730 if (!entry
.isIntersecting
) {
5731 this._activeTarget
= null;
5732 this._clearActiveClass(targetElement(entry
));
5735 const entryIsLowerThanPrevious
= entry
.target
.offsetTop
>= this._previousScrollData
.visibleEntryTop
;
5736 // if we are scrolling down, pick the bigger offsetTop
5737 if (userScrollsDown
&& entryIsLowerThanPrevious
) {
5739 // if parent isn't scrolled, let's keep the first visible item, breaking the iteration
5740 if (!parentScrollTop
) {
5746 // if we are scrolling up, pick the smallest offsetTop
5747 if (!userScrollsDown
&& !entryIsLowerThanPrevious
) {
5752 _initializeTargetsAndObservables() {
5753 this._targetLinks
= new Map();
5754 this._observableSections
= new Map();
5755 const targetLinks
= SelectorEngine
.find(SELECTOR_TARGET_LINKS
, this._config
.target
);
5756 for (const anchor
of targetLinks
) {
5757 // ensure that the anchor has an id and is not disabled
5758 if (!anchor
.hash
|| isDisabled(anchor
)) {
5761 const observableSection
= SelectorEngine
.findOne(decodeURI(anchor
.hash
), this._element
);
5763 // ensure that the observableSection exists & is visible
5764 if (isVisible(observableSection
)) {
5765 this._targetLinks
.set(decodeURI(anchor
.hash
), anchor
);
5766 this._observableSections
.set(anchor
.hash
, observableSection
);
5771 if (this._activeTarget
=== target
) {
5774 this._clearActiveClass(this._config
.target
);
5775 this._activeTarget
= target
;
5776 target
.classList
.add(CLASS_NAME_ACTIVE
$1);
5777 this._activateParents(target
);
5778 EventHandler
.trigger(this._element
, EVENT_ACTIVATE
, {
5779 relatedTarget: target
5782 _activateParents(target
) {
5783 // Activate dropdown parents
5784 if (target
.classList
.contains(CLASS_NAME_DROPDOWN_ITEM
)) {
5785 SelectorEngine
.findOne(SELECTOR_DROPDOWN_TOGGLE
$1, target
.closest(SELECTOR_DROPDOWN
)).classList
.add(CLASS_NAME_ACTIVE
$1);
5788 for (const listGroup
of SelectorEngine
.parents(target
, SELECTOR_NAV_LIST_GROUP
)) {
5789 // Set triggered links parents as active
5790 // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
5791 for (const item
of SelectorEngine
.prev(listGroup
, SELECTOR_LINK_ITEMS
)) {
5792 item
.classList
.add(CLASS_NAME_ACTIVE
$1);
5796 _clearActiveClass(parent
) {
5797 parent
.classList
.remove(CLASS_NAME_ACTIVE
$1);
5798 const activeNodes
= SelectorEngine
.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE$1}`, parent
);
5799 for (const node
of activeNodes
) {
5800 node
.classList
.remove(CLASS_NAME_ACTIVE
$1);
5805 static jQueryInterface(config
) {
5806 return this.each(function () {
5807 const data
= ScrollSpy
.getOrCreateInstance(this, config
);
5808 if (typeof config
!== 'string') {
5811 if (data
[config
] === undefined || config
.startsWith('_') || config
=== 'constructor') {
5812 throw new TypeError(`No method named "${config}"`);
5820 * Data API implementation
5823 EventHandler
.on(window
, EVENT_LOAD_DATA_API
$1, () => {
5824 for (const spy
of SelectorEngine
.find(SELECTOR_DATA_SPY
)) {
5825 ScrollSpy
.getOrCreateInstance(spy
);
5833 defineJQueryPlugin(ScrollSpy
);
5836 * --------------------------------------------------------------------------
5838 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5839 * --------------------------------------------------------------------------
5847 const NAME
$1 = 'tab';
5848 const DATA_KEY
$1 = 'bs.tab';
5849 const EVENT_KEY
$1 = `.${DATA_KEY$1}`;
5850 const EVENT_HIDE
$1 = `hide${EVENT_KEY$1}`;
5851 const EVENT_HIDDEN
$1 = `hidden${EVENT_KEY$1}`;
5852 const EVENT_SHOW
$1 = `show${EVENT_KEY$1}`;
5853 const EVENT_SHOWN
$1 = `shown${EVENT_KEY$1}`;
5854 const EVENT_CLICK_DATA_API
= `click${EVENT_KEY$1}`;
5855 const EVENT_KEYDOWN
= `keydown${EVENT_KEY$1}`;
5856 const EVENT_LOAD_DATA_API
= `load${EVENT_KEY$1}`;
5857 const ARROW_LEFT_KEY
= 'ArrowLeft';
5858 const ARROW_RIGHT_KEY
= 'ArrowRight';
5859 const ARROW_UP_KEY
= 'ArrowUp';
5860 const ARROW_DOWN_KEY
= 'ArrowDown';
5861 const HOME_KEY
= 'Home';
5862 const END_KEY
= 'End';
5863 const CLASS_NAME_ACTIVE
= 'active';
5864 const CLASS_NAME_FADE
$1 = 'fade';
5865 const CLASS_NAME_SHOW
$1 = 'show';
5866 const CLASS_DROPDOWN
= 'dropdown';
5867 const SELECTOR_DROPDOWN_TOGGLE
= '.dropdown-toggle';
5868 const SELECTOR_DROPDOWN_MENU
= '.dropdown-menu';
5869 const NOT_SELECTOR_DROPDOWN_TOGGLE
= `:not(${SELECTOR_DROPDOWN_TOGGLE})`;
5870 const SELECTOR_TAB_PANEL
= '.list-group, .nav, [role="tablist"]';
5871 const SELECTOR_OUTER
= '.nav-item, .list-group-item';
5872 const SELECTOR_INNER
= `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`;
5873 const SELECTOR_DATA_TOGGLE
= '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // TODO: could only be `tab` in v6
5874 const SELECTOR_INNER_ELEM
= `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;
5875 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"]`;
5881 class Tab
extends BaseComponent
{
5882 constructor(element
) {
5884 this._parent
= this._element
.closest(SELECTOR_TAB_PANEL
);
5885 if (!this._parent
) {
5887 // TODO: should throw exception in v6
5888 // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)
5891 // Set up initial aria attributes
5892 this._setInitialAttributes(this._parent
, this._getChildren());
5893 EventHandler
.on(this._element
, EVENT_KEYDOWN
, event
=> this._keydown(event
));
5903 // Shows this elem and deactivate the active sibling if exists
5904 const innerElem
= this._element
;
5905 if (this._elemIsActive(innerElem
)) {
5909 // Search for active tab on same parent to deactivate it
5910 const active
= this._getActiveElem();
5911 const hideEvent
= active
? EventHandler
.trigger(active
, EVENT_HIDE
$1, {
5912 relatedTarget: innerElem
5914 const showEvent
= EventHandler
.trigger(innerElem
, EVENT_SHOW
$1, {
5915 relatedTarget: active
5917 if (showEvent
.defaultPrevented
|| hideEvent
&& hideEvent
.defaultPrevented
) {
5920 this._deactivate(active
, innerElem
);
5921 this._activate(innerElem
, active
);
5925 _activate(element
, relatedElem
) {
5929 element
.classList
.add(CLASS_NAME_ACTIVE
);
5930 this._activate(SelectorEngine
.getElementFromSelector(element
)); // Search and activate/show the proper section
5932 const complete
= () => {
5933 if (element
.getAttribute('role') !== 'tab') {
5934 element
.classList
.add(CLASS_NAME_SHOW
$1);
5937 element
.removeAttribute('tabindex');
5938 element
.setAttribute('aria-selected', true);
5939 this._toggleDropDown(element
, true);
5940 EventHandler
.trigger(element
, EVENT_SHOWN
$1, {
5941 relatedTarget: relatedElem
5944 this._queueCallback(complete
, element
, element
.classList
.contains(CLASS_NAME_FADE
$1));
5946 _deactivate(element
, relatedElem
) {
5950 element
.classList
.remove(CLASS_NAME_ACTIVE
);
5952 this._deactivate(SelectorEngine
.getElementFromSelector(element
)); // Search and deactivate the shown section too
5954 const complete
= () => {
5955 if (element
.getAttribute('role') !== 'tab') {
5956 element
.classList
.remove(CLASS_NAME_SHOW
$1);
5959 element
.setAttribute('aria-selected', false);
5960 element
.setAttribute('tabindex', '-1');
5961 this._toggleDropDown(element
, false);
5962 EventHandler
.trigger(element
, EVENT_HIDDEN
$1, {
5963 relatedTarget: relatedElem
5966 this._queueCallback(complete
, element
, element
.classList
.contains(CLASS_NAME_FADE
$1));
5969 if (![ARROW_LEFT_KEY
, ARROW_RIGHT_KEY
, ARROW_UP_KEY
, ARROW_DOWN_KEY
, HOME_KEY
, END_KEY
].includes(event
.key
)) {
5972 event
.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page
5973 event
.preventDefault();
5974 const children
= this._getChildren().filter(element
=> !isDisabled(element
));
5975 let nextActiveElement
;
5976 if ([HOME_KEY
, END_KEY
].includes(event
.key
)) {
5977 nextActiveElement
= children
[event
.key
=== HOME_KEY
? 0 : children
.length
- 1];
5979 const isNext
= [ARROW_RIGHT_KEY
, ARROW_DOWN_KEY
].includes(event
.key
);
5980 nextActiveElement
= getNextActiveElement(children
, event
.target
, isNext
, true);
5982 if (nextActiveElement
) {
5983 nextActiveElement
.focus({
5986 Tab
.getOrCreateInstance(nextActiveElement
).show();
5990 // collection of inner elements
5991 return SelectorEngine
.find(SELECTOR_INNER_ELEM
, this._parent
);
5994 return this._getChildren().find(child
=> this._elemIsActive(child
)) || null;
5996 _setInitialAttributes(parent
, children
) {
5997 this._setAttributeIfNotExists(parent
, 'role', 'tablist');
5998 for (const child
of children
) {
5999 this._setInitialAttributesOnChild(child
);
6002 _setInitialAttributesOnChild(child
) {
6003 child
= this._getInnerElement(child
);
6004 const isActive
= this._elemIsActive(child
);
6005 const outerElem
= this._getOuterElement(child
);
6006 child
.setAttribute('aria-selected', isActive
);
6007 if (outerElem
!== child
) {
6008 this._setAttributeIfNotExists(outerElem
, 'role', 'presentation');
6011 child
.setAttribute('tabindex', '-1');
6013 this._setAttributeIfNotExists(child
, 'role', 'tab');
6015 // set attributes to the related panel too
6016 this._setInitialAttributesOnTargetPanel(child
);
6018 _setInitialAttributesOnTargetPanel(child
) {
6019 const target
= SelectorEngine
.getElementFromSelector(child
);
6023 this._setAttributeIfNotExists(target
, 'role', 'tabpanel');
6025 this._setAttributeIfNotExists(target
, 'aria-labelledby', `${child.id}`);
6028 _toggleDropDown(element
, open
) {
6029 const outerElem
= this._getOuterElement(element
);
6030 if (!outerElem
.classList
.contains(CLASS_DROPDOWN
)) {
6033 const toggle
= (selector
, className
) => {
6034 const element
= SelectorEngine
.findOne(selector
, outerElem
);
6036 element
.classList
.toggle(className
, open
);
6039 toggle(SELECTOR_DROPDOWN_TOGGLE
, CLASS_NAME_ACTIVE
);
6040 toggle(SELECTOR_DROPDOWN_MENU
, CLASS_NAME_SHOW
$1);
6041 outerElem
.setAttribute('aria-expanded', open
);
6043 _setAttributeIfNotExists(element
, attribute
, value
) {
6044 if (!element
.hasAttribute(attribute
)) {
6045 element
.setAttribute(attribute
, value
);
6048 _elemIsActive(elem
) {
6049 return elem
.classList
.contains(CLASS_NAME_ACTIVE
);
6052 // Try to get the inner element (usually the .nav-link)
6053 _getInnerElement(elem
) {
6054 return elem
.matches(SELECTOR_INNER_ELEM
) ? elem : SelectorEngine
.findOne(SELECTOR_INNER_ELEM
, elem
);
6057 // Try to get the outer element (usually the .nav-item)
6058 _getOuterElement(elem
) {
6059 return elem
.closest(SELECTOR_OUTER
) || elem
;
6063 static jQueryInterface(config
) {
6064 return this.each(function () {
6065 const data
= Tab
.getOrCreateInstance(this);
6066 if (typeof config
!== 'string') {
6069 if (data
[config
] === undefined || config
.startsWith('_') || config
=== 'constructor') {
6070 throw new TypeError(`No method named "${config}"`);
6078 * Data API implementation
6081 EventHandler
.on(document
, EVENT_CLICK_DATA_API
, SELECTOR_DATA_TOGGLE
, function (event
) {
6082 if (['A', 'AREA'].includes(this.tagName
)) {
6083 event
.preventDefault();
6085 if (isDisabled(this)) {
6088 Tab
.getOrCreateInstance(this).show();
6092 * Initialize on focus
6094 EventHandler
.on(window
, EVENT_LOAD_DATA_API
, () => {
6095 for (const element
of SelectorEngine
.find(SELECTOR_DATA_TOGGLE_ACTIVE
)) {
6096 Tab
.getOrCreateInstance(element
);
6103 defineJQueryPlugin(Tab
);
6106 * --------------------------------------------------------------------------
6107 * Bootstrap toast.js
6108 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
6109 * --------------------------------------------------------------------------
6117 const NAME
= 'toast';
6118 const DATA_KEY
= 'bs.toast';
6119 const EVENT_KEY
= `.${DATA_KEY}`;
6120 const EVENT_MOUSEOVER
= `mouseover${EVENT_KEY}`;
6121 const EVENT_MOUSEOUT
= `mouseout${EVENT_KEY}`;
6122 const EVENT_FOCUSIN
= `focusin${EVENT_KEY}`;
6123 const EVENT_FOCUSOUT
= `focusout${EVENT_KEY}`;
6124 const EVENT_HIDE
= `hide${EVENT_KEY}`;
6125 const EVENT_HIDDEN
= `hidden${EVENT_KEY}`;
6126 const EVENT_SHOW
= `show${EVENT_KEY}`;
6127 const EVENT_SHOWN
= `shown${EVENT_KEY}`;
6128 const CLASS_NAME_FADE
= 'fade';
6129 const CLASS_NAME_HIDE
= 'hide'; // @deprecated - kept here only for backwards compatibility
6130 const CLASS_NAME_SHOW
= 'show';
6131 const CLASS_NAME_SHOWING
= 'showing';
6132 const DefaultType
= {
6133 animation: 'boolean',
6134 autohide: 'boolean',
6147 class Toast
extends BaseComponent
{
6148 constructor(element
, config
) {
6149 super(element
, config
);
6150 this._timeout
= null;
6151 this._hasMouseInteraction
= false;
6152 this._hasKeyboardInteraction
= false;
6153 this._setListeners();
6157 static get Default() {
6160 static get DefaultType() {
6169 const showEvent
= EventHandler
.trigger(this._element
, EVENT_SHOW
);
6170 if (showEvent
.defaultPrevented
) {
6173 this._clearTimeout();
6174 if (this._config
.animation
) {
6175 this._element
.classList
.add(CLASS_NAME_FADE
);
6177 const complete
= () => {
6178 this._element
.classList
.remove(CLASS_NAME_SHOWING
);
6179 EventHandler
.trigger(this._element
, EVENT_SHOWN
);
6180 this._maybeScheduleHide();
6182 this._element
.classList
.remove(CLASS_NAME_HIDE
); // @deprecated
6183 reflow(this._element
);
6184 this._element
.classList
.add(CLASS_NAME_SHOW
, CLASS_NAME_SHOWING
);
6185 this._queueCallback(complete
, this._element
, this._config
.animation
);
6188 if (!this.isShown()) {
6191 const hideEvent
= EventHandler
.trigger(this._element
, EVENT_HIDE
);
6192 if (hideEvent
.defaultPrevented
) {
6195 const complete
= () => {
6196 this._element
.classList
.add(CLASS_NAME_HIDE
); // @deprecated
6197 this._element
.classList
.remove(CLASS_NAME_SHOWING
, CLASS_NAME_SHOW
);
6198 EventHandler
.trigger(this._element
, EVENT_HIDDEN
);
6200 this._element
.classList
.add(CLASS_NAME_SHOWING
);
6201 this._queueCallback(complete
, this._element
, this._config
.animation
);
6204 this._clearTimeout();
6205 if (this.isShown()) {
6206 this._element
.classList
.remove(CLASS_NAME_SHOW
);
6211 return this._element
.classList
.contains(CLASS_NAME_SHOW
);
6216 _maybeScheduleHide() {
6217 if (!this._config
.autohide
) {
6220 if (this._hasMouseInteraction
|| this._hasKeyboardInteraction
) {
6223 this._timeout
= setTimeout(() => {
6225 }, this._config
.delay
);
6227 _onInteraction(event
, isInteracting
) {
6228 switch (event
.type
) {
6232 this._hasMouseInteraction
= isInteracting
;
6238 this._hasKeyboardInteraction
= isInteracting
;
6242 if (isInteracting
) {
6243 this._clearTimeout();
6246 const nextElement
= event
.relatedTarget
;
6247 if (this._element
=== nextElement
|| this._element
.contains(nextElement
)) {
6250 this._maybeScheduleHide();
6253 EventHandler
.on(this._element
, EVENT_MOUSEOVER
, event
=> this._onInteraction(event
, true));
6254 EventHandler
.on(this._element
, EVENT_MOUSEOUT
, event
=> this._onInteraction(event
, false));
6255 EventHandler
.on(this._element
, EVENT_FOCUSIN
, event
=> this._onInteraction(event
, true));
6256 EventHandler
.on(this._element
, EVENT_FOCUSOUT
, event
=> this._onInteraction(event
, false));
6259 clearTimeout(this._timeout
);
6260 this._timeout
= null;
6264 static jQueryInterface(config
) {
6265 return this.each(function () {
6266 const data
= Toast
.getOrCreateInstance(this, config
);
6267 if (typeof config
=== 'string') {
6268 if (typeof data
[config
] === 'undefined') {
6269 throw new TypeError(`No method named "${config}"`);
6278 * Data API implementation
6281 enableDismissTrigger(Toast
);
6287 defineJQueryPlugin(Toast
);
6290 * --------------------------------------------------------------------------
6291 * Bootstrap index.umd.js
6292 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
6293 * --------------------------------------------------------------------------
6314 //# sourceMappingURL=bootstrap.bundle.js.map