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