source: imaps-frontend/node_modules/bootstrap/dist/js/bootstrap.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 142.0 KB
Line 
1/*!
2 * Bootstrap v5.3.3 (https://getbootstrap.com/)
3 * Copyright 2011-2024 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 const getjQuery = () => {
233 if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
234 return window.jQuery;
235 }
236 return null;
237 };
238 const DOMContentLoadedCallbacks = [];
239 const onDOMContentLoaded = callback => {
240 if (document.readyState === 'loading') {
241 // add listener on the first call when the document is in loading state
242 if (!DOMContentLoadedCallbacks.length) {
243 document.addEventListener('DOMContentLoaded', () => {
244 for (const callback of DOMContentLoadedCallbacks) {
245 callback();
246 }
247 });
248 }
249 DOMContentLoadedCallbacks.push(callback);
250 } else {
251 callback();
252 }
253 };
254 const isRTL = () => document.documentElement.dir === 'rtl';
255 const defineJQueryPlugin = plugin => {
256 onDOMContentLoaded(() => {
257 const $ = getjQuery();
258 /* istanbul ignore if */
259 if ($) {
260 const name = plugin.NAME;
261 const JQUERY_NO_CONFLICT = $.fn[name];
262 $.fn[name] = plugin.jQueryInterface;
263 $.fn[name].Constructor = plugin;
264 $.fn[name].noConflict = () => {
265 $.fn[name] = JQUERY_NO_CONFLICT;
266 return plugin.jQueryInterface;
267 };
268 }
269 });
270 };
271 const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
272 return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue;
273 };
274 const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
275 if (!waitForTransition) {
276 execute(callback);
277 return;
278 }
279 const durationPadding = 5;
280 const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
281 let called = false;
282 const handler = ({
283 target
284 }) => {
285 if (target !== transitionElement) {
286 return;
287 }
288 called = true;
289 transitionElement.removeEventListener(TRANSITION_END, handler);
290 execute(callback);
291 };
292 transitionElement.addEventListener(TRANSITION_END, handler);
293 setTimeout(() => {
294 if (!called) {
295 triggerTransitionEnd(transitionElement);
296 }
297 }, emulatedDuration);
298 };
299
300 /**
301 * Return the previous/next element of a list.
302 *
303 * @param {array} list The list of elements
304 * @param activeElement The active element
305 * @param shouldGetNext Choose to get next or previous element
306 * @param isCycleAllowed
307 * @return {Element|elem} The proper element
308 */
309 const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
310 const listLength = list.length;
311 let index = list.indexOf(activeElement);
312
313 // if the element does not exist in the list return an element
314 // depending on the direction and if cycle is allowed
315 if (index === -1) {
316 return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
317 }
318 index += shouldGetNext ? 1 : -1;
319 if (isCycleAllowed) {
320 index = (index + listLength) % listLength;
321 }
322 return list[Math.max(0, Math.min(index, listLength - 1))];
323 };
324
325 /**
326 * --------------------------------------------------------------------------
327 * Bootstrap dom/event-handler.js
328 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
329 * --------------------------------------------------------------------------
330 */
331
332
333 /**
334 * Constants
335 */
336
337 const namespaceRegex = /[^.]*(?=\..*)\.|.*/;
338 const stripNameRegex = /\..*/;
339 const stripUidRegex = /::\d+$/;
340 const eventRegistry = {}; // Events storage
341 let uidEvent = 1;
342 const customEvents = {
343 mouseenter: 'mouseover',
344 mouseleave: 'mouseout'
345 };
346 const nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);
347
348 /**
349 * Private methods
350 */
351
352 function makeEventUid(element, uid) {
353 return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;
354 }
355 function getElementEvents(element) {
356 const uid = makeEventUid(element);
357 element.uidEvent = uid;
358 eventRegistry[uid] = eventRegistry[uid] || {};
359 return eventRegistry[uid];
360 }
361 function bootstrapHandler(element, fn) {
362 return function handler(event) {
363 hydrateObj(event, {
364 delegateTarget: element
365 });
366 if (handler.oneOff) {
367 EventHandler.off(element, event.type, fn);
368 }
369 return fn.apply(element, [event]);
370 };
371 }
372 function bootstrapDelegationHandler(element, selector, fn) {
373 return function handler(event) {
374 const domElements = element.querySelectorAll(selector);
375 for (let {
376 target
377 } = event; target && target !== this; target = target.parentNode) {
378 for (const domElement of domElements) {
379 if (domElement !== target) {
380 continue;
381 }
382 hydrateObj(event, {
383 delegateTarget: target
384 });
385 if (handler.oneOff) {
386 EventHandler.off(element, event.type, selector, fn);
387 }
388 return fn.apply(target, [event]);
389 }
390 }
391 };
392 }
393 function findHandler(events, callable, delegationSelector = null) {
394 return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector);
395 }
396 function normalizeParameters(originalTypeEvent, handler, delegationFunction) {
397 const isDelegated = typeof handler === 'string';
398 // TODO: tooltip passes `false` instead of selector, so we need to check
399 const callable = isDelegated ? delegationFunction : handler || delegationFunction;
400 let typeEvent = getTypeEvent(originalTypeEvent);
401 if (!nativeEvents.has(typeEvent)) {
402 typeEvent = originalTypeEvent;
403 }
404 return [isDelegated, callable, typeEvent];
405 }
406 function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {
407 if (typeof originalTypeEvent !== 'string' || !element) {
408 return;
409 }
410 let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);
411
412 // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
413 // this prevents the handler from being dispatched the same way as mouseover or mouseout does
414 if (originalTypeEvent in customEvents) {
415 const wrapFunction = fn => {
416 return function (event) {
417 if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {
418 return fn.call(this, event);
419 }
420 };
421 };
422 callable = wrapFunction(callable);
423 }
424 const events = getElementEvents(element);
425 const handlers = events[typeEvent] || (events[typeEvent] = {});
426 const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);
427 if (previousFunction) {
428 previousFunction.oneOff = previousFunction.oneOff && oneOff;
429 return;
430 }
431 const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));
432 const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable);
433 fn.delegationSelector = isDelegated ? handler : null;
434 fn.callable = callable;
435 fn.oneOff = oneOff;
436 fn.uidEvent = uid;
437 handlers[uid] = fn;
438 element.addEventListener(typeEvent, fn, isDelegated);
439 }
440 function removeHandler(element, events, typeEvent, handler, delegationSelector) {
441 const fn = findHandler(events[typeEvent], handler, delegationSelector);
442 if (!fn) {
443 return;
444 }
445 element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));
446 delete events[typeEvent][fn.uidEvent];
447 }
448 function removeNamespacedHandlers(element, events, typeEvent, namespace) {
449 const storeElementEvent = events[typeEvent] || {};
450 for (const [handlerKey, event] of Object.entries(storeElementEvent)) {
451 if (handlerKey.includes(namespace)) {
452 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
453 }
454 }
455 }
456 function getTypeEvent(event) {
457 // allow to get the native events from namespaced events ('click.bs.button' --> 'click')
458 event = event.replace(stripNameRegex, '');
459 return customEvents[event] || event;
460 }
461 const EventHandler = {
462 on(element, event, handler, delegationFunction) {
463 addHandler(element, event, handler, delegationFunction, false);
464 },
465 one(element, event, handler, delegationFunction) {
466 addHandler(element, event, handler, delegationFunction, true);
467 },
468 off(element, originalTypeEvent, handler, delegationFunction) {
469 if (typeof originalTypeEvent !== 'string' || !element) {
470 return;
471 }
472 const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);
473 const inNamespace = typeEvent !== originalTypeEvent;
474 const events = getElementEvents(element);
475 const storeElementEvent = events[typeEvent] || {};
476 const isNamespace = originalTypeEvent.startsWith('.');
477 if (typeof callable !== 'undefined') {
478 // Simplest case: handler is passed, remove that listener ONLY.
479 if (!Object.keys(storeElementEvent).length) {
480 return;
481 }
482 removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);
483 return;
484 }
485 if (isNamespace) {
486 for (const elementEvent of Object.keys(events)) {
487 removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));
488 }
489 }
490 for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {
491 const handlerKey = keyHandlers.replace(stripUidRegex, '');
492 if (!inNamespace || originalTypeEvent.includes(handlerKey)) {
493 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
494 }
495 }
496 },
497 trigger(element, event, args) {
498 if (typeof event !== 'string' || !element) {
499 return null;
500 }
501 const $ = getjQuery();
502 const typeEvent = getTypeEvent(event);
503 const inNamespace = event !== typeEvent;
504 let jQueryEvent = null;
505 let bubbles = true;
506 let nativeDispatch = true;
507 let defaultPrevented = false;
508 if (inNamespace && $) {
509 jQueryEvent = $.Event(event, args);
510 $(element).trigger(jQueryEvent);
511 bubbles = !jQueryEvent.isPropagationStopped();
512 nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
513 defaultPrevented = jQueryEvent.isDefaultPrevented();
514 }
515 const evt = hydrateObj(new Event(event, {
516 bubbles,
517 cancelable: true
518 }), args);
519 if (defaultPrevented) {
520 evt.preventDefault();
521 }
522 if (nativeDispatch) {
523 element.dispatchEvent(evt);
524 }
525 if (evt.defaultPrevented && jQueryEvent) {
526 jQueryEvent.preventDefault();
527 }
528 return evt;
529 }
530 };
531 function hydrateObj(obj, meta = {}) {
532 for (const [key, value] of Object.entries(meta)) {
533 try {
534 obj[key] = value;
535 } catch (_unused) {
536 Object.defineProperty(obj, key, {
537 configurable: true,
538 get() {
539 return value;
540 }
541 });
542 }
543 }
544 return obj;
545 }
546
547 /**
548 * --------------------------------------------------------------------------
549 * Bootstrap dom/manipulator.js
550 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
551 * --------------------------------------------------------------------------
552 */
553
554 function normalizeData(value) {
555 if (value === 'true') {
556 return true;
557 }
558 if (value === 'false') {
559 return false;
560 }
561 if (value === Number(value).toString()) {
562 return Number(value);
563 }
564 if (value === '' || value === 'null') {
565 return null;
566 }
567 if (typeof value !== 'string') {
568 return value;
569 }
570 try {
571 return JSON.parse(decodeURIComponent(value));
572 } catch (_unused) {
573 return value;
574 }
575 }
576 function normalizeDataKey(key) {
577 return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);
578 }
579 const Manipulator = {
580 setDataAttribute(element, key, value) {
581 element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);
582 },
583 removeDataAttribute(element, key) {
584 element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);
585 },
586 getDataAttributes(element) {
587 if (!element) {
588 return {};
589 }
590 const attributes = {};
591 const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'));
592 for (const key of bsKeys) {
593 let pureKey = key.replace(/^bs/, '');
594 pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);
595 attributes[pureKey] = normalizeData(element.dataset[key]);
596 }
597 return attributes;
598 },
599 getDataAttribute(element, key) {
600 return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));
601 }
602 };
603
604 /**
605 * --------------------------------------------------------------------------
606 * Bootstrap util/config.js
607 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
608 * --------------------------------------------------------------------------
609 */
610
611
612 /**
613 * Class definition
614 */
615
616 class Config {
617 // Getters
618 static get Default() {
619 return {};
620 }
621 static get DefaultType() {
622 return {};
623 }
624 static get NAME() {
625 throw new Error('You have to implement the static method "NAME", for each component!');
626 }
627 _getConfig(config) {
628 config = this._mergeConfigObj(config);
629 config = this._configAfterMerge(config);
630 this._typeCheckConfig(config);
631 return config;
632 }
633 _configAfterMerge(config) {
634 return config;
635 }
636 _mergeConfigObj(config, element) {
637 const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse
638
639 return {
640 ...this.constructor.Default,
641 ...(typeof jsonConfig === 'object' ? jsonConfig : {}),
642 ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),
643 ...(typeof config === 'object' ? config : {})
644 };
645 }
646 _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {
647 for (const [property, expectedTypes] of Object.entries(configTypes)) {
648 const value = config[property];
649 const valueType = isElement(value) ? 'element' : toType(value);
650 if (!new RegExp(expectedTypes).test(valueType)) {
651 throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
652 }
653 }
654 }
655 }
656
657 /**
658 * --------------------------------------------------------------------------
659 * Bootstrap base-component.js
660 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
661 * --------------------------------------------------------------------------
662 */
663
664
665 /**
666 * Constants
667 */
668
669 const VERSION = '5.3.3';
670
671 /**
672 * Class definition
673 */
674
675 class BaseComponent extends Config {
676 constructor(element, config) {
677 super();
678 element = getElement(element);
679 if (!element) {
680 return;
681 }
682 this._element = element;
683 this._config = this._getConfig(config);
684 Data.set(this._element, this.constructor.DATA_KEY, this);
685 }
686
687 // Public
688 dispose() {
689 Data.remove(this._element, this.constructor.DATA_KEY);
690 EventHandler.off(this._element, this.constructor.EVENT_KEY);
691 for (const propertyName of Object.getOwnPropertyNames(this)) {
692 this[propertyName] = null;
693 }
694 }
695 _queueCallback(callback, element, isAnimated = true) {
696 executeAfterTransition(callback, element, isAnimated);
697 }
698 _getConfig(config) {
699 config = this._mergeConfigObj(config, this._element);
700 config = this._configAfterMerge(config);
701 this._typeCheckConfig(config);
702 return config;
703 }
704
705 // Static
706 static getInstance(element) {
707 return Data.get(getElement(element), this.DATA_KEY);
708 }
709 static getOrCreateInstance(element, config = {}) {
710 return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);
711 }
712 static get VERSION() {
713 return VERSION;
714 }
715 static get DATA_KEY() {
716 return `bs.${this.NAME}`;
717 }
718 static get EVENT_KEY() {
719 return `.${this.DATA_KEY}`;
720 }
721 static eventName(name) {
722 return `${name}${this.EVENT_KEY}`;
723 }
724 }
725
726 /**
727 * --------------------------------------------------------------------------
728 * Bootstrap dom/selector-engine.js
729 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
730 * --------------------------------------------------------------------------
731 */
732
733 const getSelector = element => {
734 let selector = element.getAttribute('data-bs-target');
735 if (!selector || selector === '#') {
736 let hrefAttribute = element.getAttribute('href');
737
738 // The only valid content that could double as a selector are IDs or classes,
739 // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
740 // `document.querySelector` will rightfully complain it is invalid.
741 // See https://github.com/twbs/bootstrap/issues/32273
742 if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {
743 return null;
744 }
745
746 // Just in case some CMS puts out a full URL with the anchor appended
747 if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {
748 hrefAttribute = `#${hrefAttribute.split('#')[1]}`;
749 }
750 selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null;
751 }
752 return selector ? selector.split(',').map(sel => parseSelector(sel)).join(',') : null;
753 };
754 const SelectorEngine = {
755 find(selector, element = document.documentElement) {
756 return [].concat(...Element.prototype.querySelectorAll.call(element, selector));
757 },
758 findOne(selector, element = document.documentElement) {
759 return Element.prototype.querySelector.call(element, selector);
760 },
761 children(element, selector) {
762 return [].concat(...element.children).filter(child => child.matches(selector));
763 },
764 parents(element, selector) {
765 const parents = [];
766 let ancestor = element.parentNode.closest(selector);
767 while (ancestor) {
768 parents.push(ancestor);
769 ancestor = ancestor.parentNode.closest(selector);
770 }
771 return parents;
772 },
773 prev(element, selector) {
774 let previous = element.previousElementSibling;
775 while (previous) {
776 if (previous.matches(selector)) {
777 return [previous];
778 }
779 previous = previous.previousElementSibling;
780 }
781 return [];
782 },
783 // TODO: this is now unused; remove later along with prev()
784 next(element, selector) {
785 let next = element.nextElementSibling;
786 while (next) {
787 if (next.matches(selector)) {
788 return [next];
789 }
790 next = next.nextElementSibling;
791 }
792 return [];
793 },
794 focusableChildren(element) {
795 const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `${selector}:not([tabindex^="-"])`).join(',');
796 return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));
797 },
798 getSelectorFromElement(element) {
799 const selector = getSelector(element);
800 if (selector) {
801 return SelectorEngine.findOne(selector) ? selector : null;
802 }
803 return null;
804 },
805 getElementFromSelector(element) {
806 const selector = getSelector(element);
807 return selector ? SelectorEngine.findOne(selector) : null;
808 },
809 getMultipleElementsFromSelector(element) {
810 const selector = getSelector(element);
811 return selector ? SelectorEngine.find(selector) : [];
812 }
813 };
814
815 /**
816 * --------------------------------------------------------------------------
817 * Bootstrap util/component-functions.js
818 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
819 * --------------------------------------------------------------------------
820 */
821
822 const enableDismissTrigger = (component, method = 'hide') => {
823 const clickEvent = `click.dismiss${component.EVENT_KEY}`;
824 const name = component.NAME;
825 EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
826 if (['A', 'AREA'].includes(this.tagName)) {
827 event.preventDefault();
828 }
829 if (isDisabled(this)) {
830 return;
831 }
832 const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`);
833 const instance = component.getOrCreateInstance(target);
834
835 // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
836 instance[method]();
837 });
838 };
839
840 /**
841 * --------------------------------------------------------------------------
842 * Bootstrap alert.js
843 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
844 * --------------------------------------------------------------------------
845 */
846
847
848 /**
849 * Constants
850 */
851
852 const NAME$f = 'alert';
853 const DATA_KEY$a = 'bs.alert';
854 const EVENT_KEY$b = `.${DATA_KEY$a}`;
855 const EVENT_CLOSE = `close${EVENT_KEY$b}`;
856 const EVENT_CLOSED = `closed${EVENT_KEY$b}`;
857 const CLASS_NAME_FADE$5 = 'fade';
858 const CLASS_NAME_SHOW$8 = 'show';
859
860 /**
861 * Class definition
862 */
863
864 class Alert extends BaseComponent {
865 // Getters
866 static get NAME() {
867 return NAME$f;
868 }
869
870 // Public
871 close() {
872 const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);
873 if (closeEvent.defaultPrevented) {
874 return;
875 }
876 this._element.classList.remove(CLASS_NAME_SHOW$8);
877 const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);
878 this._queueCallback(() => this._destroyElement(), this._element, isAnimated);
879 }
880
881 // Private
882 _destroyElement() {
883 this._element.remove();
884 EventHandler.trigger(this._element, EVENT_CLOSED);
885 this.dispose();
886 }
887
888 // Static
889 static jQueryInterface(config) {
890 return this.each(function () {
891 const data = Alert.getOrCreateInstance(this);
892 if (typeof config !== 'string') {
893 return;
894 }
895 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
896 throw new TypeError(`No method named "${config}"`);
897 }
898 data[config](this);
899 });
900 }
901 }
902
903 /**
904 * Data API implementation
905 */
906
907 enableDismissTrigger(Alert, 'close');
908
909 /**
910 * jQuery
911 */
912
913 defineJQueryPlugin(Alert);
914
915 /**
916 * --------------------------------------------------------------------------
917 * Bootstrap button.js
918 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
919 * --------------------------------------------------------------------------
920 */
921
922
923 /**
924 * Constants
925 */
926
927 const NAME$e = 'button';
928 const DATA_KEY$9 = 'bs.button';
929 const EVENT_KEY$a = `.${DATA_KEY$9}`;
930 const DATA_API_KEY$6 = '.data-api';
931 const CLASS_NAME_ACTIVE$3 = 'active';
932 const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle="button"]';
933 const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;
934
935 /**
936 * Class definition
937 */
938
939 class Button extends BaseComponent {
940 // Getters
941 static get NAME() {
942 return NAME$e;
943 }
944
945 // Public
946 toggle() {
947 // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
948 this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));
949 }
950
951 // Static
952 static jQueryInterface(config) {
953 return this.each(function () {
954 const data = Button.getOrCreateInstance(this);
955 if (config === 'toggle') {
956 data[config]();
957 }
958 });
959 }
960 }
961
962 /**
963 * Data API implementation
964 */
965
966 EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {
967 event.preventDefault();
968 const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);
969 const data = Button.getOrCreateInstance(button);
970 data.toggle();
971 });
972
973 /**
974 * jQuery
975 */
976
977 defineJQueryPlugin(Button);
978
979 /**
980 * --------------------------------------------------------------------------
981 * Bootstrap util/swipe.js
982 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
983 * --------------------------------------------------------------------------
984 */
985
986
987 /**
988 * Constants
989 */
990
991 const NAME$d = 'swipe';
992 const EVENT_KEY$9 = '.bs.swipe';
993 const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`;
994 const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`;
995 const EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`;
996 const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`;
997 const EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`;
998 const POINTER_TYPE_TOUCH = 'touch';
999 const POINTER_TYPE_PEN = 'pen';
1000 const CLASS_NAME_POINTER_EVENT = 'pointer-event';
1001 const SWIPE_THRESHOLD = 40;
1002 const Default$c = {
1003 endCallback: null,
1004 leftCallback: null,
1005 rightCallback: null
1006 };
1007 const DefaultType$c = {
1008 endCallback: '(function|null)',
1009 leftCallback: '(function|null)',
1010 rightCallback: '(function|null)'
1011 };
1012
1013 /**
1014 * Class definition
1015 */
1016
1017 class Swipe extends Config {
1018 constructor(element, config) {
1019 super();
1020 this._element = element;
1021 if (!element || !Swipe.isSupported()) {
1022 return;
1023 }
1024 this._config = this._getConfig(config);
1025 this._deltaX = 0;
1026 this._supportPointerEvents = Boolean(window.PointerEvent);
1027 this._initEvents();
1028 }
1029
1030 // Getters
1031 static get Default() {
1032 return Default$c;
1033 }
1034 static get DefaultType() {
1035 return DefaultType$c;
1036 }
1037 static get NAME() {
1038 return NAME$d;
1039 }
1040
1041 // Public
1042 dispose() {
1043 EventHandler.off(this._element, EVENT_KEY$9);
1044 }
1045
1046 // Private
1047 _start(event) {
1048 if (!this._supportPointerEvents) {
1049 this._deltaX = event.touches[0].clientX;
1050 return;
1051 }
1052 if (this._eventIsPointerPenTouch(event)) {
1053 this._deltaX = event.clientX;
1054 }
1055 }
1056 _end(event) {
1057 if (this._eventIsPointerPenTouch(event)) {
1058 this._deltaX = event.clientX - this._deltaX;
1059 }
1060 this._handleSwipe();
1061 execute(this._config.endCallback);
1062 }
1063 _move(event) {
1064 this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX;
1065 }
1066 _handleSwipe() {
1067 const absDeltaX = Math.abs(this._deltaX);
1068 if (absDeltaX <= SWIPE_THRESHOLD) {
1069 return;
1070 }
1071 const direction = absDeltaX / this._deltaX;
1072 this._deltaX = 0;
1073 if (!direction) {
1074 return;
1075 }
1076 execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback);
1077 }
1078 _initEvents() {
1079 if (this._supportPointerEvents) {
1080 EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event));
1081 EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event));
1082 this._element.classList.add(CLASS_NAME_POINTER_EVENT);
1083 } else {
1084 EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event));
1085 EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event));
1086 EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event));
1087 }
1088 }
1089 _eventIsPointerPenTouch(event) {
1090 return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);
1091 }
1092
1093 // Static
1094 static isSupported() {
1095 return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
1096 }
1097 }
1098
1099 /**
1100 * --------------------------------------------------------------------------
1101 * Bootstrap carousel.js
1102 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1103 * --------------------------------------------------------------------------
1104 */
1105
1106
1107 /**
1108 * Constants
1109 */
1110
1111 const NAME$c = 'carousel';
1112 const DATA_KEY$8 = 'bs.carousel';
1113 const EVENT_KEY$8 = `.${DATA_KEY$8}`;
1114 const DATA_API_KEY$5 = '.data-api';
1115 const ARROW_LEFT_KEY$1 = 'ArrowLeft';
1116 const ARROW_RIGHT_KEY$1 = 'ArrowRight';
1117 const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
1118
1119 const ORDER_NEXT = 'next';
1120 const ORDER_PREV = 'prev';
1121 const DIRECTION_LEFT = 'left';
1122 const DIRECTION_RIGHT = 'right';
1123 const EVENT_SLIDE = `slide${EVENT_KEY$8}`;
1124 const EVENT_SLID = `slid${EVENT_KEY$8}`;
1125 const EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`;
1126 const EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`;
1127 const EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`;
1128 const EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`;
1129 const EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`;
1130 const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;
1131 const CLASS_NAME_CAROUSEL = 'carousel';
1132 const CLASS_NAME_ACTIVE$2 = 'active';
1133 const CLASS_NAME_SLIDE = 'slide';
1134 const CLASS_NAME_END = 'carousel-item-end';
1135 const CLASS_NAME_START = 'carousel-item-start';
1136 const CLASS_NAME_NEXT = 'carousel-item-next';
1137 const CLASS_NAME_PREV = 'carousel-item-prev';
1138 const SELECTOR_ACTIVE = '.active';
1139 const SELECTOR_ITEM = '.carousel-item';
1140 const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM;
1141 const SELECTOR_ITEM_IMG = '.carousel-item img';
1142 const SELECTOR_INDICATORS = '.carousel-indicators';
1143 const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';
1144 const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]';
1145 const KEY_TO_DIRECTION = {
1146 [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT,
1147 [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT
1148 };
1149 const Default$b = {
1150 interval: 5000,
1151 keyboard: true,
1152 pause: 'hover',
1153 ride: false,
1154 touch: true,
1155 wrap: true
1156 };
1157 const DefaultType$b = {
1158 interval: '(number|boolean)',
1159 // TODO:v6 remove boolean support
1160 keyboard: 'boolean',
1161 pause: '(string|boolean)',
1162 ride: '(boolean|string)',
1163 touch: 'boolean',
1164 wrap: 'boolean'
1165 };
1166
1167 /**
1168 * Class definition
1169 */
1170
1171 class Carousel extends BaseComponent {
1172 constructor(element, config) {
1173 super(element, config);
1174 this._interval = null;
1175 this._activeElement = null;
1176 this._isSliding = false;
1177 this.touchTimeout = null;
1178 this._swipeHelper = null;
1179 this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);
1180 this._addEventListeners();
1181 if (this._config.ride === CLASS_NAME_CAROUSEL) {
1182 this.cycle();
1183 }
1184 }
1185
1186 // Getters
1187 static get Default() {
1188 return Default$b;
1189 }
1190 static get DefaultType() {
1191 return DefaultType$b;
1192 }
1193 static get NAME() {
1194 return NAME$c;
1195 }
1196
1197 // Public
1198 next() {
1199 this._slide(ORDER_NEXT);
1200 }
1201 nextWhenVisible() {
1202 // FIXME TODO use `document.visibilityState`
1203 // Don't call next when the page isn't visible
1204 // or the carousel or its parent isn't visible
1205 if (!document.hidden && isVisible(this._element)) {
1206 this.next();
1207 }
1208 }
1209 prev() {
1210 this._slide(ORDER_PREV);
1211 }
1212 pause() {
1213 if (this._isSliding) {
1214 triggerTransitionEnd(this._element);
1215 }
1216 this._clearInterval();
1217 }
1218 cycle() {
1219 this._clearInterval();
1220 this._updateInterval();
1221 this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval);
1222 }
1223 _maybeEnableCycle() {
1224 if (!this._config.ride) {
1225 return;
1226 }
1227 if (this._isSliding) {
1228 EventHandler.one(this._element, EVENT_SLID, () => this.cycle());
1229 return;
1230 }
1231 this.cycle();
1232 }
1233 to(index) {
1234 const items = this._getItems();
1235 if (index > items.length - 1 || index < 0) {
1236 return;
1237 }
1238 if (this._isSliding) {
1239 EventHandler.one(this._element, EVENT_SLID, () => this.to(index));
1240 return;
1241 }
1242 const activeIndex = this._getItemIndex(this._getActive());
1243 if (activeIndex === index) {
1244 return;
1245 }
1246 const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;
1247 this._slide(order, items[index]);
1248 }
1249 dispose() {
1250 if (this._swipeHelper) {
1251 this._swipeHelper.dispose();
1252 }
1253 super.dispose();
1254 }
1255
1256 // Private
1257 _configAfterMerge(config) {
1258 config.defaultInterval = config.interval;
1259 return config;
1260 }
1261 _addEventListeners() {
1262 if (this._config.keyboard) {
1263 EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event));
1264 }
1265 if (this._config.pause === 'hover') {
1266 EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause());
1267 EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle());
1268 }
1269 if (this._config.touch && Swipe.isSupported()) {
1270 this._addTouchEventListeners();
1271 }
1272 }
1273 _addTouchEventListeners() {
1274 for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {
1275 EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault());
1276 }
1277 const endCallBack = () => {
1278 if (this._config.pause !== 'hover') {
1279 return;
1280 }
1281
1282 // If it's a touch-enabled device, mouseenter/leave are fired as
1283 // part of the mouse compatibility events on first tap - the carousel
1284 // would stop cycling until user tapped out of it;
1285 // here, we listen for touchend, explicitly pause the carousel
1286 // (as if it's the second time we tap on it, mouseenter compat event
1287 // is NOT fired) and after a timeout (to allow for mouse compatibility
1288 // events to fire) we explicitly restart cycling
1289
1290 this.pause();
1291 if (this.touchTimeout) {
1292 clearTimeout(this.touchTimeout);
1293 }
1294 this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval);
1295 };
1296 const swipeConfig = {
1297 leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),
1298 rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),
1299 endCallback: endCallBack
1300 };
1301 this._swipeHelper = new Swipe(this._element, swipeConfig);
1302 }
1303 _keydown(event) {
1304 if (/input|textarea/i.test(event.target.tagName)) {
1305 return;
1306 }
1307 const direction = KEY_TO_DIRECTION[event.key];
1308 if (direction) {
1309 event.preventDefault();
1310 this._slide(this._directionToOrder(direction));
1311 }
1312 }
1313 _getItemIndex(element) {
1314 return this._getItems().indexOf(element);
1315 }
1316 _setActiveIndicatorElement(index) {
1317 if (!this._indicatorsElement) {
1318 return;
1319 }
1320 const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement);
1321 activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);
1322 activeIndicator.removeAttribute('aria-current');
1323 const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement);
1324 if (newActiveIndicator) {
1325 newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2);
1326 newActiveIndicator.setAttribute('aria-current', 'true');
1327 }
1328 }
1329 _updateInterval() {
1330 const element = this._activeElement || this._getActive();
1331 if (!element) {
1332 return;
1333 }
1334 const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);
1335 this._config.interval = elementInterval || this._config.defaultInterval;
1336 }
1337 _slide(order, element = null) {
1338 if (this._isSliding) {
1339 return;
1340 }
1341 const activeElement = this._getActive();
1342 const isNext = order === ORDER_NEXT;
1343 const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap);
1344 if (nextElement === activeElement) {
1345 return;
1346 }
1347 const nextElementIndex = this._getItemIndex(nextElement);
1348 const triggerEvent = eventName => {
1349 return EventHandler.trigger(this._element, eventName, {
1350 relatedTarget: nextElement,
1351 direction: this._orderToDirection(order),
1352 from: this._getItemIndex(activeElement),
1353 to: nextElementIndex
1354 });
1355 };
1356 const slideEvent = triggerEvent(EVENT_SLIDE);
1357 if (slideEvent.defaultPrevented) {
1358 return;
1359 }
1360 if (!activeElement || !nextElement) {
1361 // Some weirdness is happening, so we bail
1362 // TODO: change tests that use empty divs to avoid this check
1363 return;
1364 }
1365 const isCycling = Boolean(this._interval);
1366 this.pause();
1367 this._isSliding = true;
1368 this._setActiveIndicatorElement(nextElementIndex);
1369 this._activeElement = nextElement;
1370 const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;
1371 const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;
1372 nextElement.classList.add(orderClassName);
1373 reflow(nextElement);
1374 activeElement.classList.add(directionalClassName);
1375 nextElement.classList.add(directionalClassName);
1376 const completeCallBack = () => {
1377 nextElement.classList.remove(directionalClassName, orderClassName);
1378 nextElement.classList.add(CLASS_NAME_ACTIVE$2);
1379 activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);
1380 this._isSliding = false;
1381 triggerEvent(EVENT_SLID);
1382 };
1383 this._queueCallback(completeCallBack, activeElement, this._isAnimated());
1384 if (isCycling) {
1385 this.cycle();
1386 }
1387 }
1388 _isAnimated() {
1389 return this._element.classList.contains(CLASS_NAME_SLIDE);
1390 }
1391 _getActive() {
1392 return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);
1393 }
1394 _getItems() {
1395 return SelectorEngine.find(SELECTOR_ITEM, this._element);
1396 }
1397 _clearInterval() {
1398 if (this._interval) {
1399 clearInterval(this._interval);
1400 this._interval = null;
1401 }
1402 }
1403 _directionToOrder(direction) {
1404 if (isRTL()) {
1405 return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;
1406 }
1407 return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;
1408 }
1409 _orderToDirection(order) {
1410 if (isRTL()) {
1411 return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;
1412 }
1413 return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
1414 }
1415
1416 // Static
1417 static jQueryInterface(config) {
1418 return this.each(function () {
1419 const data = Carousel.getOrCreateInstance(this, config);
1420 if (typeof config === 'number') {
1421 data.to(config);
1422 return;
1423 }
1424 if (typeof config === 'string') {
1425 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
1426 throw new TypeError(`No method named "${config}"`);
1427 }
1428 data[config]();
1429 }
1430 });
1431 }
1432 }
1433
1434 /**
1435 * Data API implementation
1436 */
1437
1438 EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) {
1439 const target = SelectorEngine.getElementFromSelector(this);
1440 if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
1441 return;
1442 }
1443 event.preventDefault();
1444 const carousel = Carousel.getOrCreateInstance(target);
1445 const slideIndex = this.getAttribute('data-bs-slide-to');
1446 if (slideIndex) {
1447 carousel.to(slideIndex);
1448 carousel._maybeEnableCycle();
1449 return;
1450 }
1451 if (Manipulator.getDataAttribute(this, 'slide') === 'next') {
1452 carousel.next();
1453 carousel._maybeEnableCycle();
1454 return;
1455 }
1456 carousel.prev();
1457 carousel._maybeEnableCycle();
1458 });
1459 EventHandler.on(window, EVENT_LOAD_DATA_API$3, () => {
1460 const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);
1461 for (const carousel of carousels) {
1462 Carousel.getOrCreateInstance(carousel);
1463 }
1464 });
1465
1466 /**
1467 * jQuery
1468 */
1469
1470 defineJQueryPlugin(Carousel);
1471
1472 /**
1473 * --------------------------------------------------------------------------
1474 * Bootstrap collapse.js
1475 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1476 * --------------------------------------------------------------------------
1477 */
1478
1479
1480 /**
1481 * Constants
1482 */
1483
1484 const NAME$b = 'collapse';
1485 const DATA_KEY$7 = 'bs.collapse';
1486 const EVENT_KEY$7 = `.${DATA_KEY$7}`;
1487 const DATA_API_KEY$4 = '.data-api';
1488 const EVENT_SHOW$6 = `show${EVENT_KEY$7}`;
1489 const EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`;
1490 const EVENT_HIDE$6 = `hide${EVENT_KEY$7}`;
1491 const EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`;
1492 const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`;
1493 const CLASS_NAME_SHOW$7 = 'show';
1494 const CLASS_NAME_COLLAPSE = 'collapse';
1495 const CLASS_NAME_COLLAPSING = 'collapsing';
1496 const CLASS_NAME_COLLAPSED = 'collapsed';
1497 const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;
1498 const CLASS_NAME_HORIZONTAL = 'collapse-horizontal';
1499 const WIDTH = 'width';
1500 const HEIGHT = 'height';
1501 const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';
1502 const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle="collapse"]';
1503 const Default$a = {
1504 parent: null,
1505 toggle: true
1506 };
1507 const DefaultType$a = {
1508 parent: '(null|element)',
1509 toggle: 'boolean'
1510 };
1511
1512 /**
1513 * Class definition
1514 */
1515
1516 class Collapse extends BaseComponent {
1517 constructor(element, config) {
1518 super(element, config);
1519 this._isTransitioning = false;
1520 this._triggerArray = [];
1521 const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);
1522 for (const elem of toggleList) {
1523 const selector = SelectorEngine.getSelectorFromElement(elem);
1524 const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element);
1525 if (selector !== null && filterElement.length) {
1526 this._triggerArray.push(elem);
1527 }
1528 }
1529 this._initializeChildren();
1530 if (!this._config.parent) {
1531 this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());
1532 }
1533 if (this._config.toggle) {
1534 this.toggle();
1535 }
1536 }
1537
1538 // Getters
1539 static get Default() {
1540 return Default$a;
1541 }
1542 static get DefaultType() {
1543 return DefaultType$a;
1544 }
1545 static get NAME() {
1546 return NAME$b;
1547 }
1548
1549 // Public
1550 toggle() {
1551 if (this._isShown()) {
1552 this.hide();
1553 } else {
1554 this.show();
1555 }
1556 }
1557 show() {
1558 if (this._isTransitioning || this._isShown()) {
1559 return;
1560 }
1561 let activeChildren = [];
1562
1563 // find active children
1564 if (this._config.parent) {
1565 activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, {
1566 toggle: false
1567 }));
1568 }
1569 if (activeChildren.length && activeChildren[0]._isTransitioning) {
1570 return;
1571 }
1572 const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6);
1573 if (startEvent.defaultPrevented) {
1574 return;
1575 }
1576 for (const activeInstance of activeChildren) {
1577 activeInstance.hide();
1578 }
1579 const dimension = this._getDimension();
1580 this._element.classList.remove(CLASS_NAME_COLLAPSE);
1581 this._element.classList.add(CLASS_NAME_COLLAPSING);
1582 this._element.style[dimension] = 0;
1583 this._addAriaAndCollapsedClass(this._triggerArray, true);
1584 this._isTransitioning = true;
1585 const complete = () => {
1586 this._isTransitioning = false;
1587 this._element.classList.remove(CLASS_NAME_COLLAPSING);
1588 this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);
1589 this._element.style[dimension] = '';
1590 EventHandler.trigger(this._element, EVENT_SHOWN$6);
1591 };
1592 const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
1593 const scrollSize = `scroll${capitalizedDimension}`;
1594 this._queueCallback(complete, this._element, true);
1595 this._element.style[dimension] = `${this._element[scrollSize]}px`;
1596 }
1597 hide() {
1598 if (this._isTransitioning || !this._isShown()) {
1599 return;
1600 }
1601 const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6);
1602 if (startEvent.defaultPrevented) {
1603 return;
1604 }
1605 const dimension = this._getDimension();
1606 this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;
1607 reflow(this._element);
1608 this._element.classList.add(CLASS_NAME_COLLAPSING);
1609 this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);
1610 for (const trigger of this._triggerArray) {
1611 const element = SelectorEngine.getElementFromSelector(trigger);
1612 if (element && !this._isShown(element)) {
1613 this._addAriaAndCollapsedClass([trigger], false);
1614 }
1615 }
1616 this._isTransitioning = true;
1617 const complete = () => {
1618 this._isTransitioning = false;
1619 this._element.classList.remove(CLASS_NAME_COLLAPSING);
1620 this._element.classList.add(CLASS_NAME_COLLAPSE);
1621 EventHandler.trigger(this._element, EVENT_HIDDEN$6);
1622 };
1623 this._element.style[dimension] = '';
1624 this._queueCallback(complete, this._element, true);
1625 }
1626 _isShown(element = this._element) {
1627 return element.classList.contains(CLASS_NAME_SHOW$7);
1628 }
1629
1630 // Private
1631 _configAfterMerge(config) {
1632 config.toggle = Boolean(config.toggle); // Coerce string values
1633 config.parent = getElement(config.parent);
1634 return config;
1635 }
1636 _getDimension() {
1637 return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;
1638 }
1639 _initializeChildren() {
1640 if (!this._config.parent) {
1641 return;
1642 }
1643 const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4);
1644 for (const element of children) {
1645 const selected = SelectorEngine.getElementFromSelector(element);
1646 if (selected) {
1647 this._addAriaAndCollapsedClass([element], this._isShown(selected));
1648 }
1649 }
1650 }
1651 _getFirstLevelChildren(selector) {
1652 const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);
1653 // remove children if greater depth
1654 return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element));
1655 }
1656 _addAriaAndCollapsedClass(triggerArray, isOpen) {
1657 if (!triggerArray.length) {
1658 return;
1659 }
1660 for (const element of triggerArray) {
1661 element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);
1662 element.setAttribute('aria-expanded', isOpen);
1663 }
1664 }
1665
1666 // Static
1667 static jQueryInterface(config) {
1668 const _config = {};
1669 if (typeof config === 'string' && /show|hide/.test(config)) {
1670 _config.toggle = false;
1671 }
1672 return this.each(function () {
1673 const data = Collapse.getOrCreateInstance(this, _config);
1674 if (typeof config === 'string') {
1675 if (typeof data[config] === 'undefined') {
1676 throw new TypeError(`No method named "${config}"`);
1677 }
1678 data[config]();
1679 }
1680 });
1681 }
1682 }
1683
1684 /**
1685 * Data API implementation
1686 */
1687
1688 EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {
1689 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
1690 if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {
1691 event.preventDefault();
1692 }
1693 for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {
1694 Collapse.getOrCreateInstance(element, {
1695 toggle: false
1696 }).toggle();
1697 }
1698 });
1699
1700 /**
1701 * jQuery
1702 */
1703
1704 defineJQueryPlugin(Collapse);
1705
1706 /**
1707 * --------------------------------------------------------------------------
1708 * Bootstrap dropdown.js
1709 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1710 * --------------------------------------------------------------------------
1711 */
1712
1713
1714 /**
1715 * Constants
1716 */
1717
1718 const NAME$a = 'dropdown';
1719 const DATA_KEY$6 = 'bs.dropdown';
1720 const EVENT_KEY$6 = `.${DATA_KEY$6}`;
1721 const DATA_API_KEY$3 = '.data-api';
1722 const ESCAPE_KEY$2 = 'Escape';
1723 const TAB_KEY$1 = 'Tab';
1724 const ARROW_UP_KEY$1 = 'ArrowUp';
1725 const ARROW_DOWN_KEY$1 = 'ArrowDown';
1726 const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button
1727
1728 const EVENT_HIDE$5 = `hide${EVENT_KEY$6}`;
1729 const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`;
1730 const EVENT_SHOW$5 = `show${EVENT_KEY$6}`;
1731 const EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`;
1732 const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;
1733 const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`;
1734 const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`;
1735 const CLASS_NAME_SHOW$6 = 'show';
1736 const CLASS_NAME_DROPUP = 'dropup';
1737 const CLASS_NAME_DROPEND = 'dropend';
1738 const CLASS_NAME_DROPSTART = 'dropstart';
1739 const CLASS_NAME_DROPUP_CENTER = 'dropup-center';
1740 const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';
1741 const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)';
1742 const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`;
1743 const SELECTOR_MENU = '.dropdown-menu';
1744 const SELECTOR_NAVBAR = '.navbar';
1745 const SELECTOR_NAVBAR_NAV = '.navbar-nav';
1746 const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
1747 const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';
1748 const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';
1749 const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';
1750 const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';
1751 const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';
1752 const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';
1753 const PLACEMENT_TOPCENTER = 'top';
1754 const PLACEMENT_BOTTOMCENTER = 'bottom';
1755 const Default$9 = {
1756 autoClose: true,
1757 boundary: 'clippingParents',
1758 display: 'dynamic',
1759 offset: [0, 2],
1760 popperConfig: null,
1761 reference: 'toggle'
1762 };
1763 const DefaultType$9 = {
1764 autoClose: '(boolean|string)',
1765 boundary: '(string|element)',
1766 display: 'string',
1767 offset: '(array|string|function)',
1768 popperConfig: '(null|object|function)',
1769 reference: '(string|element|object)'
1770 };
1771
1772 /**
1773 * Class definition
1774 */
1775
1776 class Dropdown extends BaseComponent {
1777 constructor(element, config) {
1778 super(element, config);
1779 this._popper = null;
1780 this._parent = this._element.parentNode; // dropdown wrapper
1781 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
1782 this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent);
1783 this._inNavbar = this._detectNavbar();
1784 }
1785
1786 // Getters
1787 static get Default() {
1788 return Default$9;
1789 }
1790 static get DefaultType() {
1791 return DefaultType$9;
1792 }
1793 static get NAME() {
1794 return NAME$a;
1795 }
1796
1797 // Public
1798 toggle() {
1799 return this._isShown() ? this.hide() : this.show();
1800 }
1801 show() {
1802 if (isDisabled(this._element) || this._isShown()) {
1803 return;
1804 }
1805 const relatedTarget = {
1806 relatedTarget: this._element
1807 };
1808 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget);
1809 if (showEvent.defaultPrevented) {
1810 return;
1811 }
1812 this._createPopper();
1813
1814 // If this is a touch-enabled device we add extra
1815 // empty mouseover listeners to the body's immediate children;
1816 // only needed because of broken event delegation on iOS
1817 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
1818 if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {
1819 for (const element of [].concat(...document.body.children)) {
1820 EventHandler.on(element, 'mouseover', noop);
1821 }
1822 }
1823 this._element.focus();
1824 this._element.setAttribute('aria-expanded', true);
1825 this._menu.classList.add(CLASS_NAME_SHOW$6);
1826 this._element.classList.add(CLASS_NAME_SHOW$6);
1827 EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget);
1828 }
1829 hide() {
1830 if (isDisabled(this._element) || !this._isShown()) {
1831 return;
1832 }
1833 const relatedTarget = {
1834 relatedTarget: this._element
1835 };
1836 this._completeHide(relatedTarget);
1837 }
1838 dispose() {
1839 if (this._popper) {
1840 this._popper.destroy();
1841 }
1842 super.dispose();
1843 }
1844 update() {
1845 this._inNavbar = this._detectNavbar();
1846 if (this._popper) {
1847 this._popper.update();
1848 }
1849 }
1850
1851 // Private
1852 _completeHide(relatedTarget) {
1853 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget);
1854 if (hideEvent.defaultPrevented) {
1855 return;
1856 }
1857
1858 // If this is a touch-enabled device we remove the extra
1859 // empty mouseover listeners we added for iOS support
1860 if ('ontouchstart' in document.documentElement) {
1861 for (const element of [].concat(...document.body.children)) {
1862 EventHandler.off(element, 'mouseover', noop);
1863 }
1864 }
1865 if (this._popper) {
1866 this._popper.destroy();
1867 }
1868 this._menu.classList.remove(CLASS_NAME_SHOW$6);
1869 this._element.classList.remove(CLASS_NAME_SHOW$6);
1870 this._element.setAttribute('aria-expanded', 'false');
1871 Manipulator.removeDataAttribute(this._menu, 'popper');
1872 EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget);
1873 }
1874 _getConfig(config) {
1875 config = super._getConfig(config);
1876 if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {
1877 // Popper virtual elements require a getBoundingClientRect method
1878 throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);
1879 }
1880 return config;
1881 }
1882 _createPopper() {
1883 if (typeof Popper__namespace === 'undefined') {
1884 throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)');
1885 }
1886 let referenceElement = this._element;
1887 if (this._config.reference === 'parent') {
1888 referenceElement = this._parent;
1889 } else if (isElement(this._config.reference)) {
1890 referenceElement = getElement(this._config.reference);
1891 } else if (typeof this._config.reference === 'object') {
1892 referenceElement = this._config.reference;
1893 }
1894 const popperConfig = this._getPopperConfig();
1895 this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig);
1896 }
1897 _isShown() {
1898 return this._menu.classList.contains(CLASS_NAME_SHOW$6);
1899 }
1900 _getPlacement() {
1901 const parentDropdown = this._parent;
1902 if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
1903 return PLACEMENT_RIGHT;
1904 }
1905 if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {
1906 return PLACEMENT_LEFT;
1907 }
1908 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {
1909 return PLACEMENT_TOPCENTER;
1910 }
1911 if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {
1912 return PLACEMENT_BOTTOMCENTER;
1913 }
1914
1915 // We need to trim the value because custom properties can also include spaces
1916 const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';
1917 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {
1918 return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;
1919 }
1920 return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;
1921 }
1922 _detectNavbar() {
1923 return this._element.closest(SELECTOR_NAVBAR) !== null;
1924 }
1925 _getOffset() {
1926 const {
1927 offset
1928 } = this._config;
1929 if (typeof offset === 'string') {
1930 return offset.split(',').map(value => Number.parseInt(value, 10));
1931 }
1932 if (typeof offset === 'function') {
1933 return popperData => offset(popperData, this._element);
1934 }
1935 return offset;
1936 }
1937 _getPopperConfig() {
1938 const defaultBsPopperConfig = {
1939 placement: this._getPlacement(),
1940 modifiers: [{
1941 name: 'preventOverflow',
1942 options: {
1943 boundary: this._config.boundary
1944 }
1945 }, {
1946 name: 'offset',
1947 options: {
1948 offset: this._getOffset()
1949 }
1950 }]
1951 };
1952
1953 // Disable Popper if we have a static display or Dropdown is in Navbar
1954 if (this._inNavbar || this._config.display === 'static') {
1955 Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove
1956 defaultBsPopperConfig.modifiers = [{
1957 name: 'applyStyles',
1958 enabled: false
1959 }];
1960 }
1961 return {
1962 ...defaultBsPopperConfig,
1963 ...execute(this._config.popperConfig, [defaultBsPopperConfig])
1964 };
1965 }
1966 _selectMenuItem({
1967 key,
1968 target
1969 }) {
1970 const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element));
1971 if (!items.length) {
1972 return;
1973 }
1974
1975 // if target isn't included in items (e.g. when expanding the dropdown)
1976 // allow cycling to get the last item in case key equals ARROW_UP_KEY
1977 getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();
1978 }
1979
1980 // Static
1981 static jQueryInterface(config) {
1982 return this.each(function () {
1983 const data = Dropdown.getOrCreateInstance(this, config);
1984 if (typeof config !== 'string') {
1985 return;
1986 }
1987 if (typeof data[config] === 'undefined') {
1988 throw new TypeError(`No method named "${config}"`);
1989 }
1990 data[config]();
1991 });
1992 }
1993 static clearMenus(event) {
1994 if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {
1995 return;
1996 }
1997 const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);
1998 for (const toggle of openToggles) {
1999 const context = Dropdown.getInstance(toggle);
2000 if (!context || context._config.autoClose === false) {
2001 continue;
2002 }
2003 const composedPath = event.composedPath();
2004 const isMenuTarget = composedPath.includes(context._menu);
2005 if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {
2006 continue;
2007 }
2008
2009 // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
2010 if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {
2011 continue;
2012 }
2013 const relatedTarget = {
2014 relatedTarget: context._element
2015 };
2016 if (event.type === 'click') {
2017 relatedTarget.clickEvent = event;
2018 }
2019 context._completeHide(relatedTarget);
2020 }
2021 }
2022 static dataApiKeydownHandler(event) {
2023 // If not an UP | DOWN | ESCAPE key => not a dropdown command
2024 // If input/textarea && if key is other than ESCAPE => not a dropdown command
2025
2026 const isInput = /input|textarea/i.test(event.target.tagName);
2027 const isEscapeEvent = event.key === ESCAPE_KEY$2;
2028 const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key);
2029 if (!isUpOrDownEvent && !isEscapeEvent) {
2030 return;
2031 }
2032 if (isInput && !isEscapeEvent) {
2033 return;
2034 }
2035 event.preventDefault();
2036
2037 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
2038 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);
2039 const instance = Dropdown.getOrCreateInstance(getToggleButton);
2040 if (isUpOrDownEvent) {
2041 event.stopPropagation();
2042 instance.show();
2043 instance._selectMenuItem(event);
2044 return;
2045 }
2046 if (instance._isShown()) {
2047 // else is escape and we check if it is shown
2048 event.stopPropagation();
2049 instance.hide();
2050 getToggleButton.focus();
2051 }
2052 }
2053 }
2054
2055 /**
2056 * Data API implementation
2057 */
2058
2059 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);
2060 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);
2061 EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);
2062 EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
2063 EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {
2064 event.preventDefault();
2065 Dropdown.getOrCreateInstance(this).toggle();
2066 });
2067
2068 /**
2069 * jQuery
2070 */
2071
2072 defineJQueryPlugin(Dropdown);
2073
2074 /**
2075 * --------------------------------------------------------------------------
2076 * Bootstrap util/backdrop.js
2077 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2078 * --------------------------------------------------------------------------
2079 */
2080
2081
2082 /**
2083 * Constants
2084 */
2085
2086 const NAME$9 = 'backdrop';
2087 const CLASS_NAME_FADE$4 = 'fade';
2088 const CLASS_NAME_SHOW$5 = 'show';
2089 const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`;
2090 const Default$8 = {
2091 className: 'modal-backdrop',
2092 clickCallback: null,
2093 isAnimated: false,
2094 isVisible: true,
2095 // if false, we use the backdrop helper without adding any element to the dom
2096 rootElement: 'body' // give the choice to place backdrop under different elements
2097 };
2098 const DefaultType$8 = {
2099 className: 'string',
2100 clickCallback: '(function|null)',
2101 isAnimated: 'boolean',
2102 isVisible: 'boolean',
2103 rootElement: '(element|string)'
2104 };
2105
2106 /**
2107 * Class definition
2108 */
2109
2110 class Backdrop extends Config {
2111 constructor(config) {
2112 super();
2113 this._config = this._getConfig(config);
2114 this._isAppended = false;
2115 this._element = null;
2116 }
2117
2118 // Getters
2119 static get Default() {
2120 return Default$8;
2121 }
2122 static get DefaultType() {
2123 return DefaultType$8;
2124 }
2125 static get NAME() {
2126 return NAME$9;
2127 }
2128
2129 // Public
2130 show(callback) {
2131 if (!this._config.isVisible) {
2132 execute(callback);
2133 return;
2134 }
2135 this._append();
2136 const element = this._getElement();
2137 if (this._config.isAnimated) {
2138 reflow(element);
2139 }
2140 element.classList.add(CLASS_NAME_SHOW$5);
2141 this._emulateAnimation(() => {
2142 execute(callback);
2143 });
2144 }
2145 hide(callback) {
2146 if (!this._config.isVisible) {
2147 execute(callback);
2148 return;
2149 }
2150 this._getElement().classList.remove(CLASS_NAME_SHOW$5);
2151 this._emulateAnimation(() => {
2152 this.dispose();
2153 execute(callback);
2154 });
2155 }
2156 dispose() {
2157 if (!this._isAppended) {
2158 return;
2159 }
2160 EventHandler.off(this._element, EVENT_MOUSEDOWN);
2161 this._element.remove();
2162 this._isAppended = false;
2163 }
2164
2165 // Private
2166 _getElement() {
2167 if (!this._element) {
2168 const backdrop = document.createElement('div');
2169 backdrop.className = this._config.className;
2170 if (this._config.isAnimated) {
2171 backdrop.classList.add(CLASS_NAME_FADE$4);
2172 }
2173 this._element = backdrop;
2174 }
2175 return this._element;
2176 }
2177 _configAfterMerge(config) {
2178 // use getElement() with the default "body" to get a fresh Element on each instantiation
2179 config.rootElement = getElement(config.rootElement);
2180 return config;
2181 }
2182 _append() {
2183 if (this._isAppended) {
2184 return;
2185 }
2186 const element = this._getElement();
2187 this._config.rootElement.append(element);
2188 EventHandler.on(element, EVENT_MOUSEDOWN, () => {
2189 execute(this._config.clickCallback);
2190 });
2191 this._isAppended = true;
2192 }
2193 _emulateAnimation(callback) {
2194 executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
2195 }
2196 }
2197
2198 /**
2199 * --------------------------------------------------------------------------
2200 * Bootstrap util/focustrap.js
2201 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2202 * --------------------------------------------------------------------------
2203 */
2204
2205
2206 /**
2207 * Constants
2208 */
2209
2210 const NAME$8 = 'focustrap';
2211 const DATA_KEY$5 = 'bs.focustrap';
2212 const EVENT_KEY$5 = `.${DATA_KEY$5}`;
2213 const EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`;
2214 const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`;
2215 const TAB_KEY = 'Tab';
2216 const TAB_NAV_FORWARD = 'forward';
2217 const TAB_NAV_BACKWARD = 'backward';
2218 const Default$7 = {
2219 autofocus: true,
2220 trapElement: null // The element to trap focus inside of
2221 };
2222 const DefaultType$7 = {
2223 autofocus: 'boolean',
2224 trapElement: 'element'
2225 };
2226
2227 /**
2228 * Class definition
2229 */
2230
2231 class FocusTrap extends Config {
2232 constructor(config) {
2233 super();
2234 this._config = this._getConfig(config);
2235 this._isActive = false;
2236 this._lastTabNavDirection = null;
2237 }
2238
2239 // Getters
2240 static get Default() {
2241 return Default$7;
2242 }
2243 static get DefaultType() {
2244 return DefaultType$7;
2245 }
2246 static get NAME() {
2247 return NAME$8;
2248 }
2249
2250 // Public
2251 activate() {
2252 if (this._isActive) {
2253 return;
2254 }
2255 if (this._config.autofocus) {
2256 this._config.trapElement.focus();
2257 }
2258 EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop
2259 EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event));
2260 EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
2261 this._isActive = true;
2262 }
2263 deactivate() {
2264 if (!this._isActive) {
2265 return;
2266 }
2267 this._isActive = false;
2268 EventHandler.off(document, EVENT_KEY$5);
2269 }
2270
2271 // Private
2272 _handleFocusin(event) {
2273 const {
2274 trapElement
2275 } = this._config;
2276 if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {
2277 return;
2278 }
2279 const elements = SelectorEngine.focusableChildren(trapElement);
2280 if (elements.length === 0) {
2281 trapElement.focus();
2282 } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
2283 elements[elements.length - 1].focus();
2284 } else {
2285 elements[0].focus();
2286 }
2287 }
2288 _handleKeydown(event) {
2289 if (event.key !== TAB_KEY) {
2290 return;
2291 }
2292 this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
2293 }
2294 }
2295
2296 /**
2297 * --------------------------------------------------------------------------
2298 * Bootstrap util/scrollBar.js
2299 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2300 * --------------------------------------------------------------------------
2301 */
2302
2303
2304 /**
2305 * Constants
2306 */
2307
2308 const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
2309 const SELECTOR_STICKY_CONTENT = '.sticky-top';
2310 const PROPERTY_PADDING = 'padding-right';
2311 const PROPERTY_MARGIN = 'margin-right';
2312
2313 /**
2314 * Class definition
2315 */
2316
2317 class ScrollBarHelper {
2318 constructor() {
2319 this._element = document.body;
2320 }
2321
2322 // Public
2323 getWidth() {
2324 // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
2325 const documentWidth = document.documentElement.clientWidth;
2326 return Math.abs(window.innerWidth - documentWidth);
2327 }
2328 hide() {
2329 const width = this.getWidth();
2330 this._disableOverFlow();
2331 // give padding to element to balance the hidden scrollbar width
2332 this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
2333 // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
2334 this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
2335 this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);
2336 }
2337 reset() {
2338 this._resetElementAttributes(this._element, 'overflow');
2339 this._resetElementAttributes(this._element, PROPERTY_PADDING);
2340 this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);
2341 this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);
2342 }
2343 isOverflowing() {
2344 return this.getWidth() > 0;
2345 }
2346
2347 // Private
2348 _disableOverFlow() {
2349 this._saveInitialAttribute(this._element, 'overflow');
2350 this._element.style.overflow = 'hidden';
2351 }
2352 _setElementAttributes(selector, styleProperty, callback) {
2353 const scrollbarWidth = this.getWidth();
2354 const manipulationCallBack = element => {
2355 if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
2356 return;
2357 }
2358 this._saveInitialAttribute(element, styleProperty);
2359 const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);
2360 element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);
2361 };
2362 this._applyManipulationCallback(selector, manipulationCallBack);
2363 }
2364 _saveInitialAttribute(element, styleProperty) {
2365 const actualValue = element.style.getPropertyValue(styleProperty);
2366 if (actualValue) {
2367 Manipulator.setDataAttribute(element, styleProperty, actualValue);
2368 }
2369 }
2370 _resetElementAttributes(selector, styleProperty) {
2371 const manipulationCallBack = element => {
2372 const value = Manipulator.getDataAttribute(element, styleProperty);
2373 // We only want to remove the property if the value is `null`; the value can also be zero
2374 if (value === null) {
2375 element.style.removeProperty(styleProperty);
2376 return;
2377 }
2378 Manipulator.removeDataAttribute(element, styleProperty);
2379 element.style.setProperty(styleProperty, value);
2380 };
2381 this._applyManipulationCallback(selector, manipulationCallBack);
2382 }
2383 _applyManipulationCallback(selector, callBack) {
2384 if (isElement(selector)) {
2385 callBack(selector);
2386 return;
2387 }
2388 for (const sel of SelectorEngine.find(selector, this._element)) {
2389 callBack(sel);
2390 }
2391 }
2392 }
2393
2394 /**
2395 * --------------------------------------------------------------------------
2396 * Bootstrap modal.js
2397 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2398 * --------------------------------------------------------------------------
2399 */
2400
2401
2402 /**
2403 * Constants
2404 */
2405
2406 const NAME$7 = 'modal';
2407 const DATA_KEY$4 = 'bs.modal';
2408 const EVENT_KEY$4 = `.${DATA_KEY$4}`;
2409 const DATA_API_KEY$2 = '.data-api';
2410 const ESCAPE_KEY$1 = 'Escape';
2411 const EVENT_HIDE$4 = `hide${EVENT_KEY$4}`;
2412 const EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`;
2413 const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`;
2414 const EVENT_SHOW$4 = `show${EVENT_KEY$4}`;
2415 const EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`;
2416 const EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`;
2417 const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`;
2418 const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`;
2419 const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`;
2420 const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`;
2421 const CLASS_NAME_OPEN = 'modal-open';
2422 const CLASS_NAME_FADE$3 = 'fade';
2423 const CLASS_NAME_SHOW$4 = 'show';
2424 const CLASS_NAME_STATIC = 'modal-static';
2425 const OPEN_SELECTOR$1 = '.modal.show';
2426 const SELECTOR_DIALOG = '.modal-dialog';
2427 const SELECTOR_MODAL_BODY = '.modal-body';
2428 const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle="modal"]';
2429 const Default$6 = {
2430 backdrop: true,
2431 focus: true,
2432 keyboard: true
2433 };
2434 const DefaultType$6 = {
2435 backdrop: '(boolean|string)',
2436 focus: 'boolean',
2437 keyboard: 'boolean'
2438 };
2439
2440 /**
2441 * Class definition
2442 */
2443
2444 class Modal extends BaseComponent {
2445 constructor(element, config) {
2446 super(element, config);
2447 this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
2448 this._backdrop = this._initializeBackDrop();
2449 this._focustrap = this._initializeFocusTrap();
2450 this._isShown = false;
2451 this._isTransitioning = false;
2452 this._scrollBar = new ScrollBarHelper();
2453 this._addEventListeners();
2454 }
2455
2456 // Getters
2457 static get Default() {
2458 return Default$6;
2459 }
2460 static get DefaultType() {
2461 return DefaultType$6;
2462 }
2463 static get NAME() {
2464 return NAME$7;
2465 }
2466
2467 // Public
2468 toggle(relatedTarget) {
2469 return this._isShown ? this.hide() : this.show(relatedTarget);
2470 }
2471 show(relatedTarget) {
2472 if (this._isShown || this._isTransitioning) {
2473 return;
2474 }
2475 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, {
2476 relatedTarget
2477 });
2478 if (showEvent.defaultPrevented) {
2479 return;
2480 }
2481 this._isShown = true;
2482 this._isTransitioning = true;
2483 this._scrollBar.hide();
2484 document.body.classList.add(CLASS_NAME_OPEN);
2485 this._adjustDialog();
2486 this._backdrop.show(() => this._showElement(relatedTarget));
2487 }
2488 hide() {
2489 if (!this._isShown || this._isTransitioning) {
2490 return;
2491 }
2492 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4);
2493 if (hideEvent.defaultPrevented) {
2494 return;
2495 }
2496 this._isShown = false;
2497 this._isTransitioning = true;
2498 this._focustrap.deactivate();
2499 this._element.classList.remove(CLASS_NAME_SHOW$4);
2500 this._queueCallback(() => this._hideModal(), this._element, this._isAnimated());
2501 }
2502 dispose() {
2503 EventHandler.off(window, EVENT_KEY$4);
2504 EventHandler.off(this._dialog, EVENT_KEY$4);
2505 this._backdrop.dispose();
2506 this._focustrap.deactivate();
2507 super.dispose();
2508 }
2509 handleUpdate() {
2510 this._adjustDialog();
2511 }
2512
2513 // Private
2514 _initializeBackDrop() {
2515 return new Backdrop({
2516 isVisible: Boolean(this._config.backdrop),
2517 // 'static' option will be translated to true, and booleans will keep their value,
2518 isAnimated: this._isAnimated()
2519 });
2520 }
2521 _initializeFocusTrap() {
2522 return new FocusTrap({
2523 trapElement: this._element
2524 });
2525 }
2526 _showElement(relatedTarget) {
2527 // try to append dynamic modal
2528 if (!document.body.contains(this._element)) {
2529 document.body.append(this._element);
2530 }
2531 this._element.style.display = 'block';
2532 this._element.removeAttribute('aria-hidden');
2533 this._element.setAttribute('aria-modal', true);
2534 this._element.setAttribute('role', 'dialog');
2535 this._element.scrollTop = 0;
2536 const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);
2537 if (modalBody) {
2538 modalBody.scrollTop = 0;
2539 }
2540 reflow(this._element);
2541 this._element.classList.add(CLASS_NAME_SHOW$4);
2542 const transitionComplete = () => {
2543 if (this._config.focus) {
2544 this._focustrap.activate();
2545 }
2546 this._isTransitioning = false;
2547 EventHandler.trigger(this._element, EVENT_SHOWN$4, {
2548 relatedTarget
2549 });
2550 };
2551 this._queueCallback(transitionComplete, this._dialog, this._isAnimated());
2552 }
2553 _addEventListeners() {
2554 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {
2555 if (event.key !== ESCAPE_KEY$1) {
2556 return;
2557 }
2558 if (this._config.keyboard) {
2559 this.hide();
2560 return;
2561 }
2562 this._triggerBackdropTransition();
2563 });
2564 EventHandler.on(window, EVENT_RESIZE$1, () => {
2565 if (this._isShown && !this._isTransitioning) {
2566 this._adjustDialog();
2567 }
2568 });
2569 EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {
2570 // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks
2571 EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {
2572 if (this._element !== event.target || this._element !== event2.target) {
2573 return;
2574 }
2575 if (this._config.backdrop === 'static') {
2576 this._triggerBackdropTransition();
2577 return;
2578 }
2579 if (this._config.backdrop) {
2580 this.hide();
2581 }
2582 });
2583 });
2584 }
2585 _hideModal() {
2586 this._element.style.display = 'none';
2587 this._element.setAttribute('aria-hidden', true);
2588 this._element.removeAttribute('aria-modal');
2589 this._element.removeAttribute('role');
2590 this._isTransitioning = false;
2591 this._backdrop.hide(() => {
2592 document.body.classList.remove(CLASS_NAME_OPEN);
2593 this._resetAdjustments();
2594 this._scrollBar.reset();
2595 EventHandler.trigger(this._element, EVENT_HIDDEN$4);
2596 });
2597 }
2598 _isAnimated() {
2599 return this._element.classList.contains(CLASS_NAME_FADE$3);
2600 }
2601 _triggerBackdropTransition() {
2602 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1);
2603 if (hideEvent.defaultPrevented) {
2604 return;
2605 }
2606 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
2607 const initialOverflowY = this._element.style.overflowY;
2608 // return if the following background transition hasn't yet completed
2609 if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {
2610 return;
2611 }
2612 if (!isModalOverflowing) {
2613 this._element.style.overflowY = 'hidden';
2614 }
2615 this._element.classList.add(CLASS_NAME_STATIC);
2616 this._queueCallback(() => {
2617 this._element.classList.remove(CLASS_NAME_STATIC);
2618 this._queueCallback(() => {
2619 this._element.style.overflowY = initialOverflowY;
2620 }, this._dialog);
2621 }, this._dialog);
2622 this._element.focus();
2623 }
2624
2625 /**
2626 * The following methods are used to handle overflowing modals
2627 */
2628
2629 _adjustDialog() {
2630 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
2631 const scrollbarWidth = this._scrollBar.getWidth();
2632 const isBodyOverflowing = scrollbarWidth > 0;
2633 if (isBodyOverflowing && !isModalOverflowing) {
2634 const property = isRTL() ? 'paddingLeft' : 'paddingRight';
2635 this._element.style[property] = `${scrollbarWidth}px`;
2636 }
2637 if (!isBodyOverflowing && isModalOverflowing) {
2638 const property = isRTL() ? 'paddingRight' : 'paddingLeft';
2639 this._element.style[property] = `${scrollbarWidth}px`;
2640 }
2641 }
2642 _resetAdjustments() {
2643 this._element.style.paddingLeft = '';
2644 this._element.style.paddingRight = '';
2645 }
2646
2647 // Static
2648 static jQueryInterface(config, relatedTarget) {
2649 return this.each(function () {
2650 const data = Modal.getOrCreateInstance(this, config);
2651 if (typeof config !== 'string') {
2652 return;
2653 }
2654 if (typeof data[config] === 'undefined') {
2655 throw new TypeError(`No method named "${config}"`);
2656 }
2657 data[config](relatedTarget);
2658 });
2659 }
2660 }
2661
2662 /**
2663 * Data API implementation
2664 */
2665
2666 EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {
2667 const target = SelectorEngine.getElementFromSelector(this);
2668 if (['A', 'AREA'].includes(this.tagName)) {
2669 event.preventDefault();
2670 }
2671 EventHandler.one(target, EVENT_SHOW$4, showEvent => {
2672 if (showEvent.defaultPrevented) {
2673 // only register focus restorer if modal will actually get shown
2674 return;
2675 }
2676 EventHandler.one(target, EVENT_HIDDEN$4, () => {
2677 if (isVisible(this)) {
2678 this.focus();
2679 }
2680 });
2681 });
2682
2683 // avoid conflict when clicking modal toggler while another one is open
2684 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1);
2685 if (alreadyOpen) {
2686 Modal.getInstance(alreadyOpen).hide();
2687 }
2688 const data = Modal.getOrCreateInstance(target);
2689 data.toggle(this);
2690 });
2691 enableDismissTrigger(Modal);
2692
2693 /**
2694 * jQuery
2695 */
2696
2697 defineJQueryPlugin(Modal);
2698
2699 /**
2700 * --------------------------------------------------------------------------
2701 * Bootstrap offcanvas.js
2702 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2703 * --------------------------------------------------------------------------
2704 */
2705
2706
2707 /**
2708 * Constants
2709 */
2710
2711 const NAME$6 = 'offcanvas';
2712 const DATA_KEY$3 = 'bs.offcanvas';
2713 const EVENT_KEY$3 = `.${DATA_KEY$3}`;
2714 const DATA_API_KEY$1 = '.data-api';
2715 const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`;
2716 const ESCAPE_KEY = 'Escape';
2717 const CLASS_NAME_SHOW$3 = 'show';
2718 const CLASS_NAME_SHOWING$1 = 'showing';
2719 const CLASS_NAME_HIDING = 'hiding';
2720 const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';
2721 const OPEN_SELECTOR = '.offcanvas.show';
2722 const EVENT_SHOW$3 = `show${EVENT_KEY$3}`;
2723 const EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`;
2724 const EVENT_HIDE$3 = `hide${EVENT_KEY$3}`;
2725 const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`;
2726 const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`;
2727 const EVENT_RESIZE = `resize${EVENT_KEY$3}`;
2728 const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`;
2729 const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`;
2730 const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="offcanvas"]';
2731 const Default$5 = {
2732 backdrop: true,
2733 keyboard: true,
2734 scroll: false
2735 };
2736 const DefaultType$5 = {
2737 backdrop: '(boolean|string)',
2738 keyboard: 'boolean',
2739 scroll: 'boolean'
2740 };
2741
2742 /**
2743 * Class definition
2744 */
2745
2746 class Offcanvas extends BaseComponent {
2747 constructor(element, config) {
2748 super(element, config);
2749 this._isShown = false;
2750 this._backdrop = this._initializeBackDrop();
2751 this._focustrap = this._initializeFocusTrap();
2752 this._addEventListeners();
2753 }
2754
2755 // Getters
2756 static get Default() {
2757 return Default$5;
2758 }
2759 static get DefaultType() {
2760 return DefaultType$5;
2761 }
2762 static get NAME() {
2763 return NAME$6;
2764 }
2765
2766 // Public
2767 toggle(relatedTarget) {
2768 return this._isShown ? this.hide() : this.show(relatedTarget);
2769 }
2770 show(relatedTarget) {
2771 if (this._isShown) {
2772 return;
2773 }
2774 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {
2775 relatedTarget
2776 });
2777 if (showEvent.defaultPrevented) {
2778 return;
2779 }
2780 this._isShown = true;
2781 this._backdrop.show();
2782 if (!this._config.scroll) {
2783 new ScrollBarHelper().hide();
2784 }
2785 this._element.setAttribute('aria-modal', true);
2786 this._element.setAttribute('role', 'dialog');
2787 this._element.classList.add(CLASS_NAME_SHOWING$1);
2788 const completeCallBack = () => {
2789 if (!this._config.scroll || this._config.backdrop) {
2790 this._focustrap.activate();
2791 }
2792 this._element.classList.add(CLASS_NAME_SHOW$3);
2793 this._element.classList.remove(CLASS_NAME_SHOWING$1);
2794 EventHandler.trigger(this._element, EVENT_SHOWN$3, {
2795 relatedTarget
2796 });
2797 };
2798 this._queueCallback(completeCallBack, this._element, true);
2799 }
2800 hide() {
2801 if (!this._isShown) {
2802 return;
2803 }
2804 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);
2805 if (hideEvent.defaultPrevented) {
2806 return;
2807 }
2808 this._focustrap.deactivate();
2809 this._element.blur();
2810 this._isShown = false;
2811 this._element.classList.add(CLASS_NAME_HIDING);
2812 this._backdrop.hide();
2813 const completeCallback = () => {
2814 this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING);
2815 this._element.removeAttribute('aria-modal');
2816 this._element.removeAttribute('role');
2817 if (!this._config.scroll) {
2818 new ScrollBarHelper().reset();
2819 }
2820 EventHandler.trigger(this._element, EVENT_HIDDEN$3);
2821 };
2822 this._queueCallback(completeCallback, this._element, true);
2823 }
2824 dispose() {
2825 this._backdrop.dispose();
2826 this._focustrap.deactivate();
2827 super.dispose();
2828 }
2829
2830 // Private
2831 _initializeBackDrop() {
2832 const clickCallback = () => {
2833 if (this._config.backdrop === 'static') {
2834 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
2835 return;
2836 }
2837 this.hide();
2838 };
2839
2840 // 'static' option will be translated to true, and booleans will keep their value
2841 const isVisible = Boolean(this._config.backdrop);
2842 return new Backdrop({
2843 className: CLASS_NAME_BACKDROP,
2844 isVisible,
2845 isAnimated: true,
2846 rootElement: this._element.parentNode,
2847 clickCallback: isVisible ? clickCallback : null
2848 });
2849 }
2850 _initializeFocusTrap() {
2851 return new FocusTrap({
2852 trapElement: this._element
2853 });
2854 }
2855 _addEventListeners() {
2856 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
2857 if (event.key !== ESCAPE_KEY) {
2858 return;
2859 }
2860 if (this._config.keyboard) {
2861 this.hide();
2862 return;
2863 }
2864 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
2865 });
2866 }
2867
2868 // Static
2869 static jQueryInterface(config) {
2870 return this.each(function () {
2871 const data = Offcanvas.getOrCreateInstance(this, config);
2872 if (typeof config !== 'string') {
2873 return;
2874 }
2875 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
2876 throw new TypeError(`No method named "${config}"`);
2877 }
2878 data[config](this);
2879 });
2880 }
2881 }
2882
2883 /**
2884 * Data API implementation
2885 */
2886
2887 EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {
2888 const target = SelectorEngine.getElementFromSelector(this);
2889 if (['A', 'AREA'].includes(this.tagName)) {
2890 event.preventDefault();
2891 }
2892 if (isDisabled(this)) {
2893 return;
2894 }
2895 EventHandler.one(target, EVENT_HIDDEN$3, () => {
2896 // focus on trigger when it is closed
2897 if (isVisible(this)) {
2898 this.focus();
2899 }
2900 });
2901
2902 // avoid conflict when clicking a toggler of an offcanvas, while another is open
2903 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
2904 if (alreadyOpen && alreadyOpen !== target) {
2905 Offcanvas.getInstance(alreadyOpen).hide();
2906 }
2907 const data = Offcanvas.getOrCreateInstance(target);
2908 data.toggle(this);
2909 });
2910 EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {
2911 for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {
2912 Offcanvas.getOrCreateInstance(selector).show();
2913 }
2914 });
2915 EventHandler.on(window, EVENT_RESIZE, () => {
2916 for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {
2917 if (getComputedStyle(element).position !== 'fixed') {
2918 Offcanvas.getOrCreateInstance(element).hide();
2919 }
2920 }
2921 });
2922 enableDismissTrigger(Offcanvas);
2923
2924 /**
2925 * jQuery
2926 */
2927
2928 defineJQueryPlugin(Offcanvas);
2929
2930 /**
2931 * --------------------------------------------------------------------------
2932 * Bootstrap util/sanitizer.js
2933 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2934 * --------------------------------------------------------------------------
2935 */
2936
2937 // js-docs-start allow-list
2938 const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
2939 const DefaultAllowlist = {
2940 // Global attributes allowed on any supplied element below.
2941 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
2942 a: ['target', 'href', 'title', 'rel'],
2943 area: [],
2944 b: [],
2945 br: [],
2946 col: [],
2947 code: [],
2948 dd: [],
2949 div: [],
2950 dl: [],
2951 dt: [],
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
Note: See TracBrowser for help on using the repository browser.