source: Application/ocrent/wwwroot/lib/bootstrap/js/bootstrap.esm.js@ f5f7c24

Last change on this file since f5f7c24 was f5f7c24, checked in by 192011 <mk.snicker@…>, 15 months ago

Initial commit

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