/*! * bootstrap v5.1.3 (https://getbootstrap.com/) * copyright 2011-2021 the bootstrap authors (https://github.com/twbs/bootstrap/graphs/contributors) * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core')) : typeof define === 'function' && define.amd ? define(['@popperjs/core'], factory) : (global = typeof globalthis !== 'undefined' ? globalthis : global || self, global.bootstrap = factory(global.popper)); })(this, (function (popper) { 'use strict'; function _interopnamespace(e) { if (e && e.__esmodule) return e; const n = object.create(null); if (e) { for (const k in e) { if (k !== 'default') { const d = object.getownpropertydescriptor(e, k); object.defineproperty(n, k, d.get ? d : { enumerable: true, get: () => e[k] }); } } } n.default = e; return object.freeze(n); } const popper__namespace = /*#__pure__*/_interopnamespace(popper); /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): util/index.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ const max_uid = 1000000; const milliseconds_multiplier = 1000; const transition_end = 'transitionend'; // shoutout anguscroll (https://goo.gl/pxwqgp) const totype = obj => { if (obj === null || obj === undefined) { return `${obj}`; } return {}.tostring.call(obj).match(/\s([a-z]+)/i)[1].tolowercase(); }; /** * -------------------------------------------------------------------------- * public util api * -------------------------------------------------------------------------- */ const getuid = prefix => { do { prefix += math.floor(math.random() * max_uid); } while (document.getelementbyid(prefix)); return prefix; }; const getselector = element => { let selector = element.getattribute('data-bs-target'); if (!selector || selector === '#') { let hrefattr = element.getattribute('href'); // the only valid content that could double as a selector are ids or classes, // so everything starting with `#` or `.`. if a "real" url is used as the selector, // `document.queryselector` will rightfully complain it is invalid. // see https://github.com/twbs/bootstrap/issues/32273 if (!hrefattr || !hrefattr.includes('#') && !hrefattr.startswith('.')) { return null; } // just in case some cms puts out a full url with the anchor appended if (hrefattr.includes('#') && !hrefattr.startswith('#')) { hrefattr = `#${hrefattr.split('#')[1]}`; } selector = hrefattr && hrefattr !== '#' ? hrefattr.trim() : null; } return selector; }; const getselectorfromelement = element => { const selector = getselector(element); if (selector) { return document.queryselector(selector) ? selector : null; } return null; }; const getelementfromselector = element => { const selector = getselector(element); return selector ? document.queryselector(selector) : null; }; const gettransitiondurationfromelement = element => { if (!element) { return 0; } // get transition-duration of the element let { transitionduration, transitiondelay } = window.getcomputedstyle(element); const floattransitionduration = number.parsefloat(transitionduration); const floattransitiondelay = number.parsefloat(transitiondelay); // return 0 if element or transition duration is not found if (!floattransitionduration && !floattransitiondelay) { return 0; } // if multiple durations are defined, take the first transitionduration = transitionduration.split(',')[0]; transitiondelay = transitiondelay.split(',')[0]; return (number.parsefloat(transitionduration) + number.parsefloat(transitiondelay)) * milliseconds_multiplier; }; const triggertransitionend = element => { element.dispatchevent(new event(transition_end)); }; const iselement = obj => { if (!obj || typeof obj !== 'object') { return false; } if (typeof obj.jquery !== 'undefined') { obj = obj[0]; } return typeof obj.nodetype !== 'undefined'; }; const getelement = obj => { if (iselement(obj)) { // it's a jquery object or a node element return obj.jquery ? obj[0] : obj; } if (typeof obj === 'string' && obj.length > 0) { return document.queryselector(obj); } return null; }; const typecheckconfig = (componentname, config, configtypes) => { object.keys(configtypes).foreach(property => { const expectedtypes = configtypes[property]; const value = config[property]; const valuetype = value && iselement(value) ? 'element' : totype(value); if (!new regexp(expectedtypes).test(valuetype)) { throw new typeerror(`${componentname.touppercase()}: option "${property}" provided type "${valuetype}" but expected type "${expectedtypes}".`); } }); }; const isvisible = element => { if (!iselement(element) || element.getclientrects().length === 0) { return false; } return getcomputedstyle(element).getpropertyvalue('visibility') === 'visible'; }; const isdisabled = element => { if (!element || element.nodetype !== node.element_node) { return true; } if (element.classlist.contains('disabled')) { return true; } if (typeof element.disabled !== 'undefined') { return element.disabled; } return element.hasattribute('disabled') && element.getattribute('disabled') !== 'false'; }; const findshadowroot = element => { if (!document.documentelement.attachshadow) { return null; } // can find the shadow root otherwise it'll return the document if (typeof element.getrootnode === 'function') { const root = element.getrootnode(); return root instanceof shadowroot ? root : null; } if (element instanceof shadowroot) { return element; } // when we don't find a shadow root if (!element.parentnode) { return null; } return findshadowroot(element.parentnode); }; const noop = () => {}; /** * trick to restart an element's animation * * @param {htmlelement} element * @return void * * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation */ const reflow = element => { // eslint-disable-next-line no-unused-expressions element.offsetheight; }; const getjquery = () => { const { jquery } = window; if (jquery && !document.body.hasattribute('data-bs-no-jquery')) { return jquery; } return null; }; const domcontentloadedcallbacks = []; const ondomcontentloaded = callback => { if (document.readystate === 'loading') { // add listener on the first call when the document is in loading state if (!domcontentloadedcallbacks.length) { document.addeventlistener('domcontentloaded', () => { domcontentloadedcallbacks.foreach(callback => callback()); }); } domcontentloadedcallbacks.push(callback); } else { callback(); } }; const isrtl = () => document.documentelement.dir === 'rtl'; const definejqueryplugin = plugin => { ondomcontentloaded(() => { const $ = getjquery(); /* istanbul ignore if */ if ($) { const name = plugin.name; const jquery_no_conflict = $.fn[name]; $.fn[name] = plugin.jqueryinterface; $.fn[name].constructor = plugin; $.fn[name].noconflict = () => { $.fn[name] = jquery_no_conflict; return plugin.jqueryinterface; }; } }); }; const execute = callback => { if (typeof callback === 'function') { callback(); } }; const executeaftertransition = (callback, transitionelement, waitfortransition = true) => { if (!waitfortransition) { execute(callback); return; } const durationpadding = 5; const emulatedduration = gettransitiondurationfromelement(transitionelement) + durationpadding; let called = false; const handler = ({ target }) => { if (target !== transitionelement) { return; } called = true; transitionelement.removeeventlistener(transition_end, handler); execute(callback); }; transitionelement.addeventlistener(transition_end, handler); settimeout(() => { if (!called) { triggertransitionend(transitionelement); } }, emulatedduration); }; /** * return the previous/next element of a list. * * @param {array} list the list of elements * @param activeelement the active element * @param shouldgetnext choose to get next or previous element * @param iscycleallowed * @return {element|elem} the proper element */ const getnextactiveelement = (list, activeelement, shouldgetnext, iscycleallowed) => { let index = list.indexof(activeelement); // if the element does not exist in the list return an element depending on the direction and if cycle is allowed if (index === -1) { return list[!shouldgetnext && iscycleallowed ? list.length - 1 : 0]; } const listlength = list.length; index += shouldgetnext ? 1 : -1; if (iscycleallowed) { index = (index + listlength) % listlength; } return list[math.max(0, math.min(index, listlength - 1))]; }; /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): dom/event-handler.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const namespaceregex = /[^.]*(?=\..*)\.|.*/; const stripnameregex = /\..*/; const stripuidregex = /::\d+$/; const eventregistry = {}; // events storage let uidevent = 1; const customevents = { mouseenter: 'mouseover', mouseleave: 'mouseout' }; const customeventsregex = /^(mouseenter|mouseleave)/i; 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']); /** * ------------------------------------------------------------------------ * private methods * ------------------------------------------------------------------------ */ function getuidevent(element, uid) { return uid && `${uid}::${uidevent++}` || element.uidevent || uidevent++; } function getevent(element) { const uid = getuidevent(element); element.uidevent = uid; eventregistry[uid] = eventregistry[uid] || {}; return eventregistry[uid]; } function bootstraphandler(element, fn) { return function handler(event) { event.delegatetarget = element; if (handler.oneoff) { eventhandler.off(element, event.type, fn); } return fn.apply(element, [event]); }; } function bootstrapdelegationhandler(element, selector, fn) { return function handler(event) { const domelements = element.queryselectorall(selector); for (let { target } = event; target && target !== this; target = target.parentnode) { for (let i = domelements.length; i--;) { if (domelements[i] === target) { event.delegatetarget = target; if (handler.oneoff) { eventhandler.off(element, event.type, selector, fn); } return fn.apply(target, [event]); } } } // to please eslint return null; }; } function findhandler(events, handler, delegationselector = null) { const uideventlist = object.keys(events); for (let i = 0, len = uideventlist.length; i < len; i++) { const event = events[uideventlist[i]]; if (event.originalhandler === handler && event.delegationselector === delegationselector) { return event; } } return null; } function normalizeparams(originaltypeevent, handler, delegationfn) { const delegation = typeof handler === 'string'; const originalhandler = delegation ? delegationfn : handler; let typeevent = gettypeevent(originaltypeevent); const isnative = nativeevents.has(typeevent); if (!isnative) { typeevent = originaltypeevent; } return [delegation, originalhandler, typeevent]; } function addhandler(element, originaltypeevent, handler, delegationfn, oneoff) { if (typeof originaltypeevent !== 'string' || !element) { return; } if (!handler) { handler = delegationfn; delegationfn = null; } // in case of mouseenter or mouseleave wrap the handler within a function that checks for its dom position // this prevents the handler from being dispatched the same way as mouseover or mouseout does if (customeventsregex.test(originaltypeevent)) { const wrapfn = fn => { return function (event) { if (!event.relatedtarget || event.relatedtarget !== event.delegatetarget && !event.delegatetarget.contains(event.relatedtarget)) { return fn.call(this, event); } }; }; if (delegationfn) { delegationfn = wrapfn(delegationfn); } else { handler = wrapfn(handler); } } const [delegation, originalhandler, typeevent] = normalizeparams(originaltypeevent, handler, delegationfn); const events = getevent(element); const handlers = events[typeevent] || (events[typeevent] = {}); const previousfn = findhandler(handlers, originalhandler, delegation ? handler : null); if (previousfn) { previousfn.oneoff = previousfn.oneoff && oneoff; return; } const uid = getuidevent(originalhandler, originaltypeevent.replace(namespaceregex, '')); const fn = delegation ? bootstrapdelegationhandler(element, handler, delegationfn) : bootstraphandler(element, handler); fn.delegationselector = delegation ? handler : null; fn.originalhandler = originalhandler; fn.oneoff = oneoff; fn.uidevent = uid; handlers[uid] = fn; element.addeventlistener(typeevent, fn, delegation); } function removehandler(element, events, typeevent, handler, delegationselector) { const fn = findhandler(events[typeevent], handler, delegationselector); if (!fn) { return; } element.removeeventlistener(typeevent, fn, boolean(delegationselector)); delete events[typeevent][fn.uidevent]; } function removenamespacedhandlers(element, events, typeevent, namespace) { const storeelementevent = events[typeevent] || {}; object.keys(storeelementevent).foreach(handlerkey => { if (handlerkey.includes(namespace)) { const event = storeelementevent[handlerkey]; removehandler(element, events, typeevent, event.originalhandler, event.delegationselector); } }); } function gettypeevent(event) { // allow to get the native events from namespaced events ('click.bs.button' --> 'click') event = event.replace(stripnameregex, ''); return customevents[event] || event; } const eventhandler = { on(element, event, handler, delegationfn) { addhandler(element, event, handler, delegationfn, false); }, one(element, event, handler, delegationfn) { addhandler(element, event, handler, delegationfn, true); }, off(element, originaltypeevent, handler, delegationfn) { if (typeof originaltypeevent !== 'string' || !element) { return; } const [delegation, originalhandler, typeevent] = normalizeparams(originaltypeevent, handler, delegationfn); const innamespace = typeevent !== originaltypeevent; const events = getevent(element); const isnamespace = originaltypeevent.startswith('.'); if (typeof originalhandler !== 'undefined') { // simplest case: handler is passed, remove that listener only. if (!events || !events[typeevent]) { return; } removehandler(element, events, typeevent, originalhandler, delegation ? handler : null); return; } if (isnamespace) { object.keys(events).foreach(elementevent => { removenamespacedhandlers(element, events, elementevent, originaltypeevent.slice(1)); }); } const storeelementevent = events[typeevent] || {}; object.keys(storeelementevent).foreach(keyhandlers => { const handlerkey = keyhandlers.replace(stripuidregex, ''); if (!innamespace || originaltypeevent.includes(handlerkey)) { const event = storeelementevent[keyhandlers]; removehandler(element, events, typeevent, event.originalhandler, event.delegationselector); } }); }, trigger(element, event, args) { if (typeof event !== 'string' || !element) { return null; } const $ = getjquery(); const typeevent = gettypeevent(event); const innamespace = event !== typeevent; const isnative = nativeevents.has(typeevent); let jqueryevent; let bubbles = true; let nativedispatch = true; let defaultprevented = false; let evt = null; if (innamespace && $) { jqueryevent = $.event(event, args); $(element).trigger(jqueryevent); bubbles = !jqueryevent.ispropagationstopped(); nativedispatch = !jqueryevent.isimmediatepropagationstopped(); defaultprevented = jqueryevent.isdefaultprevented(); } if (isnative) { evt = document.createevent('htmlevents'); evt.initevent(typeevent, bubbles, true); } else { evt = new customevent(event, { bubbles, cancelable: true }); } // merge custom information in our event if (typeof args !== 'undefined') { object.keys(args).foreach(key => { object.defineproperty(evt, key, { get() { return args[key]; } }); }); } if (defaultprevented) { evt.preventdefault(); } if (nativedispatch) { element.dispatchevent(evt); } if (evt.defaultprevented && typeof jqueryevent !== 'undefined') { jqueryevent.preventdefault(); } return evt; } }; /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): dom/data.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const elementmap = new map(); const data = { set(element, key, instance) { if (!elementmap.has(element)) { elementmap.set(element, new map()); } const instancemap = elementmap.get(element); // make it clear we only want one instance per element // can be removed later when multiple key/instances are fine to be used if (!instancemap.has(key) && instancemap.size !== 0) { // eslint-disable-next-line no-console console.error(`bootstrap doesn't allow more than one instance per element. bound instance: ${array.from(instancemap.keys())[0]}.`); return; } instancemap.set(key, instance); }, get(element, key) { if (elementmap.has(element)) { return elementmap.get(element).get(key) || null; } return null; }, remove(element, key) { if (!elementmap.has(element)) { return; } const instancemap = elementmap.get(element); instancemap.delete(key); // free up element references if there are no instances left for an element if (instancemap.size === 0) { elementmap.delete(element); } } }; /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): base-component.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const version = '5.1.3'; class basecomponent { constructor(element) { element = getelement(element); if (!element) { return; } this._element = element; data.set(this._element, this.constructor.data_key, this); } dispose() { data.remove(this._element, this.constructor.data_key); eventhandler.off(this._element, this.constructor.event_key); object.getownpropertynames(this).foreach(propertyname => { this[propertyname] = null; }); } _queuecallback(callback, element, isanimated = true) { executeaftertransition(callback, element, isanimated); } /** static */ static getinstance(element) { return data.get(getelement(element), this.data_key); } static getorcreateinstance(element, config = {}) { return this.getinstance(element) || new this(element, typeof config === 'object' ? config : null); } static get version() { return version; } static get name() { throw new error('you have to implement the static method "name", for each component!'); } static get data_key() { return `bs.${this.name}`; } static get event_key() { return `.${this.data_key}`; } } /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): util/component-functions.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ const enabledismisstrigger = (component, method = 'hide') => { const clickevent = `click.dismiss${component.event_key}`; const name = component.name; eventhandler.on(document, clickevent, `[data-bs-dismiss="${name}"]`, function (event) { if (['a', 'area'].includes(this.tagname)) { event.preventdefault(); } if (isdisabled(this)) { return; } const target = getelementfromselector(this) || this.closest(`.${name}`); const instance = component.getorcreateinstance(target); // method argument is left, for alert and only, as it doesn't implement the 'hide' method instance[method](); }); }; /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): alert.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const name$d = 'alert'; const data_key$c = 'bs.alert'; const event_key$c = `.${data_key$c}`; const event_close = `close${event_key$c}`; const event_closed = `closed${event_key$c}`; const class_name_fade$5 = 'fade'; const class_name_show$8 = 'show'; /** * ------------------------------------------------------------------------ * class definition * ------------------------------------------------------------------------ */ class alert extends basecomponent { // getters static get name() { return name$d; } // public close() { const closeevent = eventhandler.trigger(this._element, event_close); if (closeevent.defaultprevented) { return; } this._element.classlist.remove(class_name_show$8); const isanimated = this._element.classlist.contains(class_name_fade$5); this._queuecallback(() => this._destroyelement(), this._element, isanimated); } // private _destroyelement() { this._element.remove(); eventhandler.trigger(this._element, event_closed); this.dispose(); } // static static jqueryinterface(config) { return this.each(function () { const data = alert.getorcreateinstance(this); if (typeof config !== 'string') { return; } if (data[config] === undefined || config.startswith('_') || config === 'constructor') { throw new typeerror(`no method named "${config}"`); } data[config](this); }); } } /** * ------------------------------------------------------------------------ * data api implementation * ------------------------------------------------------------------------ */ enabledismisstrigger(alert, 'close'); /** * ------------------------------------------------------------------------ * jquery * ------------------------------------------------------------------------ * add .alert to jquery only if jquery is present */ definejqueryplugin(alert); /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): button.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const name$c = 'button'; const data_key$b = 'bs.button'; const event_key$b = `.${data_key$b}`; const data_api_key$7 = '.data-api'; const class_name_active$3 = 'active'; const selector_data_toggle$5 = '[data-bs-toggle="button"]'; const event_click_data_api$6 = `click${event_key$b}${data_api_key$7}`; /** * ------------------------------------------------------------------------ * class definition * ------------------------------------------------------------------------ */ class button extends basecomponent { // getters static get name() { return name$c; } // public toggle() { // toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method this._element.setattribute('aria-pressed', this._element.classlist.toggle(class_name_active$3)); } // static static jqueryinterface(config) { return this.each(function () { const data = button.getorcreateinstance(this); if (config === 'toggle') { data[config](); } }); } } /** * ------------------------------------------------------------------------ * data api implementation * ------------------------------------------------------------------------ */ eventhandler.on(document, event_click_data_api$6, selector_data_toggle$5, event => { event.preventdefault(); const button = event.target.closest(selector_data_toggle$5); const data = button.getorcreateinstance(button); data.toggle(); }); /** * ------------------------------------------------------------------------ * jquery * ------------------------------------------------------------------------ * add .button to jquery only if jquery is present */ definejqueryplugin(button); /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): dom/manipulator.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ function normalizedata(val) { if (val === 'true') { return true; } if (val === 'false') { return false; } if (val === number(val).tostring()) { return number(val); } if (val === '' || val === 'null') { return null; } return val; } function normalizedatakey(key) { return key.replace(/[a-z]/g, chr => `-${chr.tolowercase()}`); } const manipulator = { setdataattribute(element, key, value) { element.setattribute(`data-bs-${normalizedatakey(key)}`, value); }, removedataattribute(element, key) { element.removeattribute(`data-bs-${normalizedatakey(key)}`); }, getdataattributes(element) { if (!element) { return {}; } const attributes = {}; object.keys(element.dataset).filter(key => key.startswith('bs')).foreach(key => { let purekey = key.replace(/^bs/, ''); purekey = purekey.charat(0).tolowercase() + purekey.slice(1, purekey.length); attributes[purekey] = normalizedata(element.dataset[key]); }); return attributes; }, getdataattribute(element, key) { return normalizedata(element.getattribute(`data-bs-${normalizedatakey(key)}`)); }, offset(element) { const rect = element.getboundingclientrect(); return { top: rect.top + window.pageyoffset, left: rect.left + window.pagexoffset }; }, position(element) { return { top: element.offsettop, left: element.offsetleft }; } }; /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): dom/selector-engine.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ const node_text = 3; const selectorengine = { find(selector, element = document.documentelement) { return [].concat(...element.prototype.queryselectorall.call(element, selector)); }, findone(selector, element = document.documentelement) { return element.prototype.queryselector.call(element, selector); }, children(element, selector) { return [].concat(...element.children).filter(child => child.matches(selector)); }, parents(element, selector) { const parents = []; let ancestor = element.parentnode; while (ancestor && ancestor.nodetype === node.element_node && ancestor.nodetype !== node_text) { if (ancestor.matches(selector)) { parents.push(ancestor); } ancestor = ancestor.parentnode; } return parents; }, prev(element, selector) { let previous = element.previouselementsibling; while (previous) { if (previous.matches(selector)) { return [previous]; } previous = previous.previouselementsibling; } return []; }, next(element, selector) { let next = element.nextelementsibling; while (next) { if (next.matches(selector)) { return [next]; } next = next.nextelementsibling; } return []; }, focusablechildren(element) { const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `${selector}:not([tabindex^="-"])`).join(', '); return this.find(focusables, element).filter(el => !isdisabled(el) && isvisible(el)); } }; /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): carousel.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const name$b = 'carousel'; const data_key$a = 'bs.carousel'; const event_key$a = `.${data_key$a}`; const data_api_key$6 = '.data-api'; const arrow_left_key = 'arrowleft'; const arrow_right_key = 'arrowright'; const touchevent_compat_wait = 500; // time for mouse compat events to fire after touch const swipe_threshold = 40; const default$a = { interval: 5000, keyboard: true, slide: false, pause: 'hover', wrap: true, touch: true }; const defaulttype$a = { interval: '(number|boolean)', keyboard: 'boolean', slide: '(boolean|string)', pause: '(string|boolean)', wrap: 'boolean', touch: 'boolean' }; const order_next = 'next'; const order_prev = 'prev'; const direction_left = 'left'; const direction_right = 'right'; const key_to_direction = { [arrow_left_key]: direction_right, [arrow_right_key]: direction_left }; const event_slide = `slide${event_key$a}`; const event_slid = `slid${event_key$a}`; const event_keydown = `keydown${event_key$a}`; const event_mouseenter = `mouseenter${event_key$a}`; const event_mouseleave = `mouseleave${event_key$a}`; const event_touchstart = `touchstart${event_key$a}`; const event_touchmove = `touchmove${event_key$a}`; const event_touchend = `touchend${event_key$a}`; const event_pointerdown = `pointerdown${event_key$a}`; const event_pointerup = `pointerup${event_key$a}`; const event_drag_start = `dragstart${event_key$a}`; const event_load_data_api$2 = `load${event_key$a}${data_api_key$6}`; const event_click_data_api$5 = `click${event_key$a}${data_api_key$6}`; const class_name_carousel = 'carousel'; const class_name_active$2 = 'active'; const class_name_slide = 'slide'; const class_name_end = 'carousel-item-end'; const class_name_start = 'carousel-item-start'; const class_name_next = 'carousel-item-next'; const class_name_prev = 'carousel-item-prev'; const class_name_pointer_event = 'pointer-event'; const selector_active$1 = '.active'; const selector_active_item = '.active.carousel-item'; const selector_item = '.carousel-item'; const selector_item_img = '.carousel-item img'; const selector_next_prev = '.carousel-item-next, .carousel-item-prev'; const selector_indicators = '.carousel-indicators'; const selector_indicator = '[data-bs-target]'; const selector_data_slide = '[data-bs-slide], [data-bs-slide-to]'; const selector_data_ride = '[data-bs-ride="carousel"]'; const pointer_type_touch = 'touch'; const pointer_type_pen = 'pen'; /** * ------------------------------------------------------------------------ * class definition * ------------------------------------------------------------------------ */ class carousel extends basecomponent { constructor(element, config) { super(element); this._items = null; this._interval = null; this._activeelement = null; this._ispaused = false; this._issliding = false; this.touchtimeout = null; this.touchstartx = 0; this.touchdeltax = 0; this._config = this._getconfig(config); this._indicatorselement = selectorengine.findone(selector_indicators, this._element); this._touchsupported = 'ontouchstart' in document.documentelement || navigator.maxtouchpoints > 0; this._pointerevent = boolean(window.pointerevent); this._addeventlisteners(); } // getters static get default() { return default$a; } static get name() { return name$b; } // public next() { this._slide(order_next); } nextwhenvisible() { // don't call next when the page isn't visible // or the carousel or its parent isn't visible if (!document.hidden && isvisible(this._element)) { this.next(); } } prev() { this._slide(order_prev); } pause(event) { if (!event) { this._ispaused = true; } if (selectorengine.findone(selector_next_prev, this._element)) { triggertransitionend(this._element); this.cycle(true); } clearinterval(this._interval); this._interval = null; } cycle(event) { if (!event) { this._ispaused = false; } if (this._interval) { clearinterval(this._interval); this._interval = null; } if (this._config && this._config.interval && !this._ispaused) { this._updateinterval(); this._interval = setinterval((document.visibilitystate ? this.nextwhenvisible : this.next).bind(this), this._config.interval); } } to(index) { this._activeelement = selectorengine.findone(selector_active_item, this._element); const activeindex = this._getitemindex(this._activeelement); if (index > this._items.length - 1 || index < 0) { return; } if (this._issliding) { eventhandler.one(this._element, event_slid, () => this.to(index)); return; } if (activeindex === index) { this.pause(); this.cycle(); return; } const order = index > activeindex ? order_next : order_prev; this._slide(order, this._items[index]); } // private _getconfig(config) { config = { ...default$a, ...manipulator.getdataattributes(this._element), ...(typeof config === 'object' ? config : {}) }; typecheckconfig(name$b, config, defaulttype$a); return config; } _handleswipe() { const absdeltax = math.abs(this.touchdeltax); if (absdeltax <= swipe_threshold) { return; } const direction = absdeltax / this.touchdeltax; this.touchdeltax = 0; if (!direction) { return; } this._slide(direction > 0 ? direction_right : direction_left); } _addeventlisteners() { if (this._config.keyboard) { eventhandler.on(this._element, event_keydown, event => this._keydown(event)); } if (this._config.pause === 'hover') { eventhandler.on(this._element, event_mouseenter, event => this.pause(event)); eventhandler.on(this._element, event_mouseleave, event => this.cycle(event)); } if (this._config.touch && this._touchsupported) { this._addtoucheventlisteners(); } } _addtoucheventlisteners() { const haspointerpentouch = event => { return this._pointerevent && (event.pointertype === pointer_type_pen || event.pointertype === pointer_type_touch); }; const start = event => { if (haspointerpentouch(event)) { this.touchstartx = event.clientx; } else if (!this._pointerevent) { this.touchstartx = event.touches[0].clientx; } }; const move = event => { // ensure swiping with one touch and not pinching this.touchdeltax = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientx - this.touchstartx; }; const end = event => { if (haspointerpentouch(event)) { this.touchdeltax = event.clientx - this.touchstartx; } this._handleswipe(); if (this._config.pause === 'hover') { // if it's a touch-enabled device, mouseenter/leave are fired as // part of the mouse compatibility events on first tap - the carousel // would stop cycling until user tapped out of it; // here, we listen for touchend, explicitly pause the carousel // (as if it's the second time we tap on it, mouseenter compat event // is not fired) and after a timeout (to allow for mouse compatibility // events to fire) we explicitly restart cycling this.pause(); if (this.touchtimeout) { cleartimeout(this.touchtimeout); } this.touchtimeout = settimeout(event => this.cycle(event), touchevent_compat_wait + this._config.interval); } }; selectorengine.find(selector_item_img, this._element).foreach(itemimg => { eventhandler.on(itemimg, event_drag_start, event => event.preventdefault()); }); if (this._pointerevent) { eventhandler.on(this._element, event_pointerdown, event => start(event)); eventhandler.on(this._element, event_pointerup, event => end(event)); this._element.classlist.add(class_name_pointer_event); } else { eventhandler.on(this._element, event_touchstart, event => start(event)); eventhandler.on(this._element, event_touchmove, event => move(event)); eventhandler.on(this._element, event_touchend, event => end(event)); } } _keydown(event) { if (/input|textarea/i.test(event.target.tagname)) { return; } const direction = key_to_direction[event.key]; if (direction) { event.preventdefault(); this._slide(direction); } } _getitemindex(element) { this._items = element && element.parentnode ? selectorengine.find(selector_item, element.parentnode) : []; return this._items.indexof(element); } _getitembyorder(order, activeelement) { const isnext = order === order_next; return getnextactiveelement(this._items, activeelement, isnext, this._config.wrap); } _triggerslideevent(relatedtarget, eventdirectionname) { const targetindex = this._getitemindex(relatedtarget); const fromindex = this._getitemindex(selectorengine.findone(selector_active_item, this._element)); return eventhandler.trigger(this._element, event_slide, { relatedtarget, direction: eventdirectionname, from: fromindex, to: targetindex }); } _setactiveindicatorelement(element) { if (this._indicatorselement) { const activeindicator = selectorengine.findone(selector_active$1, this._indicatorselement); activeindicator.classlist.remove(class_name_active$2); activeindicator.removeattribute('aria-current'); const indicators = selectorengine.find(selector_indicator, this._indicatorselement); for (let i = 0; i < indicators.length; i++) { if (number.parseint(indicators[i].getattribute('data-bs-slide-to'), 10) === this._getitemindex(element)) { indicators[i].classlist.add(class_name_active$2); indicators[i].setattribute('aria-current', 'true'); break; } } } } _updateinterval() { const element = this._activeelement || selectorengine.findone(selector_active_item, this._element); if (!element) { return; } const elementinterval = number.parseint(element.getattribute('data-bs-interval'), 10); if (elementinterval) { this._config.defaultinterval = this._config.defaultinterval || this._config.interval; this._config.interval = elementinterval; } else { this._config.interval = this._config.defaultinterval || this._config.interval; } } _slide(directionororder, element) { const order = this._directiontoorder(directionororder); const activeelement = selectorengine.findone(selector_active_item, this._element); const activeelementindex = this._getitemindex(activeelement); const nextelement = element || this._getitembyorder(order, activeelement); const nextelementindex = this._getitemindex(nextelement); const iscycling = boolean(this._interval); const isnext = order === order_next; const directionalclassname = isnext ? class_name_start : class_name_end; const orderclassname = isnext ? class_name_next : class_name_prev; const eventdirectionname = this._ordertodirection(order); if (nextelement && nextelement.classlist.contains(class_name_active$2)) { this._issliding = false; return; } if (this._issliding) { return; } const slideevent = this._triggerslideevent(nextelement, eventdirectionname); if (slideevent.defaultprevented) { return; } if (!activeelement || !nextelement) { // some weirdness is happening, so we bail return; } this._issliding = true; if (iscycling) { this.pause(); } this._setactiveindicatorelement(nextelement); this._activeelement = nextelement; const triggerslidevent = () => { eventhandler.trigger(this._element, event_slid, { relatedtarget: nextelement, direction: eventdirectionname, from: activeelementindex, to: nextelementindex }); }; if (this._element.classlist.contains(class_name_slide)) { nextelement.classlist.add(orderclassname); reflow(nextelement); activeelement.classlist.add(directionalclassname); nextelement.classlist.add(directionalclassname); const completecallback = () => { nextelement.classlist.remove(directionalclassname, orderclassname); nextelement.classlist.add(class_name_active$2); activeelement.classlist.remove(class_name_active$2, orderclassname, directionalclassname); this._issliding = false; settimeout(triggerslidevent, 0); }; this._queuecallback(completecallback, activeelement, true); } else { activeelement.classlist.remove(class_name_active$2); nextelement.classlist.add(class_name_active$2); this._issliding = false; triggerslidevent(); } if (iscycling) { this.cycle(); } } _directiontoorder(direction) { if (![direction_right, direction_left].includes(direction)) { return direction; } if (isrtl()) { return direction === direction_left ? order_prev : order_next; } return direction === direction_left ? order_next : order_prev; } _ordertodirection(order) { if (![order_next, order_prev].includes(order)) { return order; } if (isrtl()) { return order === order_prev ? direction_left : direction_right; } return order === order_prev ? direction_right : direction_left; } // static static carouselinterface(element, config) { const data = carousel.getorcreateinstance(element, config); let { _config } = data; if (typeof config === 'object') { _config = { ..._config, ...config }; } const action = typeof config === 'string' ? config : _config.slide; if (typeof config === 'number') { data.to(config); } else if (typeof action === 'string') { if (typeof data[action] === 'undefined') { throw new typeerror(`no method named "${action}"`); } data[action](); } else if (_config.interval && _config.ride) { data.pause(); data.cycle(); } } static jqueryinterface(config) { return this.each(function () { carousel.carouselinterface(this, config); }); } static dataapiclickhandler(event) { const target = getelementfromselector(this); if (!target || !target.classlist.contains(class_name_carousel)) { return; } const config = { ...manipulator.getdataattributes(target), ...manipulator.getdataattributes(this) }; const slideindex = this.getattribute('data-bs-slide-to'); if (slideindex) { config.interval = false; } carousel.carouselinterface(target, config); if (slideindex) { carousel.getinstance(target).to(slideindex); } event.preventdefault(); } } /** * ------------------------------------------------------------------------ * data api implementation * ------------------------------------------------------------------------ */ eventhandler.on(document, event_click_data_api$5, selector_data_slide, carousel.dataapiclickhandler); eventhandler.on(window, event_load_data_api$2, () => { const carousels = selectorengine.find(selector_data_ride); for (let i = 0, len = carousels.length; i < len; i++) { carousel.carouselinterface(carousels[i], carousel.getinstance(carousels[i])); } }); /** * ------------------------------------------------------------------------ * jquery * ------------------------------------------------------------------------ * add .carousel to jquery only if jquery is present */ definejqueryplugin(carousel); /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): collapse.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const name$a = 'collapse'; const data_key$9 = 'bs.collapse'; const event_key$9 = `.${data_key$9}`; const data_api_key$5 = '.data-api'; const default$9 = { toggle: true, parent: null }; const defaulttype$9 = { toggle: 'boolean', parent: '(null|element)' }; const event_show$5 = `show${event_key$9}`; const event_shown$5 = `shown${event_key$9}`; const event_hide$5 = `hide${event_key$9}`; const event_hidden$5 = `hidden${event_key$9}`; const event_click_data_api$4 = `click${event_key$9}${data_api_key$5}`; const class_name_show$7 = 'show'; const class_name_collapse = 'collapse'; const class_name_collapsing = 'collapsing'; const class_name_collapsed = 'collapsed'; const class_name_deeper_children = `:scope .${class_name_collapse} .${class_name_collapse}`; const class_name_horizontal = 'collapse-horizontal'; const width = 'width'; const height = 'height'; const selector_actives = '.collapse.show, .collapse.collapsing'; const selector_data_toggle$4 = '[data-bs-toggle="collapse"]'; /** * ------------------------------------------------------------------------ * class definition * ------------------------------------------------------------------------ */ class collapse extends basecomponent { constructor(element, config) { super(element); this._istransitioning = false; this._config = this._getconfig(config); this._triggerarray = []; const togglelist = selectorengine.find(selector_data_toggle$4); for (let i = 0, len = togglelist.length; i < len; i++) { const elem = togglelist[i]; const selector = getselectorfromelement(elem); const filterelement = selectorengine.find(selector).filter(foundelem => foundelem === this._element); if (selector !== null && filterelement.length) { this._selector = selector; this._triggerarray.push(elem); } } this._initializechildren(); if (!this._config.parent) { this._addariaandcollapsedclass(this._triggerarray, this._isshown()); } if (this._config.toggle) { this.toggle(); } } // getters static get default() { return default$9; } static get name() { return name$a; } // public toggle() { if (this._isshown()) { this.hide(); } else { this.show(); } } show() { if (this._istransitioning || this._isshown()) { return; } let actives = []; let activesdata; if (this._config.parent) { const children = selectorengine.find(class_name_deeper_children, this._config.parent); actives = selectorengine.find(selector_actives, this._config.parent).filter(elem => !children.includes(elem)); // remove children if greater depth } const container = selectorengine.findone(this._selector); if (actives.length) { const tempactivedata = actives.find(elem => container !== elem); activesdata = tempactivedata ? collapse.getinstance(tempactivedata) : null; if (activesdata && activesdata._istransitioning) { return; } } const startevent = eventhandler.trigger(this._element, event_show$5); if (startevent.defaultprevented) { return; } actives.foreach(elemactive => { if (container !== elemactive) { collapse.getorcreateinstance(elemactive, { toggle: false }).hide(); } if (!activesdata) { data.set(elemactive, data_key$9, null); } }); const dimension = this._getdimension(); this._element.classlist.remove(class_name_collapse); this._element.classlist.add(class_name_collapsing); this._element.style[dimension] = 0; this._addariaandcollapsedclass(this._triggerarray, true); this._istransitioning = true; const complete = () => { this._istransitioning = false; this._element.classlist.remove(class_name_collapsing); this._element.classlist.add(class_name_collapse, class_name_show$7); this._element.style[dimension] = ''; eventhandler.trigger(this._element, event_shown$5); }; const capitalizeddimension = dimension[0].touppercase() + dimension.slice(1); const scrollsize = `scroll${capitalizeddimension}`; this._queuecallback(complete, this._element, true); this._element.style[dimension] = `${this._element[scrollsize]}px`; } hide() { if (this._istransitioning || !this._isshown()) { return; } const startevent = eventhandler.trigger(this._element, event_hide$5); if (startevent.defaultprevented) { return; } const dimension = this._getdimension(); this._element.style[dimension] = `${this._element.getboundingclientrect()[dimension]}px`; reflow(this._element); this._element.classlist.add(class_name_collapsing); this._element.classlist.remove(class_name_collapse, class_name_show$7); const triggerarraylength = this._triggerarray.length; for (let i = 0; i < triggerarraylength; i++) { const trigger = this._triggerarray[i]; const elem = getelementfromselector(trigger); if (elem && !this._isshown(elem)) { this._addariaandcollapsedclass([trigger], false); } } this._istransitioning = true; const complete = () => { this._istransitioning = false; this._element.classlist.remove(class_name_collapsing); this._element.classlist.add(class_name_collapse); eventhandler.trigger(this._element, event_hidden$5); }; this._element.style[dimension] = ''; this._queuecallback(complete, this._element, true); } _isshown(element = this._element) { return element.classlist.contains(class_name_show$7); } // private _getconfig(config) { config = { ...default$9, ...manipulator.getdataattributes(this._element), ...config }; config.toggle = boolean(config.toggle); // coerce string values config.parent = getelement(config.parent); typecheckconfig(name$a, config, defaulttype$9); return config; } _getdimension() { return this._element.classlist.contains(class_name_horizontal) ? width : height; } _initializechildren() { if (!this._config.parent) { return; } const children = selectorengine.find(class_name_deeper_children, this._config.parent); selectorengine.find(selector_data_toggle$4, this._config.parent).filter(elem => !children.includes(elem)).foreach(element => { const selected = getelementfromselector(element); if (selected) { this._addariaandcollapsedclass([element], this._isshown(selected)); } }); } _addariaandcollapsedclass(triggerarray, isopen) { if (!triggerarray.length) { return; } triggerarray.foreach(elem => { if (isopen) { elem.classlist.remove(class_name_collapsed); } else { elem.classlist.add(class_name_collapsed); } elem.setattribute('aria-expanded', isopen); }); } // static static jqueryinterface(config) { return this.each(function () { const _config = {}; if (typeof config === 'string' && /show|hide/.test(config)) { _config.toggle = false; } const data = collapse.getorcreateinstance(this, _config); if (typeof config === 'string') { if (typeof data[config] === 'undefined') { throw new typeerror(`no method named "${config}"`); } data[config](); } }); } } /** * ------------------------------------------------------------------------ * data api implementation * ------------------------------------------------------------------------ */ eventhandler.on(document, event_click_data_api$4, selector_data_toggle$4, function (event) { // preventdefault only for elements (which change the url) not inside the collapsible element if (event.target.tagname === 'a' || event.delegatetarget && event.delegatetarget.tagname === 'a') { event.preventdefault(); } const selector = getselectorfromelement(this); const selectorelements = selectorengine.find(selector); selectorelements.foreach(element => { collapse.getorcreateinstance(element, { toggle: false }).toggle(); }); }); /** * ------------------------------------------------------------------------ * jquery * ------------------------------------------------------------------------ * add .collapse to jquery only if jquery is present */ definejqueryplugin(collapse); /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): dropdown.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const name$9 = 'dropdown'; const data_key$8 = 'bs.dropdown'; const event_key$8 = `.${data_key$8}`; const data_api_key$4 = '.data-api'; const escape_key$2 = 'escape'; const space_key = 'space'; const tab_key$1 = 'tab'; const arrow_up_key = 'arrowup'; const arrow_down_key = 'arrowdown'; const right_mouse_button = 2; // mouseevent.button value for the secondary button, usually the right button const regexp_keydown = new regexp(`${arrow_up_key}|${arrow_down_key}|${escape_key$2}`); const event_hide$4 = `hide${event_key$8}`; const event_hidden$4 = `hidden${event_key$8}`; const event_show$4 = `show${event_key$8}`; const event_shown$4 = `shown${event_key$8}`; const event_click_data_api$3 = `click${event_key$8}${data_api_key$4}`; const event_keydown_data_api = `keydown${event_key$8}${data_api_key$4}`; const event_keyup_data_api = `keyup${event_key$8}${data_api_key$4}`; const class_name_show$6 = 'show'; const class_name_dropup = 'dropup'; const class_name_dropend = 'dropend'; const class_name_dropstart = 'dropstart'; const class_name_navbar = 'navbar'; const selector_data_toggle$3 = '[data-bs-toggle="dropdown"]'; const selector_menu = '.dropdown-menu'; const selector_navbar_nav = '.navbar-nav'; const selector_visible_items = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'; const placement_top = isrtl() ? 'top-end' : 'top-start'; const placement_topend = isrtl() ? 'top-start' : 'top-end'; const placement_bottom = isrtl() ? 'bottom-end' : 'bottom-start'; const placement_bottomend = isrtl() ? 'bottom-start' : 'bottom-end'; const placement_right = isrtl() ? 'left-start' : 'right-start'; const placement_left = isrtl() ? 'right-start' : 'left-start'; const default$8 = { offset: [0, 2], boundary: 'clippingparents', reference: 'toggle', display: 'dynamic', popperconfig: null, autoclose: true }; const defaulttype$8 = { offset: '(array|string|function)', boundary: '(string|element)', reference: '(string|element|object)', display: 'string', popperconfig: '(null|object|function)', autoclose: '(boolean|string)' }; /** * ------------------------------------------------------------------------ * class definition * ------------------------------------------------------------------------ */ class dropdown extends basecomponent { constructor(element, config) { super(element); this._popper = null; this._config = this._getconfig(config); this._menu = this._getmenuelement(); this._innavbar = this._detectnavbar(); } // getters static get default() { return default$8; } static get defaulttype() { return defaulttype$8; } static get name() { return name$9; } // public toggle() { return this._isshown() ? this.hide() : this.show(); } show() { if (isdisabled(this._element) || this._isshown(this._menu)) { return; } const relatedtarget = { relatedtarget: this._element }; const showevent = eventhandler.trigger(this._element, event_show$4, relatedtarget); if (showevent.defaultprevented) { return; } const parent = dropdown.getparentfromelement(this._element); // totally disable popper for dropdowns in navbar if (this._innavbar) { manipulator.setdataattribute(this._menu, 'popper', 'none'); } else { this._createpopper(parent); } // if this is a touch-enabled device we add extra // empty mouseover listeners to the body's immediate children; // only needed because of broken event delegation on ios // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html if ('ontouchstart' in document.documentelement && !parent.closest(selector_navbar_nav)) { [].concat(...document.body.children).foreach(elem => eventhandler.on(elem, 'mouseover', noop)); } this._element.focus(); this._element.setattribute('aria-expanded', true); this._menu.classlist.add(class_name_show$6); this._element.classlist.add(class_name_show$6); eventhandler.trigger(this._element, event_shown$4, relatedtarget); } hide() { if (isdisabled(this._element) || !this._isshown(this._menu)) { return; } const relatedtarget = { relatedtarget: this._element }; this._completehide(relatedtarget); } dispose() { if (this._popper) { this._popper.destroy(); } super.dispose(); } update() { this._innavbar = this._detectnavbar(); if (this._popper) { this._popper.update(); } } // private _completehide(relatedtarget) { const hideevent = eventhandler.trigger(this._element, event_hide$4, relatedtarget); if (hideevent.defaultprevented) { return; } // if this is a touch-enabled device we remove the extra // empty mouseover listeners we added for ios support if ('ontouchstart' in document.documentelement) { [].concat(...document.body.children).foreach(elem => eventhandler.off(elem, 'mouseover', noop)); } if (this._popper) { this._popper.destroy(); } this._menu.classlist.remove(class_name_show$6); this._element.classlist.remove(class_name_show$6); this._element.setattribute('aria-expanded', 'false'); manipulator.removedataattribute(this._menu, 'popper'); eventhandler.trigger(this._element, event_hidden$4, relatedtarget); } _getconfig(config) { config = { ...this.constructor.default, ...manipulator.getdataattributes(this._element), ...config }; typecheckconfig(name$9, config, this.constructor.defaulttype); if (typeof config.reference === 'object' && !iselement(config.reference) && typeof config.reference.getboundingclientrect !== 'function') { // popper virtual elements require a getboundingclientrect method throw new typeerror(`${name$9.touppercase()}: option "reference" provided type "object" without a required "getboundingclientrect" method.`); } return config; } _createpopper(parent) { if (typeof popper__namespace === 'undefined') { throw new typeerror('bootstrap\'s dropdowns require popper (https://popper.js.org)'); } let referenceelement = this._element; if (this._config.reference === 'parent') { referenceelement = parent; } else if (iselement(this._config.reference)) { referenceelement = getelement(this._config.reference); } else if (typeof this._config.reference === 'object') { referenceelement = this._config.reference; } const popperconfig = this._getpopperconfig(); const isdisplaystatic = popperconfig.modifiers.find(modifier => modifier.name === 'applystyles' && modifier.enabled === false); this._popper = popper__namespace.createpopper(referenceelement, this._menu, popperconfig); if (isdisplaystatic) { manipulator.setdataattribute(this._menu, 'popper', 'static'); } } _isshown(element = this._element) { return element.classlist.contains(class_name_show$6); } _getmenuelement() { return selectorengine.next(this._element, selector_menu)[0]; } _getplacement() { const parentdropdown = this._element.parentnode; if (parentdropdown.classlist.contains(class_name_dropend)) { return placement_right; } if (parentdropdown.classlist.contains(class_name_dropstart)) { return placement_left; } // we need to trim the value because custom properties can also include spaces const isend = getcomputedstyle(this._menu).getpropertyvalue('--bs-position').trim() === 'end'; if (parentdropdown.classlist.contains(class_name_dropup)) { return isend ? placement_topend : placement_top; } return isend ? placement_bottomend : placement_bottom; } _detectnavbar() { return this._element.closest(`.${class_name_navbar}`) !== null; } _getoffset() { const { offset } = this._config; if (typeof offset === 'string') { return offset.split(',').map(val => number.parseint(val, 10)); } if (typeof offset === 'function') { return popperdata => offset(popperdata, this._element); } return offset; } _getpopperconfig() { const defaultbspopperconfig = { placement: this._getplacement(), modifiers: [{ name: 'preventoverflow', options: { boundary: this._config.boundary } }, { name: 'offset', options: { offset: this._getoffset() } }] }; // disable popper if we have a static display if (this._config.display === 'static') { defaultbspopperconfig.modifiers = [{ name: 'applystyles', enabled: false }]; } return { ...defaultbspopperconfig, ...(typeof this._config.popperconfig === 'function' ? this._config.popperconfig(defaultbspopperconfig) : this._config.popperconfig) }; } _selectmenuitem({ key, target }) { const items = selectorengine.find(selector_visible_items, this._menu).filter(isvisible); if (!items.length) { return; } // if target isn't included in items (e.g. when expanding the dropdown) // allow cycling to get the last item in case key equals arrow_up_key getnextactiveelement(items, target, key === arrow_down_key, !items.includes(target)).focus(); } // static static jqueryinterface(config) { return this.each(function () { const data = dropdown.getorcreateinstance(this, config); if (typeof config !== 'string') { return; } if (typeof data[config] === 'undefined') { throw new typeerror(`no method named "${config}"`); } data[config](); }); } static clearmenus(event) { if (event && (event.button === right_mouse_button || event.type === 'keyup' && event.key !== tab_key$1)) { return; } const toggles = selectorengine.find(selector_data_toggle$3); for (let i = 0, len = toggles.length; i < len; i++) { const context = dropdown.getinstance(toggles[i]); if (!context || context._config.autoclose === false) { continue; } if (!context._isshown()) { continue; } const relatedtarget = { relatedtarget: context._element }; if (event) { const composedpath = event.composedpath(); const ismenutarget = composedpath.includes(context._menu); if (composedpath.includes(context._element) || context._config.autoclose === 'inside' && !ismenutarget || context._config.autoclose === 'outside' && ismenutarget) { continue; } // tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === tab_key$1 || /input|select|option|textarea|form/i.test(event.target.tagname))) { continue; } if (event.type === 'click') { relatedtarget.clickevent = event; } } context._completehide(relatedtarget); } } static getparentfromelement(element) { return getelementfromselector(element) || element.parentnode; } static dataapikeydownhandler(event) { // if not input/textarea: // - and not a key in regexp_keydown => not a dropdown command // if input/textarea: // - if space key => not a dropdown command // - if key is other than escape // - if key is not up or down => not a dropdown command // - if trigger inside the menu => not a dropdown command if (/input|textarea/i.test(event.target.tagname) ? event.key === space_key || event.key !== escape_key$2 && (event.key !== arrow_down_key && event.key !== arrow_up_key || event.target.closest(selector_menu)) : !regexp_keydown.test(event.key)) { return; } const isactive = this.classlist.contains(class_name_show$6); if (!isactive && event.key === escape_key$2) { return; } event.preventdefault(); event.stoppropagation(); if (isdisabled(this)) { return; } const gettogglebutton = this.matches(selector_data_toggle$3) ? this : selectorengine.prev(this, selector_data_toggle$3)[0]; const instance = dropdown.getorcreateinstance(gettogglebutton); if (event.key === escape_key$2) { instance.hide(); return; } if (event.key === arrow_up_key || event.key === arrow_down_key) { if (!isactive) { instance.show(); } instance._selectmenuitem(event); return; } if (!isactive || event.key === space_key) { dropdown.clearmenus(); } } } /** * ------------------------------------------------------------------------ * data api implementation * ------------------------------------------------------------------------ */ eventhandler.on(document, event_keydown_data_api, selector_data_toggle$3, dropdown.dataapikeydownhandler); eventhandler.on(document, event_keydown_data_api, selector_menu, dropdown.dataapikeydownhandler); eventhandler.on(document, event_click_data_api$3, dropdown.clearmenus); eventhandler.on(document, event_keyup_data_api, dropdown.clearmenus); eventhandler.on(document, event_click_data_api$3, selector_data_toggle$3, function (event) { event.preventdefault(); dropdown.getorcreateinstance(this).toggle(); }); /** * ------------------------------------------------------------------------ * jquery * ------------------------------------------------------------------------ * add .dropdown to jquery only if jquery is present */ definejqueryplugin(dropdown); /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): util/scrollbar.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ const selector_fixed_content = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'; const selector_sticky_content = '.sticky-top'; class scrollbarhelper { constructor() { this._element = document.body; } getwidth() { // https://developer.mozilla.org/en-us/docs/web/api/window/innerwidth#usage_notes const documentwidth = document.documentelement.clientwidth; return math.abs(window.innerwidth - documentwidth); } hide() { const width = this.getwidth(); this._disableoverflow(); // give padding to element to balance the hidden scrollbar width this._setelementattributes(this._element, 'paddingright', calculatedvalue => calculatedvalue + width); // trick: we adjust positive paddingright and negative marginright to sticky-top elements to keep showing fullwidth this._setelementattributes(selector_fixed_content, 'paddingright', calculatedvalue => calculatedvalue + width); this._setelementattributes(selector_sticky_content, 'marginright', calculatedvalue => calculatedvalue - width); } _disableoverflow() { this._saveinitialattribute(this._element, 'overflow'); this._element.style.overflow = 'hidden'; } _setelementattributes(selector, styleprop, callback) { const scrollbarwidth = this.getwidth(); const manipulationcallback = element => { if (element !== this._element && window.innerwidth > element.clientwidth + scrollbarwidth) { return; } this._saveinitialattribute(element, styleprop); const calculatedvalue = window.getcomputedstyle(element)[styleprop]; element.style[styleprop] = `${callback(number.parsefloat(calculatedvalue))}px`; }; this._applymanipulationcallback(selector, manipulationcallback); } reset() { this._resetelementattributes(this._element, 'overflow'); this._resetelementattributes(this._element, 'paddingright'); this._resetelementattributes(selector_fixed_content, 'paddingright'); this._resetelementattributes(selector_sticky_content, 'marginright'); } _saveinitialattribute(element, styleprop) { const actualvalue = element.style[styleprop]; if (actualvalue) { manipulator.setdataattribute(element, styleprop, actualvalue); } } _resetelementattributes(selector, styleprop) { const manipulationcallback = element => { const value = manipulator.getdataattribute(element, styleprop); if (typeof value === 'undefined') { element.style.removeproperty(styleprop); } else { manipulator.removedataattribute(element, styleprop); element.style[styleprop] = value; } }; this._applymanipulationcallback(selector, manipulationcallback); } _applymanipulationcallback(selector, callback) { if (iselement(selector)) { callback(selector); } else { selectorengine.find(selector, this._element).foreach(callback); } } isoverflowing() { return this.getwidth() > 0; } } /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): util/backdrop.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ const default$7 = { classname: 'modal-backdrop', isvisible: true, // if false, we use the backdrop helper without adding any element to the dom isanimated: false, rootelement: 'body', // give the choice to place backdrop under different elements clickcallback: null }; const defaulttype$7 = { classname: 'string', isvisible: 'boolean', isanimated: 'boolean', rootelement: '(element|string)', clickcallback: '(function|null)' }; const name$8 = 'backdrop'; const class_name_fade$4 = 'fade'; const class_name_show$5 = 'show'; const event_mousedown = `mousedown.bs.${name$8}`; class backdrop { constructor(config) { this._config = this._getconfig(config); this._isappended = false; this._element = null; } show(callback) { if (!this._config.isvisible) { execute(callback); return; } this._append(); if (this._config.isanimated) { reflow(this._getelement()); } this._getelement().classlist.add(class_name_show$5); this._emulateanimation(() => { execute(callback); }); } hide(callback) { if (!this._config.isvisible) { execute(callback); return; } this._getelement().classlist.remove(class_name_show$5); this._emulateanimation(() => { this.dispose(); execute(callback); }); } // private _getelement() { if (!this._element) { const backdrop = document.createelement('div'); backdrop.classname = this._config.classname; if (this._config.isanimated) { backdrop.classlist.add(class_name_fade$4); } this._element = backdrop; } return this._element; } _getconfig(config) { config = { ...default$7, ...(typeof config === 'object' ? config : {}) }; // use getelement() with the default "body" to get a fresh element on each instantiation config.rootelement = getelement(config.rootelement); typecheckconfig(name$8, config, defaulttype$7); return config; } _append() { if (this._isappended) { return; } this._config.rootelement.append(this._getelement()); eventhandler.on(this._getelement(), event_mousedown, () => { execute(this._config.clickcallback); }); this._isappended = true; } dispose() { if (!this._isappended) { return; } eventhandler.off(this._element, event_mousedown); this._element.remove(); this._isappended = false; } _emulateanimation(callback) { executeaftertransition(callback, this._getelement(), this._config.isanimated); } } /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): util/focustrap.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ const default$6 = { trapelement: null, // the element to trap focus inside of autofocus: true }; const defaulttype$6 = { trapelement: 'element', autofocus: 'boolean' }; const name$7 = 'focustrap'; const data_key$7 = 'bs.focustrap'; const event_key$7 = `.${data_key$7}`; const event_focusin$1 = `focusin${event_key$7}`; const event_keydown_tab = `keydown.tab${event_key$7}`; const tab_key = 'tab'; const tab_nav_forward = 'forward'; const tab_nav_backward = 'backward'; class focustrap { constructor(config) { this._config = this._getconfig(config); this._isactive = false; this._lasttabnavdirection = null; } activate() { const { trapelement, autofocus } = this._config; if (this._isactive) { return; } if (autofocus) { trapelement.focus(); } eventhandler.off(document, event_key$7); // guard against infinite focus loop eventhandler.on(document, event_focusin$1, event => this._handlefocusin(event)); eventhandler.on(document, event_keydown_tab, event => this._handlekeydown(event)); this._isactive = true; } deactivate() { if (!this._isactive) { return; } this._isactive = false; eventhandler.off(document, event_key$7); } // private _handlefocusin(event) { const { target } = event; const { trapelement } = this._config; if (target === document || target === trapelement || trapelement.contains(target)) { return; } const elements = selectorengine.focusablechildren(trapelement); if (elements.length === 0) { trapelement.focus(); } else if (this._lasttabnavdirection === tab_nav_backward) { elements[elements.length - 1].focus(); } else { elements[0].focus(); } } _handlekeydown(event) { if (event.key !== tab_key) { return; } this._lasttabnavdirection = event.shiftkey ? tab_nav_backward : tab_nav_forward; } _getconfig(config) { config = { ...default$6, ...(typeof config === 'object' ? config : {}) }; typecheckconfig(name$7, config, defaulttype$6); return config; } } /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): modal.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const name$6 = 'modal'; const data_key$6 = 'bs.modal'; const event_key$6 = `.${data_key$6}`; const data_api_key$3 = '.data-api'; const escape_key$1 = 'escape'; const default$5 = { backdrop: true, keyboard: true, focus: true }; const defaulttype$5 = { backdrop: '(boolean|string)', keyboard: 'boolean', focus: 'boolean' }; const event_hide$3 = `hide${event_key$6}`; const event_hide_prevented = `hideprevented${event_key$6}`; const event_hidden$3 = `hidden${event_key$6}`; const event_show$3 = `show${event_key$6}`; const event_shown$3 = `shown${event_key$6}`; const event_resize = `resize${event_key$6}`; const event_click_dismiss = `click.dismiss${event_key$6}`; const event_keydown_dismiss$1 = `keydown.dismiss${event_key$6}`; const event_mouseup_dismiss = `mouseup.dismiss${event_key$6}`; const event_mousedown_dismiss = `mousedown.dismiss${event_key$6}`; const event_click_data_api$2 = `click${event_key$6}${data_api_key$3}`; const class_name_open = 'modal-open'; const class_name_fade$3 = 'fade'; const class_name_show$4 = 'show'; const class_name_static = 'modal-static'; const open_selector$1 = '.modal.show'; const selector_dialog = '.modal-dialog'; const selector_modal_body = '.modal-body'; const selector_data_toggle$2 = '[data-bs-toggle="modal"]'; /** * ------------------------------------------------------------------------ * class definition * ------------------------------------------------------------------------ */ class modal extends basecomponent { constructor(element, config) { super(element); this._config = this._getconfig(config); this._dialog = selectorengine.findone(selector_dialog, this._element); this._backdrop = this._initializebackdrop(); this._focustrap = this._initializefocustrap(); this._isshown = false; this._ignorebackdropclick = false; this._istransitioning = false; this._scrollbar = new scrollbarhelper(); } // getters static get default() { return default$5; } static get name() { return name$6; } // public toggle(relatedtarget) { return this._isshown ? this.hide() : this.show(relatedtarget); } show(relatedtarget) { if (this._isshown || this._istransitioning) { return; } const showevent = eventhandler.trigger(this._element, event_show$3, { relatedtarget }); if (showevent.defaultprevented) { return; } this._isshown = true; if (this._isanimated()) { this._istransitioning = true; } this._scrollbar.hide(); document.body.classlist.add(class_name_open); this._adjustdialog(); this._setescapeevent(); this._setresizeevent(); eventhandler.on(this._dialog, event_mousedown_dismiss, () => { eventhandler.one(this._element, event_mouseup_dismiss, event => { if (event.target === this._element) { this._ignorebackdropclick = true; } }); }); this._showbackdrop(() => this._showelement(relatedtarget)); } hide() { if (!this._isshown || this._istransitioning) { return; } const hideevent = eventhandler.trigger(this._element, event_hide$3); if (hideevent.defaultprevented) { return; } this._isshown = false; const isanimated = this._isanimated(); if (isanimated) { this._istransitioning = true; } this._setescapeevent(); this._setresizeevent(); this._focustrap.deactivate(); this._element.classlist.remove(class_name_show$4); eventhandler.off(this._element, event_click_dismiss); eventhandler.off(this._dialog, event_mousedown_dismiss); this._queuecallback(() => this._hidemodal(), this._element, isanimated); } dispose() { [window, this._dialog].foreach(htmlelement => eventhandler.off(htmlelement, event_key$6)); this._backdrop.dispose(); this._focustrap.deactivate(); super.dispose(); } handleupdate() { this._adjustdialog(); } // private _initializebackdrop() { return new backdrop({ isvisible: boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value isanimated: this._isanimated() }); } _initializefocustrap() { return new focustrap({ trapelement: this._element }); } _getconfig(config) { config = { ...default$5, ...manipulator.getdataattributes(this._element), ...(typeof config === 'object' ? config : {}) }; typecheckconfig(name$6, config, defaulttype$5); return config; } _showelement(relatedtarget) { const isanimated = this._isanimated(); const modalbody = selectorengine.findone(selector_modal_body, this._dialog); if (!this._element.parentnode || this._element.parentnode.nodetype !== node.element_node) { // don't move modal's dom position document.body.append(this._element); } this._element.style.display = 'block'; this._element.removeattribute('aria-hidden'); this._element.setattribute('aria-modal', true); this._element.setattribute('role', 'dialog'); this._element.scrolltop = 0; if (modalbody) { modalbody.scrolltop = 0; } if (isanimated) { reflow(this._element); } this._element.classlist.add(class_name_show$4); const transitioncomplete = () => { if (this._config.focus) { this._focustrap.activate(); } this._istransitioning = false; eventhandler.trigger(this._element, event_shown$3, { relatedtarget }); }; this._queuecallback(transitioncomplete, this._dialog, isanimated); } _setescapeevent() { if (this._isshown) { eventhandler.on(this._element, event_keydown_dismiss$1, event => { if (this._config.keyboard && event.key === escape_key$1) { event.preventdefault(); this.hide(); } else if (!this._config.keyboard && event.key === escape_key$1) { this._triggerbackdroptransition(); } }); } else { eventhandler.off(this._element, event_keydown_dismiss$1); } } _setresizeevent() { if (this._isshown) { eventhandler.on(window, event_resize, () => this._adjustdialog()); } else { eventhandler.off(window, event_resize); } } _hidemodal() { this._element.style.display = 'none'; this._element.setattribute('aria-hidden', true); this._element.removeattribute('aria-modal'); this._element.removeattribute('role'); this._istransitioning = false; this._backdrop.hide(() => { document.body.classlist.remove(class_name_open); this._resetadjustments(); this._scrollbar.reset(); eventhandler.trigger(this._element, event_hidden$3); }); } _showbackdrop(callback) { eventhandler.on(this._element, event_click_dismiss, event => { if (this._ignorebackdropclick) { this._ignorebackdropclick = false; return; } if (event.target !== event.currenttarget) { return; } if (this._config.backdrop === true) { this.hide(); } else if (this._config.backdrop === 'static') { this._triggerbackdroptransition(); } }); this._backdrop.show(callback); } _isanimated() { return this._element.classlist.contains(class_name_fade$3); } _triggerbackdroptransition() { const hideevent = eventhandler.trigger(this._element, event_hide_prevented); if (hideevent.defaultprevented) { return; } const { classlist, scrollheight, style } = this._element; const ismodaloverflowing = scrollheight > document.documentelement.clientheight; // return if the following background transition hasn't yet completed if (!ismodaloverflowing && style.overflowy === 'hidden' || classlist.contains(class_name_static)) { return; } if (!ismodaloverflowing) { style.overflowy = 'hidden'; } classlist.add(class_name_static); this._queuecallback(() => { classlist.remove(class_name_static); if (!ismodaloverflowing) { this._queuecallback(() => { style.overflowy = ''; }, this._dialog); } }, this._dialog); this._element.focus(); } // ---------------------------------------------------------------------- // the following methods are used to handle overflowing modals // ---------------------------------------------------------------------- _adjustdialog() { const ismodaloverflowing = this._element.scrollheight > document.documentelement.clientheight; const scrollbarwidth = this._scrollbar.getwidth(); const isbodyoverflowing = scrollbarwidth > 0; if (!isbodyoverflowing && ismodaloverflowing && !isrtl() || isbodyoverflowing && !ismodaloverflowing && isrtl()) { this._element.style.paddingleft = `${scrollbarwidth}px`; } if (isbodyoverflowing && !ismodaloverflowing && !isrtl() || !isbodyoverflowing && ismodaloverflowing && isrtl()) { this._element.style.paddingright = `${scrollbarwidth}px`; } } _resetadjustments() { this._element.style.paddingleft = ''; this._element.style.paddingright = ''; } // static static jqueryinterface(config, relatedtarget) { return this.each(function () { const data = modal.getorcreateinstance(this, config); if (typeof config !== 'string') { return; } if (typeof data[config] === 'undefined') { throw new typeerror(`no method named "${config}"`); } data[config](relatedtarget); }); } } /** * ------------------------------------------------------------------------ * data api implementation * ------------------------------------------------------------------------ */ eventhandler.on(document, event_click_data_api$2, selector_data_toggle$2, function (event) { const target = getelementfromselector(this); if (['a', 'area'].includes(this.tagname)) { event.preventdefault(); } eventhandler.one(target, event_show$3, showevent => { if (showevent.defaultprevented) { // only register focus restorer if modal will actually get shown return; } eventhandler.one(target, event_hidden$3, () => { if (isvisible(this)) { this.focus(); } }); }); // avoid conflict when clicking moddal toggler while another one is open const allreadyopen = selectorengine.findone(open_selector$1); if (allreadyopen) { modal.getinstance(allreadyopen).hide(); } const data = modal.getorcreateinstance(target); data.toggle(this); }); enabledismisstrigger(modal); /** * ------------------------------------------------------------------------ * jquery * ------------------------------------------------------------------------ * add .modal to jquery only if jquery is present */ definejqueryplugin(modal); /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): offcanvas.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const name$5 = 'offcanvas'; const data_key$5 = 'bs.offcanvas'; const event_key$5 = `.${data_key$5}`; const data_api_key$2 = '.data-api'; const event_load_data_api$1 = `load${event_key$5}${data_api_key$2}`; const escape_key = 'escape'; const default$4 = { backdrop: true, keyboard: true, scroll: false }; const defaulttype$4 = { backdrop: 'boolean', keyboard: 'boolean', scroll: 'boolean' }; const class_name_show$3 = 'show'; const class_name_backdrop = 'offcanvas-backdrop'; const open_selector = '.offcanvas.show'; const event_show$2 = `show${event_key$5}`; const event_shown$2 = `shown${event_key$5}`; const event_hide$2 = `hide${event_key$5}`; const event_hidden$2 = `hidden${event_key$5}`; const event_click_data_api$1 = `click${event_key$5}${data_api_key$2}`; const event_keydown_dismiss = `keydown.dismiss${event_key$5}`; const selector_data_toggle$1 = '[data-bs-toggle="offcanvas"]'; /** * ------------------------------------------------------------------------ * class definition * ------------------------------------------------------------------------ */ class offcanvas extends basecomponent { constructor(element, config) { super(element); this._config = this._getconfig(config); this._isshown = false; this._backdrop = this._initializebackdrop(); this._focustrap = this._initializefocustrap(); this._addeventlisteners(); } // getters static get name() { return name$5; } static get default() { return default$4; } // public toggle(relatedtarget) { return this._isshown ? this.hide() : this.show(relatedtarget); } show(relatedtarget) { if (this._isshown) { return; } const showevent = eventhandler.trigger(this._element, event_show$2, { relatedtarget }); if (showevent.defaultprevented) { return; } this._isshown = true; this._element.style.visibility = 'visible'; this._backdrop.show(); if (!this._config.scroll) { new scrollbarhelper().hide(); } this._element.removeattribute('aria-hidden'); this._element.setattribute('aria-modal', true); this._element.setattribute('role', 'dialog'); this._element.classlist.add(class_name_show$3); const completecallback = () => { if (!this._config.scroll) { this._focustrap.activate(); } eventhandler.trigger(this._element, event_shown$2, { relatedtarget }); }; this._queuecallback(completecallback, this._element, true); } hide() { if (!this._isshown) { return; } const hideevent = eventhandler.trigger(this._element, event_hide$2); if (hideevent.defaultprevented) { return; } this._focustrap.deactivate(); this._element.blur(); this._isshown = false; this._element.classlist.remove(class_name_show$3); this._backdrop.hide(); const completecallback = () => { this._element.setattribute('aria-hidden', true); this._element.removeattribute('aria-modal'); this._element.removeattribute('role'); this._element.style.visibility = 'hidden'; if (!this._config.scroll) { new scrollbarhelper().reset(); } eventhandler.trigger(this._element, event_hidden$2); }; this._queuecallback(completecallback, this._element, true); } dispose() { this._backdrop.dispose(); this._focustrap.deactivate(); super.dispose(); } // private _getconfig(config) { config = { ...default$4, ...manipulator.getdataattributes(this._element), ...(typeof config === 'object' ? config : {}) }; typecheckconfig(name$5, config, defaulttype$4); return config; } _initializebackdrop() { return new backdrop({ classname: class_name_backdrop, isvisible: this._config.backdrop, isanimated: true, rootelement: this._element.parentnode, clickcallback: () => this.hide() }); } _initializefocustrap() { return new focustrap({ trapelement: this._element }); } _addeventlisteners() { eventhandler.on(this._element, event_keydown_dismiss, event => { if (this._config.keyboard && event.key === escape_key) { this.hide(); } }); } // static static jqueryinterface(config) { return this.each(function () { const data = offcanvas.getorcreateinstance(this, config); if (typeof config !== 'string') { return; } if (data[config] === undefined || config.startswith('_') || config === 'constructor') { throw new typeerror(`no method named "${config}"`); } data[config](this); }); } } /** * ------------------------------------------------------------------------ * data api implementation * ------------------------------------------------------------------------ */ eventhandler.on(document, event_click_data_api$1, selector_data_toggle$1, function (event) { const target = getelementfromselector(this); if (['a', 'area'].includes(this.tagname)) { event.preventdefault(); } if (isdisabled(this)) { return; } eventhandler.one(target, event_hidden$2, () => { // focus on trigger when it is closed if (isvisible(this)) { this.focus(); } }); // avoid conflict when clicking a toggler of an offcanvas, while another is open const allreadyopen = selectorengine.findone(open_selector); if (allreadyopen && allreadyopen !== target) { offcanvas.getinstance(allreadyopen).hide(); } const data = offcanvas.getorcreateinstance(target); data.toggle(this); }); eventhandler.on(window, event_load_data_api$1, () => selectorengine.find(open_selector).foreach(el => offcanvas.getorcreateinstance(el).show())); enabledismisstrigger(offcanvas); /** * ------------------------------------------------------------------------ * jquery * ------------------------------------------------------------------------ */ definejqueryplugin(offcanvas); /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): util/sanitizer.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ const uriattributes = new set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']); const aria_attribute_pattern = /^aria-[\w-]*$/i; /** * a pattern that recognizes a commonly useful subset of urls that are safe. * * shoutout to angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts */ const safe_url_pattern = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i; /** * a pattern that matches safe data urls. only matches image, video and audio types. * * shoutout to angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts */ const data_url_pattern = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i; const allowedattribute = (attribute, allowedattributelist) => { const attributename = attribute.nodename.tolowercase(); if (allowedattributelist.includes(attributename)) { if (uriattributes.has(attributename)) { return boolean(safe_url_pattern.test(attribute.nodevalue) || data_url_pattern.test(attribute.nodevalue)); } return true; } const regexp = allowedattributelist.filter(attributeregex => attributeregex instanceof regexp); // check if a regular expression validates the attribute. for (let i = 0, len = regexp.length; i < len; i++) { if (regexp[i].test(attributename)) { return true; } } return false; }; const defaultallowlist = { // global attributes allowed on any supplied element below. '*': ['class', 'dir', 'id', 'lang', 'role', aria_attribute_pattern], a: ['target', 'href', 'title', 'rel'], area: [], b: [], br: [], col: [], code: [], div: [], em: [], hr: [], h1: [], h2: [], h3: [], h4: [], h5: [], h6: [], i: [], img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], li: [], ol: [], p: [], pre: [], s: [], small: [], span: [], sub: [], sup: [], strong: [], u: [], ul: [] }; function sanitizehtml(unsafehtml, allowlist, sanitizefn) { if (!unsafehtml.length) { return unsafehtml; } if (sanitizefn && typeof sanitizefn === 'function') { return sanitizefn(unsafehtml); } const domparser = new window.domparser(); const createddocument = domparser.parsefromstring(unsafehtml, 'text/html'); const elements = [].concat(...createddocument.body.queryselectorall('*')); for (let i = 0, len = elements.length; i < len; i++) { const element = elements[i]; const elementname = element.nodename.tolowercase(); if (!object.keys(allowlist).includes(elementname)) { element.remove(); continue; } const attributelist = [].concat(...element.attributes); const allowedattributes = [].concat(allowlist['*'] || [], allowlist[elementname] || []); attributelist.foreach(attribute => { if (!allowedattribute(attribute, allowedattributes)) { element.removeattribute(attribute.nodename); } }); } return createddocument.body.innerhtml; } /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): tooltip.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const name$4 = 'tooltip'; const data_key$4 = 'bs.tooltip'; const event_key$4 = `.${data_key$4}`; const class_prefix$1 = 'bs-tooltip'; const disallowed_attributes = new set(['sanitize', 'allowlist', 'sanitizefn']); const defaulttype$3 = { animation: 'boolean', template: 'string', title: '(string|element|function)', trigger: 'string', delay: '(number|object)', html: 'boolean', selector: '(string|boolean)', placement: '(string|function)', offset: '(array|string|function)', container: '(string|element|boolean)', fallbackplacements: 'array', boundary: '(string|element)', customclass: '(string|function)', sanitize: 'boolean', sanitizefn: '(null|function)', allowlist: 'object', popperconfig: '(null|object|function)' }; const attachmentmap = { auto: 'auto', top: 'top', right: isrtl() ? 'left' : 'right', bottom: 'bottom', left: isrtl() ? 'right' : 'left' }; const default$3 = { animation: true, template: '', trigger: 'hover focus', title: '', delay: 0, html: false, selector: false, placement: 'top', offset: [0, 0], container: false, fallbackplacements: ['top', 'right', 'bottom', 'left'], boundary: 'clippingparents', customclass: '', sanitize: true, sanitizefn: null, allowlist: defaultallowlist, popperconfig: null }; const event$2 = { hide: `hide${event_key$4}`, hidden: `hidden${event_key$4}`, show: `show${event_key$4}`, shown: `shown${event_key$4}`, inserted: `inserted${event_key$4}`, click: `click${event_key$4}`, focusin: `focusin${event_key$4}`, focusout: `focusout${event_key$4}`, mouseenter: `mouseenter${event_key$4}`, mouseleave: `mouseleave${event_key$4}` }; const class_name_fade$2 = 'fade'; const class_name_modal = 'modal'; const class_name_show$2 = 'show'; const hover_state_show = 'show'; const hover_state_out = 'out'; const selector_tooltip_inner = '.tooltip-inner'; const selector_modal = `.${class_name_modal}`; const event_modal_hide = 'hide.bs.modal'; const trigger_hover = 'hover'; const trigger_focus = 'focus'; const trigger_click = 'click'; const trigger_manual = 'manual'; /** * ------------------------------------------------------------------------ * class definition * ------------------------------------------------------------------------ */ class tooltip extends basecomponent { constructor(element, config) { if (typeof popper__namespace === 'undefined') { throw new typeerror('bootstrap\'s tooltips require popper (https://popper.js.org)'); } super(element); // private this._isenabled = true; this._timeout = 0; this._hoverstate = ''; this._activetrigger = {}; this._popper = null; // protected this._config = this._getconfig(config); this.tip = null; this._setlisteners(); } // getters static get default() { return default$3; } static get name() { return name$4; } static get event() { return event$2; } static get defaulttype() { return defaulttype$3; } // public enable() { this._isenabled = true; } disable() { this._isenabled = false; } toggleenabled() { this._isenabled = !this._isenabled; } toggle(event) { if (!this._isenabled) { return; } if (event) { const context = this._initializeondelegatedtarget(event); context._activetrigger.click = !context._activetrigger.click; if (context._iswithactivetrigger()) { context._enter(null, context); } else { context._leave(null, context); } } else { if (this.gettipelement().classlist.contains(class_name_show$2)) { this._leave(null, this); return; } this._enter(null, this); } } dispose() { cleartimeout(this._timeout); eventhandler.off(this._element.closest(selector_modal), event_modal_hide, this._hidemodalhandler); if (this.tip) { this.tip.remove(); } this._disposepopper(); super.dispose(); } show() { if (this._element.style.display === 'none') { throw new error('please use show on visible elements'); } if (!(this.iswithcontent() && this._isenabled)) { return; } const showevent = eventhandler.trigger(this._element, this.constructor.event.show); const shadowroot = findshadowroot(this._element); const isinthedom = shadowroot === null ? this._element.ownerdocument.documentelement.contains(this._element) : shadowroot.contains(this._element); if (showevent.defaultprevented || !isinthedom) { return; } // a trick to recreate a tooltip in case a new title is given by using the not documented `data-bs-original-title` // this will be removed later in favor of a `setcontent` method if (this.constructor.name === 'tooltip' && this.tip && this.gettitle() !== this.tip.queryselector(selector_tooltip_inner).innerhtml) { this._disposepopper(); this.tip.remove(); this.tip = null; } const tip = this.gettipelement(); const tipid = getuid(this.constructor.name); tip.setattribute('id', tipid); this._element.setattribute('aria-describedby', tipid); if (this._config.animation) { tip.classlist.add(class_name_fade$2); } const placement = typeof this._config.placement === 'function' ? this._config.placement.call(this, tip, this._element) : this._config.placement; const attachment = this._getattachment(placement); this._addattachmentclass(attachment); const { container } = this._config; data.set(tip, this.constructor.data_key, this); if (!this._element.ownerdocument.documentelement.contains(this.tip)) { container.append(tip); eventhandler.trigger(this._element, this.constructor.event.inserted); } if (this._popper) { this._popper.update(); } else { this._popper = popper__namespace.createpopper(this._element, tip, this._getpopperconfig(attachment)); } tip.classlist.add(class_name_show$2); const customclass = this._resolvepossiblefunction(this._config.customclass); if (customclass) { tip.classlist.add(...customclass.split(' ')); } // if this is a touch-enabled device we add extra // empty mouseover listeners to the body's immediate children; // only needed because of broken event delegation on ios // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html if ('ontouchstart' in document.documentelement) { [].concat(...document.body.children).foreach(element => { eventhandler.on(element, 'mouseover', noop); }); } const complete = () => { const prevhoverstate = this._hoverstate; this._hoverstate = null; eventhandler.trigger(this._element, this.constructor.event.shown); if (prevhoverstate === hover_state_out) { this._leave(null, this); } }; const isanimated = this.tip.classlist.contains(class_name_fade$2); this._queuecallback(complete, this.tip, isanimated); } hide() { if (!this._popper) { return; } const tip = this.gettipelement(); const complete = () => { if (this._iswithactivetrigger()) { return; } if (this._hoverstate !== hover_state_show) { tip.remove(); } this._cleantipclass(); this._element.removeattribute('aria-describedby'); eventhandler.trigger(this._element, this.constructor.event.hidden); this._disposepopper(); }; const hideevent = eventhandler.trigger(this._element, this.constructor.event.hide); if (hideevent.defaultprevented) { return; } tip.classlist.remove(class_name_show$2); // if this is a touch-enabled device we remove the extra // empty mouseover listeners we added for ios support if ('ontouchstart' in document.documentelement) { [].concat(...document.body.children).foreach(element => eventhandler.off(element, 'mouseover', noop)); } this._activetrigger[trigger_click] = false; this._activetrigger[trigger_focus] = false; this._activetrigger[trigger_hover] = false; const isanimated = this.tip.classlist.contains(class_name_fade$2); this._queuecallback(complete, this.tip, isanimated); this._hoverstate = ''; } update() { if (this._popper !== null) { this._popper.update(); } } // protected iswithcontent() { return boolean(this.gettitle()); } gettipelement() { if (this.tip) { return this.tip; } const element = document.createelement('div'); element.innerhtml = this._config.template; const tip = element.children[0]; this.setcontent(tip); tip.classlist.remove(class_name_fade$2, class_name_show$2); this.tip = tip; return this.tip; } setcontent(tip) { this._sanitizeandsetcontent(tip, this.gettitle(), selector_tooltip_inner); } _sanitizeandsetcontent(template, content, selector) { const templateelement = selectorengine.findone(selector, template); if (!content && templateelement) { templateelement.remove(); return; } // we use append for html objects to maintain js events this.setelementcontent(templateelement, content); } setelementcontent(element, content) { if (element === null) { return; } if (iselement(content)) { content = getelement(content); // content is a dom node or a jquery if (this._config.html) { if (content.parentnode !== element) { element.innerhtml = ''; element.append(content); } } else { element.textcontent = content.textcontent; } return; } if (this._config.html) { if (this._config.sanitize) { content = sanitizehtml(content, this._config.allowlist, this._config.sanitizefn); } element.innerhtml = content; } else { element.textcontent = content; } } gettitle() { const title = this._element.getattribute('data-bs-original-title') || this._config.title; return this._resolvepossiblefunction(title); } updateattachment(attachment) { if (attachment === 'right') { return 'end'; } if (attachment === 'left') { return 'start'; } return attachment; } // private _initializeondelegatedtarget(event, context) { return context || this.constructor.getorcreateinstance(event.delegatetarget, this._getdelegateconfig()); } _getoffset() { const { offset } = this._config; if (typeof offset === 'string') { return offset.split(',').map(val => number.parseint(val, 10)); } if (typeof offset === 'function') { return popperdata => offset(popperdata, this._element); } return offset; } _resolvepossiblefunction(content) { return typeof content === 'function' ? content.call(this._element) : content; } _getpopperconfig(attachment) { const defaultbspopperconfig = { placement: attachment, modifiers: [{ name: 'flip', options: { fallbackplacements: this._config.fallbackplacements } }, { name: 'offset', options: { offset: this._getoffset() } }, { name: 'preventoverflow', options: { boundary: this._config.boundary } }, { name: 'arrow', options: { element: `.${this.constructor.name}-arrow` } }, { name: 'onchange', enabled: true, phase: 'afterwrite', fn: data => this._handlepopperplacementchange(data) }], onfirstupdate: data => { if (data.options.placement !== data.placement) { this._handlepopperplacementchange(data); } } }; return { ...defaultbspopperconfig, ...(typeof this._config.popperconfig === 'function' ? this._config.popperconfig(defaultbspopperconfig) : this._config.popperconfig) }; } _addattachmentclass(attachment) { this.gettipelement().classlist.add(`${this._getbasicclassprefix()}-${this.updateattachment(attachment)}`); } _getattachment(placement) { return attachmentmap[placement.touppercase()]; } _setlisteners() { const triggers = this._config.trigger.split(' '); triggers.foreach(trigger => { if (trigger === 'click') { eventhandler.on(this._element, this.constructor.event.click, this._config.selector, event => this.toggle(event)); } else if (trigger !== trigger_manual) { const eventin = trigger === trigger_hover ? this.constructor.event.mouseenter : this.constructor.event.focusin; const eventout = trigger === trigger_hover ? this.constructor.event.mouseleave : this.constructor.event.focusout; eventhandler.on(this._element, eventin, this._config.selector, event => this._enter(event)); eventhandler.on(this._element, eventout, this._config.selector, event => this._leave(event)); } }); this._hidemodalhandler = () => { if (this._element) { this.hide(); } }; eventhandler.on(this._element.closest(selector_modal), event_modal_hide, this._hidemodalhandler); if (this._config.selector) { this._config = { ...this._config, trigger: 'manual', selector: '' }; } else { this._fixtitle(); } } _fixtitle() { const title = this._element.getattribute('title'); const originaltitletype = typeof this._element.getattribute('data-bs-original-title'); if (title || originaltitletype !== 'string') { this._element.setattribute('data-bs-original-title', title || ''); if (title && !this._element.getattribute('aria-label') && !this._element.textcontent) { this._element.setattribute('aria-label', title); } this._element.setattribute('title', ''); } } _enter(event, context) { context = this._initializeondelegatedtarget(event, context); if (event) { context._activetrigger[event.type === 'focusin' ? trigger_focus : trigger_hover] = true; } if (context.gettipelement().classlist.contains(class_name_show$2) || context._hoverstate === hover_state_show) { context._hoverstate = hover_state_show; return; } cleartimeout(context._timeout); context._hoverstate = hover_state_show; if (!context._config.delay || !context._config.delay.show) { context.show(); return; } context._timeout = settimeout(() => { if (context._hoverstate === hover_state_show) { context.show(); } }, context._config.delay.show); } _leave(event, context) { context = this._initializeondelegatedtarget(event, context); if (event) { context._activetrigger[event.type === 'focusout' ? trigger_focus : trigger_hover] = context._element.contains(event.relatedtarget); } if (context._iswithactivetrigger()) { return; } cleartimeout(context._timeout); context._hoverstate = hover_state_out; if (!context._config.delay || !context._config.delay.hide) { context.hide(); return; } context._timeout = settimeout(() => { if (context._hoverstate === hover_state_out) { context.hide(); } }, context._config.delay.hide); } _iswithactivetrigger() { for (const trigger in this._activetrigger) { if (this._activetrigger[trigger]) { return true; } } return false; } _getconfig(config) { const dataattributes = manipulator.getdataattributes(this._element); object.keys(dataattributes).foreach(dataattr => { if (disallowed_attributes.has(dataattr)) { delete dataattributes[dataattr]; } }); config = { ...this.constructor.default, ...dataattributes, ...(typeof config === 'object' && config ? config : {}) }; config.container = config.container === false ? document.body : getelement(config.container); if (typeof config.delay === 'number') { config.delay = { show: config.delay, hide: config.delay }; } if (typeof config.title === 'number') { config.title = config.title.tostring(); } if (typeof config.content === 'number') { config.content = config.content.tostring(); } typecheckconfig(name$4, config, this.constructor.defaulttype); if (config.sanitize) { config.template = sanitizehtml(config.template, config.allowlist, config.sanitizefn); } return config; } _getdelegateconfig() { const config = {}; for (const key in this._config) { if (this.constructor.default[key] !== this._config[key]) { config[key] = this._config[key]; } } // in the future can be replaced with: // const keyswithdifferentvalues = object.entries(this._config).filter(entry => this.constructor.default[entry[0]] !== this._config[entry[0]]) // `object.fromentries(keyswithdifferentvalues)` return config; } _cleantipclass() { const tip = this.gettipelement(); const basicclassprefixregex = new regexp(`(^|\\s)${this._getbasicclassprefix()}\\s+`, 'g'); const tabclass = tip.getattribute('class').match(basicclassprefixregex); if (tabclass !== null && tabclass.length > 0) { tabclass.map(token => token.trim()).foreach(tclass => tip.classlist.remove(tclass)); } } _getbasicclassprefix() { return class_prefix$1; } _handlepopperplacementchange(popperdata) { const { state } = popperdata; if (!state) { return; } this.tip = state.elements.popper; this._cleantipclass(); this._addattachmentclass(this._getattachment(state.placement)); } _disposepopper() { if (this._popper) { this._popper.destroy(); this._popper = null; } } // static static jqueryinterface(config) { return this.each(function () { const data = tooltip.getorcreateinstance(this, config); if (typeof config === 'string') { if (typeof data[config] === 'undefined') { throw new typeerror(`no method named "${config}"`); } data[config](); } }); } } /** * ------------------------------------------------------------------------ * jquery * ------------------------------------------------------------------------ * add .tooltip to jquery only if jquery is present */ definejqueryplugin(tooltip); /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): popover.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const name$3 = 'popover'; const data_key$3 = 'bs.popover'; const event_key$3 = `.${data_key$3}`; const class_prefix = 'bs-popover'; const default$2 = { ...tooltip.default, placement: 'right', offset: [0, 8], trigger: 'click', content: '', template: '' }; const defaulttype$2 = { ...tooltip.defaulttype, content: '(string|element|function)' }; const event$1 = { hide: `hide${event_key$3}`, hidden: `hidden${event_key$3}`, show: `show${event_key$3}`, shown: `shown${event_key$3}`, inserted: `inserted${event_key$3}`, click: `click${event_key$3}`, focusin: `focusin${event_key$3}`, focusout: `focusout${event_key$3}`, mouseenter: `mouseenter${event_key$3}`, mouseleave: `mouseleave${event_key$3}` }; const selector_title = '.popover-header'; const selector_content = '.popover-body'; /** * ------------------------------------------------------------------------ * class definition * ------------------------------------------------------------------------ */ class popover extends tooltip { // getters static get default() { return default$2; } static get name() { return name$3; } static get event() { return event$1; } static get defaulttype() { return defaulttype$2; } // overrides iswithcontent() { return this.gettitle() || this._getcontent(); } setcontent(tip) { this._sanitizeandsetcontent(tip, this.gettitle(), selector_title); this._sanitizeandsetcontent(tip, this._getcontent(), selector_content); } // private _getcontent() { return this._resolvepossiblefunction(this._config.content); } _getbasicclassprefix() { return class_prefix; } // static static jqueryinterface(config) { return this.each(function () { const data = popover.getorcreateinstance(this, config); if (typeof config === 'string') { if (typeof data[config] === 'undefined') { throw new typeerror(`no method named "${config}"`); } data[config](); } }); } } /** * ------------------------------------------------------------------------ * jquery * ------------------------------------------------------------------------ * add .popover to jquery only if jquery is present */ definejqueryplugin(popover); /** * -------------------------------------------------------------------------- * bootstrap (v5.1.3): scrollspy.js * licensed under mit (https://github.com/twbs/bootstrap/blob/main/license) * -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * constants * ------------------------------------------------------------------------ */ const name$2 = 'scrollspy'; const data_key$2 = 'bs.scrollspy'; const event_key$2 = `.${data_key$2}`; const data_api_key$1 = '.data-api'; const default$1 = { offset: 10, method: 'auto', target: '' }; const defaulttype$1 = { offset: 'number', method: 'string', target: '(string|element)' }; const event_activate = `activate${event_key$2}`; const event_scroll = `scroll${event_key$2}`; const event_load_data_api = `load${event_key$2}${data_api_key$1}`; const class_name_dropdown_item = 'dropdown-item'; const class_name_active$1 = 'active'; const selector_data_spy = '[data-bs-spy="scroll"]'; const selector_nav_list_group$1 = '.nav, .list-group'; const selector_nav_links = '.nav-link'; const selector_nav_items = '.nav-item'; const selector_list_items = '.list-group-item'; const selector_link_items = `${selector_nav_links}, ${selector_list_items}, .${class_name_dropdown_item}`; const selector_dropdown$1 = '.dropdown'; const selector_dropdown_toggle$1 = '.dropdown-toggle'; const method_offset = 'offset'; const method_position = 'position'; /** * ------------------------------------------------------------------------ * class definition * ------------------------------------------------------------------------ */ class scrollspy extends basecomponent { constructor(element, config) { super(element); this._scrollelement = this._element.tagname === 'body' ? window : this._element; this._config = this._getconfig(config); this._offsets = []; this._targets = []; this._activetarget = null; this._scrollheight = 0; eventhandler.on(this._scrollelement, event_scroll, () => this._process()); this.refresh(); this._process(); } // getters static get default() { return default$1; } static get name() { return name$2; } // public refresh() { const automethod = this._scrollelement === this._scrollelement.window ? method_offset : method_position; const offsetmethod = this._config.method === 'auto' ? automethod : this._config.method; const offsetbase = offsetmethod === method_position ? this._getscrolltop() : 0; this._offsets = []; this._targets = []; this._scrollheight = this._getscrollheight(); const targets = selectorengine.find(selector_link_items, this._config.target); targets.map(element => { const targetselector = getselectorfromelement(element); const target = targetselector ? selectorengine.findone(targetselector) : null; if (target) { const targetbcr = target.getboundingclientrect(); if (targetbcr.width || targetbcr.height) { return [manipulator[offsetmethod](target).top + offsetbase, targetselector]; } } return null; }).filter(item => item).sort((a, b) => a[0] - b[0]).foreach(item => { this._offsets.push(item[0]); this._targets.push(item[1]); }); } dispose() { eventhandler.off(this._scrollelement, event_key$2); super.dispose(); } // private _getconfig(config) { config = { ...default$1, ...manipulator.getdataattributes(this._element), ...(typeof config === 'object' && config ? config : {}) }; config.target = getelement(config.target) || document.documentelement; typecheckconfig(name$2, config, defaulttype$1); return config; } _getscrolltop() { return this._scrollelement === window ? this._scrollelement.pageyoffset : this._scrollelement.scrolltop; } _getscrollheight() { return this._scrollelement.scrollheight || math.max(document.body.scrollheight, document.documentelement.scrollheight); } _getoffsetheight() { return this._scrollelement === window ? window.innerheight : this._scrollelement.getboundingclientrect().height; } _process() { const scrolltop = this._getscrolltop() + this._config.offset; const scrollheight = this._getscrollheight(); const maxscroll = this._config.offset + scrollheight - this._getoffsetheight(); if (this._scrollheight !== scrollheight) { this.refresh(); } if (scrolltop >= maxscroll) { const target = this._targets[this._targets.length - 1]; if (this._activetarget !== target) { this._activate(target); } return; } if (this._activetarget && scrolltop < this._offsets[0] && this._offsets[0] > 0) { this._activetarget = null; this._clear(); return; } for (let i = this._offsets.length; i--;) { const isactivetarget = this._activetarget !== this._targets[i] && scrolltop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrolltop < this._offsets[i + 1]); if (isactivetarget) { this._activate(this._targets[i]); } } } _activate(target) { this._activetarget = target; this._clear(); const queries = selector_link_items.split(',').map(selector => `${selector}[data-bs-target="${target}"],${selector}[href="${target}"]`); const link = selectorengine.findone(queries.join(','), this._config.target); link.classlist.add(class_name_active$1); if (link.classlist.contains(class_name_dropdown_item)) { selectorengine.findone(selector_dropdown_toggle$1, link.closest(selector_dropdown$1)).classlist.add(class_name_active$1); } else { selectorengine.parents(link, selector_nav_list_group$1).foreach(listgroup => { // set triggered links parents as active // with both