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