From a107386ecd7cf1cb9484876c26c3e358c962cdd2 Mon Sep 17 00:00:00 2001 From: Astrian Zheng Date: Wed, 18 Oct 2023 10:40:53 +1100 Subject: [PATCH] Book appointment page --- FIT5032-Assignment/App_Start/BundleConfig.cs | 39 +- .../Controllers/AppointmentsController.cs | 30 +- FIT5032-Assignment/FIT5032-Assignment.csproj | 5 + .../FIT5032-Assignment.csproj.user | 2 +- FIT5032-Assignment/Scripts/bootstrap.js | 7263 ++++-------- FIT5032-Assignment/Scripts/bootstrap.min.js | 11 +- .../Scripts/moment-with-locales.js | 9792 +++++++++++++++++ .../Scripts/moment-with-locales.min.js | 10 + FIT5032-Assignment/Scripts/moment.js | 3043 +++++ FIT5032-Assignment/Scripts/moment.min.js | 7 + .../Views/Appointments/Create.cshtml | 73 +- FIT5032-Assignment/packages.config | 2 + 12 files changed, 15245 insertions(+), 5032 deletions(-) create mode 100644 FIT5032-Assignment/Scripts/moment-with-locales.js create mode 100644 FIT5032-Assignment/Scripts/moment-with-locales.min.js create mode 100644 FIT5032-Assignment/Scripts/moment.js create mode 100644 FIT5032-Assignment/Scripts/moment.min.js diff --git a/FIT5032-Assignment/App_Start/BundleConfig.cs b/FIT5032-Assignment/App_Start/BundleConfig.cs index b4c436d..0bf4530 100644 --- a/FIT5032-Assignment/App_Start/BundleConfig.cs +++ b/FIT5032-Assignment/App_Start/BundleConfig.cs @@ -1,30 +1,23 @@ using System.Web; using System.Web.Optimization; -namespace FIT5032_Assignment -{ - public class BundleConfig - { - // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862 - public static void RegisterBundles(BundleCollection bundles) - { - bundles.Add(new ScriptBundle("~/bundles/jquery").Include( - "~/Scripts/jquery-{version}.js")); +namespace FIT5032_Assignment { + public class BundleConfig { + // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862 + public static void RegisterBundles(BundleCollection bundles) { + bundles.Add(new ScriptBundle("~/bundles/jquery").Include("~/Scripts/jquery-{version}.js")); + bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include("~/Scripts/jquery.validate*")); - bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( - "~/Scripts/jquery.validate*")); + // Use the development version of Modernizr to develop with and learn from. Then, when you're + // ready for production, use the build tool at https://modernizr.com to pick only the tests you need. + bundles.Add(new ScriptBundle("~/bundles/modernizr").Include("~/Scripts/modernizr-*")); + bundles.Add(new Bundle("~/bundles/bootstrap").Include("~/Scripts/bootstrap.js")); + bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/bootstrap.css", "~/Content/site.css")); - // Use the development version of Modernizr to develop with and learn from. Then, when you're - // ready for production, use the build tool at https://modernizr.com to pick only the tests you need. - bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( - "~/Scripts/modernizr-*")); - - bundles.Add(new Bundle("~/bundles/bootstrap").Include( - "~/Scripts/bootstrap.js")); - - bundles.Add(new StyleBundle("~/Content/css").Include( - "~/Content/bootstrap.css", - "~/Content/site.css")); - } + // Bootstrap.v3.Datetimepicker.CSS + bundles.Add(new StyleBundle("~/bundles/datetimepicker.style").Include("~/Content/bootstrap-datetimepicker.min.css")); + bundles.Add(new ScriptBundle("~/bundles/moment").Include("~/Scripts/moment.min.js")); + bundles.Add(new Bundle("~/bundles/datetimepicker").Include("~/Scripts/bootstrap-datetimepicker.min.js")); } + } } diff --git a/FIT5032-Assignment/Controllers/AppointmentsController.cs b/FIT5032-Assignment/Controllers/AppointmentsController.cs index 8fcab73..4378ae8 100644 --- a/FIT5032-Assignment/Controllers/AppointmentsController.cs +++ b/FIT5032-Assignment/Controllers/AppointmentsController.cs @@ -22,22 +22,28 @@ namespace FIT5032_Assignment.Controllers { } // GET: Appointments/Create - public ActionResult Create() { - // Pass a dropdown list for all doctors - List doctors = db.Doctors.ToList(); - // Create a tuple for put uuid and displayName into it - List> doctorsList = new List>(); - List users = db.Users.ToList(); - for (int i = 0; i < doctors.Count; i++) { - // Get displayName from users table - string displayName = users.Find(user => user.uuid == doctors[i].user).displayName; - Tuple doctor = new Tuple(doctors[i].user, displayName); - doctorsList.Add(doctor); + public ActionResult Create(string id) { + if (id == null) { + // Pass a dropdown list for all doctors + List doctors = db.Doctors.ToList(); + List> usersList = new List>(); + foreach (var doctor in doctors) { + // Fetch the user obj + Users user = db.Users.Find(doctor.user); + usersList.Add(new Tuple(user, doctor)); + } + ViewBag.doctorsList = usersList; + } else { + ViewBag.doctorId = id; + // Fetch doctor profile + ViewBag.doctor = db.Doctors.Where(d => d.user == id); + ViewBag.doctorUser = db.Users.Find(id); } - ViewBag.doctorsList = new SelectList(doctorsList, "Item1", "Item2"); return View(); + } + // POST: Appointments/Create [HttpPost] public ActionResult Create(FormCollection collection) { diff --git a/FIT5032-Assignment/FIT5032-Assignment.csproj b/FIT5032-Assignment/FIT5032-Assignment.csproj index 95ccd9c..a8b4be2 100644 --- a/FIT5032-Assignment/FIT5032-Assignment.csproj +++ b/FIT5032-Assignment/FIT5032-Assignment.csproj @@ -295,6 +295,10 @@ + + + + Web.config @@ -318,6 +322,7 @@ + diff --git a/FIT5032-Assignment/FIT5032-Assignment.csproj.user b/FIT5032-Assignment/FIT5032-Assignment.csproj.user index 186cd61..48d35fd 100644 --- a/FIT5032-Assignment/FIT5032-Assignment.csproj.user +++ b/FIT5032-Assignment/FIT5032-Assignment.csproj.user @@ -15,7 +15,7 @@ ~/Views/Shared/_Layout.cshtml True False - True + False FIT5032_Assignment.Models.Database1Entities False False diff --git a/FIT5032-Assignment/Scripts/bootstrap.js b/FIT5032-Assignment/Scripts/bootstrap.js index 9ccfb0b..170bd60 100644 --- a/FIT5032-Assignment/Scripts/bootstrap.js +++ b/FIT5032-Assignment/Scripts/bootstrap.js @@ -1,3488 +1,1316 @@ /*! - * Bootstrap v5.2.3 (https://getbootstrap.com/) - * Copyright 2011-2022 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'; + * Bootstrap v3.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 Twitter, Inc. + * Licensed under the MIT license + */ - function _interopNamespace(e) { - if (e && e.__esModule) return e; - const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } }); - 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] - }); - } +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') +} + ++function ($) { + 'use strict'; + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4') + } +}(jQuery); + +/* ======================================================================== + * Bootstrap: transition.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#transitions + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: https://modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } } } - n.default = e; - return Object.freeze(n); + + return false // explicit for ie8 ( ._.) } - const Popper__namespace = /*#__PURE__*/_interopNamespace(Popper); + // https://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.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'; // Shout-out Angus Croll (https://goo.gl/pxwQGp) + $(function () { + $.support.transition = transitionEnd() - const toType = object => { - if (object === null || object === undefined) { - return `${object}`; - } + if (!$.support.transition) return - return Object.prototype.toString.call(object).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 hrefAttribute = 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 (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) { - return null; - } // Just in case some CMS puts out a full URL with the anchor appended - - - if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) { - hrefAttribute = `#${hrefAttribute.split('#')[1]}`; - } - - selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.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 = object => { - if (!object || typeof object !== 'object') { - return false; - } - - if (typeof object.jquery !== 'undefined') { - object = object[0]; - } - - return typeof object.nodeType !== 'undefined'; - }; - - const getElement = object => { - // it's a jQuery object or a node element - if (isElement(object)) { - return object.jquery ? object[0] : object; - } - - if (typeof object === 'string' && object.length > 0) { - return document.querySelector(object); - } - - return null; - }; - - const isVisible = element => { - if (!isElement(element) || element.getClientRects().length === 0) { - return false; - } - - const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'; // Handle `details` element as its content may falsie appear visible when it is closed - - const closedDetails = element.closest('details:not([open])'); - - if (!closedDetails) { - return elementIsVisible; - } - - if (closedDetails !== element) { - const summary = element.closest('summary'); - - if (summary && summary.parentNode !== closedDetails) { - return false; - } - - if (summary === null) { - return false; + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) } } + }) - return elementIsVisible; - }; +}(jQuery); - const isDisabled = element => { - if (!element || element.nodeType !== Node.ELEMENT_NODE) { - return true; +/* ======================================================================== + * Bootstrap: alert.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#alerts + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.4.1' + + Alert.TRANSITION_DURATION = 150 + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } - if (element.classList.contains('disabled')) { - return true; + selector = selector === '#' ? [] : selector + var $parent = $(document).find(selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.closest('.alert') } - if (typeof element.disabled !== 'undefined') { - return element.disabled; + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() } - 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 + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(Alert.TRANSITION_DURATION) : + removeElement() + } - if (typeof element.getRootNode === 'function') { - const root = element.getRootNode(); - return root instanceof ShadowRoot ? root : null; - } + // ALERT PLUGIN DEFINITION + // ======================= - if (element instanceof ShadowRoot) { - return element; - } // when we don't find a shadow root + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert - if (!element.parentNode) { - return null; - } + // ALERT NO CONFLICT + // ================= - 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 - */ + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } - const reflow = element => { - element.offsetHeight; // eslint-disable-line no-unused-expressions - }; + // ALERT DATA-API + // ============== - const getjQuery = () => { - if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) { - return window.jQuery; - } + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) - return null; - }; +}(jQuery); - const DOMContentLoadedCallbacks = []; +/* ======================================================================== + * Bootstrap: button.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#buttons + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ - 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', () => { - for (const callback of DOMContentLoadedCallbacks) { - callback(); - } - }); + ++function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.4.1' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state += 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + $el[val](data[state] == null ? this.options[state] : data[state]) + + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d).prop(d, true) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d).prop(d, false) } + }, this), 0) + } - DOMContentLoadedCallbacks.push(callback); + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + if ($input.prop('checked')) changed = false + $parent.find('.active').removeClass('active') + this.$element.addClass('active') + } else if ($input.prop('type') == 'checkbox') { + if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false + this.$element.toggleClass('active') + } + $input.prop('checked', this.$element.hasClass('active')) + if (changed) $input.trigger('change') } 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) => { - const listLength = list.length; - 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 !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]; - } - - index += shouldGetNext ? 1 : -1; - - if (isCycleAllowed) { - index = (index + listLength) % listLength; - } - - return list[Math.max(0, Math.min(index, listLength - 1))]; - }; - - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.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 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 makeEventUid(element, uid) { - return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++; - } - - function getElementEvents(element) { - const uid = makeEventUid(element); - element.uidEvent = uid; - eventRegistry[uid] = eventRegistry[uid] || {}; - return eventRegistry[uid]; - } - - function bootstrapHandler(element, fn) { - return function handler(event) { - hydrateObj(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 (const domElement of domElements) { - if (domElement !== target) { - continue; - } - - hydrateObj(event, { - delegateTarget: target - }); - - if (handler.oneOff) { - EventHandler.off(element, event.type, selector, fn); - } - - return fn.apply(target, [event]); - } - } - }; - } - - function findHandler(events, callable, delegationSelector = null) { - return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector); - } - - function normalizeParameters(originalTypeEvent, handler, delegationFunction) { - const isDelegated = typeof handler === 'string'; // todo: tooltip passes `false` instead of selector, so we need to check - - const callable = isDelegated ? delegationFunction : handler || delegationFunction; - let typeEvent = getTypeEvent(originalTypeEvent); - - if (!nativeEvents.has(typeEvent)) { - typeEvent = originalTypeEvent; - } - - return [isDelegated, callable, typeEvent]; - } - - function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) { - if (typeof originalTypeEvent !== 'string' || !element) { - return; - } - - let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position - // this prevents the handler from being dispatched the same way as mouseover or mouseout does - - if (originalTypeEvent in customEvents) { - const wrapFunction = fn => { - return function (event) { - if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) { - return fn.call(this, event); - } - }; - }; - - callable = wrapFunction(callable); - } - - const events = getElementEvents(element); - const handlers = events[typeEvent] || (events[typeEvent] = {}); - const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null); - - if (previousFunction) { - previousFunction.oneOff = previousFunction.oneOff && oneOff; - return; - } - - const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, '')); - const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable); - fn.delegationSelector = isDelegated ? handler : null; - fn.callable = callable; - fn.oneOff = oneOff; - fn.uidEvent = uid; - handlers[uid] = fn; - element.addEventListener(typeEvent, fn, isDelegated); - } - - 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] || {}; - - for (const handlerKey of Object.keys(storeElementEvent)) { - if (handlerKey.includes(namespace)) { - const event = storeElementEvent[handlerKey]; - removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); - } + this.$element.attr('aria-pressed', !this.$element.hasClass('active')) + this.$element.toggleClass('active') } } - function getTypeEvent(event) { - // allow to get the native events from namespaced events ('click.bs.button' --> 'click') - event = event.replace(stripNameRegex, ''); - return customEvents[event] || event; + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) } - const EventHandler = { - on(element, event, handler, delegationFunction) { - addHandler(element, event, handler, delegationFunction, false); - }, + var old = $.fn.button - one(element, event, handler, delegationFunction) { - addHandler(element, event, handler, delegationFunction, true); - }, + $.fn.button = Plugin + $.fn.button.Constructor = Button - off(element, originalTypeEvent, handler, delegationFunction) { - if (typeof originalTypeEvent !== 'string' || !element) { - return; - } - const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); - const inNamespace = typeEvent !== originalTypeEvent; - const events = getElementEvents(element); - const storeElementEvent = events[typeEvent] || {}; - const isNamespace = originalTypeEvent.startsWith('.'); + // BUTTON NO CONFLICT + // ================== - if (typeof callable !== 'undefined') { - // Simplest case: handler is passed, remove that listener ONLY. - if (!Object.keys(storeElementEvent).length) { - return; - } - - removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null); - return; - } - - if (isNamespace) { - for (const elementEvent of Object.keys(events)) { - removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1)); - } - } - - for (const keyHandlers of Object.keys(storeElementEvent)) { - const handlerKey = keyHandlers.replace(stripUidRegex, ''); - - if (!inNamespace || originalTypeEvent.includes(handlerKey)) { - const event = storeElementEvent[keyHandlers]; - removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); - } - } - }, - - trigger(element, event, args) { - if (typeof event !== 'string' || !element) { - return null; - } - - const $ = getjQuery(); - const typeEvent = getTypeEvent(event); - const inNamespace = event !== typeEvent; - let jQueryEvent = null; - let bubbles = true; - let nativeDispatch = true; - let defaultPrevented = false; - - if (inNamespace && $) { - jQueryEvent = $.Event(event, args); - $(element).trigger(jQueryEvent); - bubbles = !jQueryEvent.isPropagationStopped(); - nativeDispatch = !jQueryEvent.isImmediatePropagationStopped(); - defaultPrevented = jQueryEvent.isDefaultPrevented(); - } - - let evt = new Event(event, { - bubbles, - cancelable: true - }); - evt = hydrateObj(evt, args); - - if (defaultPrevented) { - evt.preventDefault(); - } - - if (nativeDispatch) { - element.dispatchEvent(evt); - } - - if (evt.defaultPrevented && jQueryEvent) { - jQueryEvent.preventDefault(); - } - - return evt; - } - - }; - - function hydrateObj(obj, meta) { - for (const [key, value] of Object.entries(meta || {})) { - try { - obj[key] = value; - } catch (_unused) { - Object.defineProperty(obj, key, { - configurable: true, - - get() { - return value; - } - - }); - } - } - - return obj; + $.fn.button.noConflict = function () { + $.fn.button = old + return this } - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.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()); + // BUTTON DATA-API + // =============== + + $(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target).closest('.btn') + Plugin.call($btn, 'toggle') + if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { + // Prevent double click on radios, and the double selections (so cancellation) on checkboxes + e.preventDefault() + // The target component still receive the focus + if ($btn.is('input,button')) $btn.trigger('focus') + else $btn.find('input:visible,button:visible').first().trigger('focus') } + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { + $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) + }) - 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 +}(jQuery); - 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; - } +/* ======================================================================== + * Bootstrap: carousel.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#carousel + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ - instanceMap.set(key, instance); - }, - get(element, key) { - if (elementMap.has(element)) { - return elementMap.get(element).get(key) || null; - } ++function ($) { + 'use strict'; - return null; - }, + // CAROUSEL CLASS DEFINITION + // ========================= - remove(element, key) { - if (!elementMap.has(element)) { - return; - } + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.paused = null + this.sliding = null + this.interval = null + this.$active = null + this.$items = null - const instanceMap = elementMap.get(element); - instanceMap.delete(key); // free up element references if there are no instances left for an element + this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) - if (instanceMap.size === 0) { - elementMap.delete(element); - } - } - - }; - - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): dom/manipulator.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - function normalizeData(value) { - if (value === 'true') { - return true; - } - - if (value === 'false') { - return false; - } - - if (value === Number(value).toString()) { - return Number(value); - } - - if (value === '' || value === 'null') { - return null; - } - - if (typeof value !== 'string') { - return value; - } - - try { - return JSON.parse(decodeURIComponent(value)); - } catch (_unused) { - return value; - } + this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) } - function normalizeDataKey(key) { - return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`); - } + Carousel.VERSION = '3.4.1' - const Manipulator = { - setDataAttribute(element, key, value) { - element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value); - }, + Carousel.TRANSITION_DURATION = 600 - removeDataAttribute(element, key) { - element.removeAttribute(`data-bs-${normalizeDataKey(key)}`); - }, - - getDataAttributes(element) { - if (!element) { - return {}; - } - - const attributes = {}; - const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig')); - - for (const key of bsKeys) { - 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)}`)); - } - - }; - - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/config.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Class definition - */ - - class Config { - // Getters - static get Default() { - return {}; - } - - static get DefaultType() { - return {}; - } - - static get NAME() { - throw new Error('You have to implement the static method "NAME", for each component!'); - } - - _getConfig(config) { - config = this._mergeConfigObj(config); - config = this._configAfterMerge(config); - - this._typeCheckConfig(config); - - return config; - } - - _configAfterMerge(config) { - return config; - } - - _mergeConfigObj(config, element) { - const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse - - return { ...this.constructor.Default, - ...(typeof jsonConfig === 'object' ? jsonConfig : {}), - ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}), - ...(typeof config === 'object' ? config : {}) - }; - } - - _typeCheckConfig(config, configTypes = this.constructor.DefaultType) { - for (const property of Object.keys(configTypes)) { - const expectedTypes = configTypes[property]; - const value = config[property]; - const valueType = isElement(value) ? 'element' : toType(value); - - if (!new RegExp(expectedTypes).test(valueType)) { - throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`); - } - } - } - - } - - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): base-component.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ - - const VERSION = '5.2.3'; - /** - * Class definition - */ - - class BaseComponent extends Config { - constructor(element, config) { - super(); - element = getElement(element); - - if (!element) { - return; - } - - this._element = element; - this._config = this._getConfig(config); - Data.set(this._element, this.constructor.DATA_KEY, this); - } // Public - - - dispose() { - Data.remove(this._element, this.constructor.DATA_KEY); - EventHandler.off(this._element, this.constructor.EVENT_KEY); - - for (const propertyName of Object.getOwnPropertyNames(this)) { - this[propertyName] = null; - } - } - - _queueCallback(callback, element, isAnimated = true) { - executeAfterTransition(callback, element, isAnimated); - } - - _getConfig(config) { - config = this._mergeConfigObj(config, this._element); - config = this._configAfterMerge(config); - - this._typeCheckConfig(config); - - return config; - } // 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 DATA_KEY() { - return `bs.${this.NAME}`; - } - - static get EVENT_KEY() { - return `.${this.DATA_KEY}`; - } - - static eventName(name) { - return `${name}${this.EVENT_KEY}`; - } - - } - - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.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.2.3): alert.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ - - const NAME$f = 'alert'; - const DATA_KEY$a = 'bs.alert'; - const EVENT_KEY$b = `.${DATA_KEY$a}`; - const EVENT_CLOSE = `close${EVENT_KEY$b}`; - const EVENT_CLOSED = `closed${EVENT_KEY$b}`; - const CLASS_NAME_FADE$5 = 'fade'; - const CLASS_NAME_SHOW$8 = 'show'; - /** - * Class definition - */ - - class Alert extends BaseComponent { - // Getters - static get NAME() { - return NAME$f; - } // 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 - */ - - defineJQueryPlugin(Alert); - - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): button.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ - - const NAME$e = 'button'; - const DATA_KEY$9 = 'bs.button'; - const EVENT_KEY$a = `.${DATA_KEY$9}`; - const DATA_API_KEY$6 = '.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$a}${DATA_API_KEY$6}`; - /** - * Class definition - */ - - class Button extends BaseComponent { - // Getters - static get NAME() { - return NAME$e; - } // 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 - */ - - defineJQueryPlugin(Button); - - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): dom/selector-engine.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ - - 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.closest(selector); - - while (ancestor) { - parents.push(ancestor); - ancestor = ancestor.parentNode.closest(selector); - } - - return parents; - }, - - prev(element, selector) { - let previous = element.previousElementSibling; - - while (previous) { - if (previous.matches(selector)) { - return [previous]; - } - - previous = previous.previousElementSibling; - } - - return []; - }, - - // TODO: this is now unused; remove later along with prev() - 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.2.3): util/swipe.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ - - const NAME$d = 'swipe'; - const EVENT_KEY$9 = '.bs.swipe'; - const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`; - const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`; - const EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`; - const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`; - const EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`; - const POINTER_TYPE_TOUCH = 'touch'; - const POINTER_TYPE_PEN = 'pen'; - const CLASS_NAME_POINTER_EVENT = 'pointer-event'; - const SWIPE_THRESHOLD = 40; - const Default$c = { - endCallback: null, - leftCallback: null, - rightCallback: null - }; - const DefaultType$c = { - endCallback: '(function|null)', - leftCallback: '(function|null)', - rightCallback: '(function|null)' - }; - /** - * Class definition - */ - - class Swipe extends Config { - constructor(element, config) { - super(); - this._element = element; - - if (!element || !Swipe.isSupported()) { - return; - } - - this._config = this._getConfig(config); - this._deltaX = 0; - this._supportPointerEvents = Boolean(window.PointerEvent); - - this._initEvents(); - } // Getters - - - static get Default() { - return Default$c; - } - - static get DefaultType() { - return DefaultType$c; - } - - static get NAME() { - return NAME$d; - } // Public - - - dispose() { - EventHandler.off(this._element, EVENT_KEY$9); - } // Private - - - _start(event) { - if (!this._supportPointerEvents) { - this._deltaX = event.touches[0].clientX; - return; - } - - if (this._eventIsPointerPenTouch(event)) { - this._deltaX = event.clientX; - } - } - - _end(event) { - if (this._eventIsPointerPenTouch(event)) { - this._deltaX = event.clientX - this._deltaX; - } - - this._handleSwipe(); - - execute(this._config.endCallback); - } - - _move(event) { - this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX; - } - - _handleSwipe() { - const absDeltaX = Math.abs(this._deltaX); - - if (absDeltaX <= SWIPE_THRESHOLD) { - return; - } - - const direction = absDeltaX / this._deltaX; - this._deltaX = 0; - - if (!direction) { - return; - } - - execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback); - } - - _initEvents() { - if (this._supportPointerEvents) { - EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event)); - EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event)); - - this._element.classList.add(CLASS_NAME_POINTER_EVENT); - } else { - EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event)); - EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event)); - EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event)); - } - } - - _eventIsPointerPenTouch(event) { - return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH); - } // Static - - - static isSupported() { - return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0; - } - - } - - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): carousel.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ - - const NAME$c = 'carousel'; - const DATA_KEY$8 = 'bs.carousel'; - const EVENT_KEY$8 = `.${DATA_KEY$8}`; - const DATA_API_KEY$5 = '.data-api'; - const ARROW_LEFT_KEY$1 = 'ArrowLeft'; - const ARROW_RIGHT_KEY$1 = 'ArrowRight'; - const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch - - const ORDER_NEXT = 'next'; - const ORDER_PREV = 'prev'; - const DIRECTION_LEFT = 'left'; - const DIRECTION_RIGHT = 'right'; - const EVENT_SLIDE = `slide${EVENT_KEY$8}`; - const EVENT_SLID = `slid${EVENT_KEY$8}`; - const EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`; - const EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`; - const EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`; - const EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`; - const EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`; - const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`; - 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 SELECTOR_ACTIVE = '.active'; - const SELECTOR_ITEM = '.carousel-item'; - const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM; - const SELECTOR_ITEM_IMG = '.carousel-item img'; - const SELECTOR_INDICATORS = '.carousel-indicators'; - const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'; - const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]'; - const KEY_TO_DIRECTION = { - [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT, - [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT - }; - const Default$b = { + Carousel.DEFAULTS = { interval: 5000, - keyboard: true, pause: 'hover', - ride: false, - touch: true, - wrap: true - }; - const DefaultType$b = { - interval: '(number|boolean)', - // TODO:v6 remove boolean support - keyboard: 'boolean', - pause: '(string|boolean)', - ride: '(boolean|string)', - touch: 'boolean', - wrap: 'boolean' - }; - /** - * Class definition - */ - - class Carousel extends BaseComponent { - constructor(element, config) { - super(element, config); - this._interval = null; - this._activeElement = null; - this._isSliding = false; - this.touchTimeout = null; - this._swipeHelper = null; - this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element); - - this._addEventListeners(); - - if (this._config.ride === CLASS_NAME_CAROUSEL) { - this.cycle(); - } - } // Getters - - - static get Default() { - return Default$b; - } - - static get DefaultType() { - return DefaultType$b; - } - - static get NAME() { - return NAME$c; - } // Public - - - next() { - this._slide(ORDER_NEXT); - } - - nextWhenVisible() { - // FIXME TODO use `document.visibilityState` - // 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() { - if (this._isSliding) { - triggerTransitionEnd(this._element); - } - - this._clearInterval(); - } - - cycle() { - this._clearInterval(); - - this._updateInterval(); - - this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval); - } - - _maybeEnableCycle() { - if (!this._config.ride) { - return; - } - - if (this._isSliding) { - EventHandler.one(this._element, EVENT_SLID, () => this.cycle()); - return; - } - - this.cycle(); - } - - to(index) { - const items = this._getItems(); - - if (index > items.length - 1 || index < 0) { - return; - } - - if (this._isSliding) { - EventHandler.one(this._element, EVENT_SLID, () => this.to(index)); - return; - } - - const activeIndex = this._getItemIndex(this._getActive()); - - if (activeIndex === index) { - return; - } - - const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV; - - this._slide(order, items[index]); - } - - dispose() { - if (this._swipeHelper) { - this._swipeHelper.dispose(); - } - - super.dispose(); - } // Private - - - _configAfterMerge(config) { - config.defaultInterval = config.interval; - return config; - } - - _addEventListeners() { - if (this._config.keyboard) { - EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event)); - } - - if (this._config.pause === 'hover') { - EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause()); - EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle()); - } - - if (this._config.touch && Swipe.isSupported()) { - this._addTouchEventListeners(); - } - } - - _addTouchEventListeners() { - for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) { - EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault()); - } - - const endCallBack = () => { - if (this._config.pause !== 'hover') { - return; - } // 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(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval); - }; - - const swipeConfig = { - leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)), - rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)), - endCallback: endCallBack - }; - this._swipeHelper = new Swipe(this._element, swipeConfig); - } - - _keydown(event) { - if (/input|textarea/i.test(event.target.tagName)) { - return; - } - - const direction = KEY_TO_DIRECTION[event.key]; - - if (direction) { - event.preventDefault(); - - this._slide(this._directionToOrder(direction)); - } - } - - _getItemIndex(element) { - return this._getItems().indexOf(element); - } - - _setActiveIndicatorElement(index) { - if (!this._indicatorsElement) { - return; - } - - const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement); - activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2); - activeIndicator.removeAttribute('aria-current'); - const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement); - - if (newActiveIndicator) { - newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2); - newActiveIndicator.setAttribute('aria-current', 'true'); - } - } - - _updateInterval() { - const element = this._activeElement || this._getActive(); - - if (!element) { - return; - } - - const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10); - this._config.interval = elementInterval || this._config.defaultInterval; - } - - _slide(order, element = null) { - if (this._isSliding) { - return; - } - - const activeElement = this._getActive(); - - const isNext = order === ORDER_NEXT; - const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap); - - if (nextElement === activeElement) { - return; - } - - const nextElementIndex = this._getItemIndex(nextElement); - - const triggerEvent = eventName => { - return EventHandler.trigger(this._element, eventName, { - relatedTarget: nextElement, - direction: this._orderToDirection(order), - from: this._getItemIndex(activeElement), - to: nextElementIndex - }); - }; - - const slideEvent = triggerEvent(EVENT_SLIDE); - - if (slideEvent.defaultPrevented) { - return; - } - - if (!activeElement || !nextElement) { - // Some weirdness is happening, so we bail - // todo: change tests that use empty divs to avoid this check - return; - } - - const isCycling = Boolean(this._interval); - this.pause(); - this._isSliding = true; - - this._setActiveIndicatorElement(nextElementIndex); - - this._activeElement = nextElement; - const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END; - const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV; - 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; - triggerEvent(EVENT_SLID); - }; - - this._queueCallback(completeCallBack, activeElement, this._isAnimated()); - - if (isCycling) { - this.cycle(); - } - } - - _isAnimated() { - return this._element.classList.contains(CLASS_NAME_SLIDE); - } - - _getActive() { - return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element); - } - - _getItems() { - return SelectorEngine.find(SELECTOR_ITEM, this._element); - } - - _clearInterval() { - if (this._interval) { - clearInterval(this._interval); - this._interval = null; - } - } - - _directionToOrder(direction) { - if (isRTL()) { - return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT; - } - - return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV; - } - - _orderToDirection(order) { - if (isRTL()) { - return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT; - } - - return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT; - } // Static - - - static jQueryInterface(config) { - return this.each(function () { - const data = Carousel.getOrCreateInstance(this, config); - - if (typeof config === 'number') { - data.to(config); - return; - } - - if (typeof config === 'string') { - if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { - throw new TypeError(`No method named "${config}"`); - } - - data[config](); - } - }); - } - + wrap: true, + keyboard: true } - /** - * Data API implementation - */ - - EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) { - const target = getElementFromSelector(this); - - if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) { - return; + Carousel.prototype.keydown = function (e) { + if (/input|textarea/i.test(e.target.tagName)) return + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return } - event.preventDefault(); - const carousel = Carousel.getOrCreateInstance(target); - const slideIndex = this.getAttribute('data-bs-slide-to'); + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.getItemForDirection = function (direction, active) { + var activeIndex = this.getItemIndex(active) + var willWrap = (direction == 'prev' && activeIndex === 0) + || (direction == 'next' && activeIndex == (this.$items.length - 1)) + if (willWrap && !this.options.wrap) return active + var delta = direction == 'prev' ? -1 : 1 + var itemIndex = (activeIndex + delta) % this.$items.length + return this.$items.eq(itemIndex) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || this.getItemForDirection(type, $active) + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var that = this + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + if (typeof $next === 'object' && $next.length) { + $next[0].offsetWidth // force reflow + } + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd(Carousel.TRANSITION_DURATION) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + var clickHandler = function (e) { + var $this = $(this) + var href = $this.attr('href') + if (href) { + href = href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + } + + var target = $this.attr('data-target') || href + var $target = $(document).find(target) + + if (!$target.hasClass('carousel')) return + + var options = $.extend({}, $target.data(), $this.data()) + var slideIndex = $this.attr('data-slide-to') + if (slideIndex) options.interval = false + + Plugin.call($target, options) if (slideIndex) { - carousel.to(slideIndex); - - carousel._maybeEnableCycle(); - - return; + $target.data('bs.carousel').to(slideIndex) } - if (Manipulator.getDataAttribute(this, 'slide') === 'next') { - carousel.next(); + e.preventDefault() + } - carousel._maybeEnableCycle(); + $(document) + .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) + .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) - return; + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: collapse.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#collapse + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + +/* jshint latedef: false */ + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + + '[data-toggle="collapse"][data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) } - carousel.prev(); + if (this.options.toggle) this.toggle() + } - carousel._maybeEnableCycle(); - }); - EventHandler.on(window, EVENT_LOAD_DATA_API$3, () => { - const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE); + Collapse.VERSION = '3.4.1' - for (const carousel of carousels) { - Carousel.getOrCreateInstance(carousel); - } - }); - /** - * jQuery - */ + Collapse.TRANSITION_DURATION = 350 - defineJQueryPlugin(Carousel); - - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): collapse.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ - - const NAME$b = 'collapse'; - const DATA_KEY$7 = 'bs.collapse'; - const EVENT_KEY$7 = `.${DATA_KEY$7}`; - const DATA_API_KEY$4 = '.data-api'; - const EVENT_SHOW$6 = `show${EVENT_KEY$7}`; - const EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`; - const EVENT_HIDE$6 = `hide${EVENT_KEY$7}`; - const EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`; - const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`; - 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"]'; - const Default$a = { - parent: null, + Collapse.DEFAULTS = { toggle: true - }; - const DefaultType$a = { - parent: '(null|element)', - toggle: 'boolean' - }; - /** - * Class definition - */ - - class Collapse extends BaseComponent { - constructor(element, config) { - super(element, config); - this._isTransitioning = false; - this._triggerArray = []; - const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4); - - for (const elem of toggleList) { - const selector = getSelectorFromElement(elem); - const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element); - - if (selector !== null && filterElement.length) { - 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$a; - } - - static get DefaultType() { - return DefaultType$a; - } - - static get NAME() { - return NAME$b; - } // Public - - - toggle() { - if (this._isShown()) { - this.hide(); - } else { - this.show(); - } - } - - show() { - if (this._isTransitioning || this._isShown()) { - return; - } - - let activeChildren = []; // find active children - - if (this._config.parent) { - activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, { - toggle: false - })); - } - - if (activeChildren.length && activeChildren[0]._isTransitioning) { - return; - } - - const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6); - - if (startEvent.defaultPrevented) { - return; - } - - for (const activeInstance of activeChildren) { - activeInstance.hide(); - } - - 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$6); - }; - - 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$6); - - 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); - - for (const trigger of this._triggerArray) { - const element = getElementFromSelector(trigger); - - if (element && !this._isShown(element)) { - 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$6); - }; - - this._element.style[dimension] = ''; - - this._queueCallback(complete, this._element, true); - } - - _isShown(element = this._element) { - return element.classList.contains(CLASS_NAME_SHOW$7); - } // Private - - - _configAfterMerge(config) { - config.toggle = Boolean(config.toggle); // Coerce string values - - config.parent = getElement(config.parent); - return config; - } - - _getDimension() { - return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT; - } - - _initializeChildren() { - if (!this._config.parent) { - return; - } - - const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4); - - for (const element of children) { - const selected = getElementFromSelector(element); - - if (selected) { - this._addAriaAndCollapsedClass([element], this._isShown(selected)); - } - } - } - - _getFirstLevelChildren(selector) { - const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent); // remove children if greater depth - - return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element)); - } - - _addAriaAndCollapsedClass(triggerArray, isOpen) { - if (!triggerArray.length) { - return; - } - - for (const element of triggerArray) { - element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen); - element.setAttribute('aria-expanded', isOpen); - } - } // Static - - - static jQueryInterface(config) { - const _config = {}; - - if (typeof config === 'string' && /show|hide/.test(config)) { - _config.toggle = false; - } - - return this.each(function () { - 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); - - for (const element of selectorElements) { - Collapse.getOrCreateInstance(element, { - toggle: false - }).toggle(); - } - }); - /** - * jQuery - */ - - defineJQueryPlugin(Collapse); - - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): dropdown.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ - - const NAME$a = 'dropdown'; - const DATA_KEY$6 = 'bs.dropdown'; - const EVENT_KEY$6 = `.${DATA_KEY$6}`; - const DATA_API_KEY$3 = '.data-api'; - const ESCAPE_KEY$2 = 'Escape'; - const TAB_KEY$1 = 'Tab'; - const ARROW_UP_KEY$1 = 'ArrowUp'; - const ARROW_DOWN_KEY$1 = 'ArrowDown'; - const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button - - const EVENT_HIDE$5 = `hide${EVENT_KEY$6}`; - const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`; - const EVENT_SHOW$5 = `show${EVENT_KEY$6}`; - const EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`; - const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`; - const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`; - const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`; - const CLASS_NAME_SHOW$6 = 'show'; - const CLASS_NAME_DROPUP = 'dropup'; - const CLASS_NAME_DROPEND = 'dropend'; - const CLASS_NAME_DROPSTART = 'dropstart'; - const CLASS_NAME_DROPUP_CENTER = 'dropup-center'; - const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center'; - const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)'; - const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`; - const SELECTOR_MENU = '.dropdown-menu'; - const SELECTOR_NAVBAR = '.navbar'; - 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 PLACEMENT_TOPCENTER = 'top'; - const PLACEMENT_BOTTOMCENTER = 'bottom'; - const Default$9 = { - autoClose: true, - boundary: 'clippingParents', - display: 'dynamic', - offset: [0, 2], - popperConfig: null, - reference: 'toggle' - }; - const DefaultType$9 = { - autoClose: '(boolean|string)', - boundary: '(string|element)', - display: 'string', - offset: '(array|string|function)', - popperConfig: '(null|object|function)', - reference: '(string|element|object)' - }; - /** - * Class definition - */ - - class Dropdown extends BaseComponent { - constructor(element, config) { - super(element, config); - this._popper = null; - this._parent = this._element.parentNode; // dropdown wrapper - // todo: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.2/forms/input-group/ - - this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent); - this._inNavbar = this._detectNavbar(); - } // Getters - - - static get Default() { - return Default$9; - } - - static get DefaultType() { - return DefaultType$9; - } - - static get NAME() { - return NAME$a; - } // Public - - - toggle() { - return this._isShown() ? this.hide() : this.show(); - } - - show() { - if (isDisabled(this._element) || this._isShown()) { - return; - } - - const relatedTarget = { - relatedTarget: this._element - }; - const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget); - - if (showEvent.defaultPrevented) { - return; - } - - this._createPopper(); // 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 && !this._parent.closest(SELECTOR_NAVBAR_NAV)) { - for (const element of [].concat(...document.body.children)) { - EventHandler.on(element, '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$5, relatedTarget); - } - - hide() { - if (isDisabled(this._element) || !this._isShown()) { - 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$5, 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) { - for (const element of [].concat(...document.body.children)) { - EventHandler.off(element, '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$5, relatedTarget); - } - - _getConfig(config) { - config = super._getConfig(config); - - if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') { - // Popper virtual elements require a getBoundingClientRect method - throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`); - } - - return config; - } - - _createPopper() { - 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 = this._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(); - - this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig); - } - - _isShown() { - return this._menu.classList.contains(CLASS_NAME_SHOW$6); - } - - _getPlacement() { - const parentDropdown = this._parent; - - if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) { - return PLACEMENT_RIGHT; - } - - if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) { - return PLACEMENT_LEFT; - } - - if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) { - return PLACEMENT_TOPCENTER; - } - - if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) { - return PLACEMENT_BOTTOMCENTER; - } // 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(SELECTOR_NAVBAR) !== null; - } - - _getOffset() { - const { - offset - } = this._config; - - if (typeof offset === 'string') { - return offset.split(',').map(value => Number.parseInt(value, 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 or Dropdown is in Navbar - - if (this._inNavbar || this._config.display === 'static') { - Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // todo:v6 remove - - 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(element => isVisible(element)); - - 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$1, !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.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) { - return; - } - - const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN); - - for (const toggle of openToggles) { - const context = Dropdown.getInstance(toggle); - - if (!context || context._config.autoClose === false) { - continue; - } - - 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; - } - - const relatedTarget = { - relatedTarget: context._element - }; - - if (event.type === 'click') { - relatedTarget.clickEvent = event; - } - - context._completeHide(relatedTarget); - } - } - - static dataApiKeydownHandler(event) { - // If not an UP | DOWN | ESCAPE key => not a dropdown command - // If input/textarea && if key is other than ESCAPE => not a dropdown command - const isInput = /input|textarea/i.test(event.target.tagName); - const isEscapeEvent = event.key === ESCAPE_KEY$2; - const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key); - - if (!isUpOrDownEvent && !isEscapeEvent) { - return; - } - - if (isInput && !isEscapeEvent) { - return; - } - - event.preventDefault(); // todo: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.2/forms/input-group/ - - const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3, event.delegateTarget.parentNode); - const instance = Dropdown.getOrCreateInstance(getToggleButton); - - if (isUpOrDownEvent) { - event.stopPropagation(); - instance.show(); - - instance._selectMenuItem(event); - - return; - } - - if (instance._isShown()) { - // else is escape and we check if it is shown - event.stopPropagation(); - instance.hide(); - getToggleButton.focus(); - } - } - - } - /** - * 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 - */ - - defineJQueryPlugin(Dropdown); - - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/scrollBar.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ - - const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'; - const SELECTOR_STICKY_CONTENT = '.sticky-top'; - const PROPERTY_PADDING = 'padding-right'; - const PROPERTY_MARGIN = 'margin-right'; - /** - * Class definition - */ - - class ScrollBarHelper { - constructor() { - this._element = document.body; - } // Public - - - 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, PROPERTY_PADDING, calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth - - - this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width); - - this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width); - } - - reset() { - this._resetElementAttributes(this._element, 'overflow'); - - this._resetElementAttributes(this._element, PROPERTY_PADDING); - - this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING); - - this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN); - } - - isOverflowing() { - return this.getWidth() > 0; - } // Private - - - _disableOverFlow() { - this._saveInitialAttribute(this._element, 'overflow'); - - this._element.style.overflow = 'hidden'; - } - - _setElementAttributes(selector, styleProperty, callback) { - const scrollbarWidth = this.getWidth(); - - const manipulationCallBack = element => { - if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) { - return; - } - - this._saveInitialAttribute(element, styleProperty); - - const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty); - element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`); - }; - - this._applyManipulationCallback(selector, manipulationCallBack); - } - - _saveInitialAttribute(element, styleProperty) { - const actualValue = element.style.getPropertyValue(styleProperty); - - if (actualValue) { - Manipulator.setDataAttribute(element, styleProperty, actualValue); - } - } - - _resetElementAttributes(selector, styleProperty) { - const manipulationCallBack = element => { - const value = Manipulator.getDataAttribute(element, styleProperty); // We only want to remove the property if the value is `null`; the value can also be zero - - if (value === null) { - element.style.removeProperty(styleProperty); - return; - } - - Manipulator.removeDataAttribute(element, styleProperty); - element.style.setProperty(styleProperty, value); - }; - - this._applyManipulationCallback(selector, manipulationCallBack); - } - - _applyManipulationCallback(selector, callBack) { - if (isElement(selector)) { - callBack(selector); - return; - } - - for (const sel of SelectorEngine.find(selector, this._element)) { - callBack(sel); - } - } - } - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/backdrop.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ - - const NAME$9 = 'backdrop'; - const CLASS_NAME_FADE$4 = 'fade'; - const CLASS_NAME_SHOW$5 = 'show'; - const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`; - const Default$8 = { - className: 'modal-backdrop', - clickCallback: null, - isAnimated: false, - isVisible: true, - // if false, we use the backdrop helper without adding any element to the dom - rootElement: 'body' // give the choice to place backdrop under different elements - - }; - const DefaultType$8 = { - className: 'string', - clickCallback: '(function|null)', - isAnimated: 'boolean', - isVisible: 'boolean', - rootElement: '(element|string)' - }; - /** - * Class definition - */ - - class Backdrop extends Config { - constructor(config) { - super(); - this._config = this._getConfig(config); - this._isAppended = false; - this._element = null; - } // Getters - - - static get Default() { - return Default$8; - } - - static get DefaultType() { - return DefaultType$8; - } - - static get NAME() { - return NAME$9; - } // Public - - - show(callback) { - if (!this._config.isVisible) { - execute(callback); - return; - } - - this._append(); - - const element = this._getElement(); - - if (this._config.isAnimated) { - reflow(element); - } - - element.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); - }); - } - - dispose() { - if (!this._isAppended) { - return; - } - - EventHandler.off(this._element, EVENT_MOUSEDOWN); - - this._element.remove(); - - this._isAppended = false; - } // 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; - } - - _configAfterMerge(config) { - // use getElement() with the default "body" to get a fresh Element on each instantiation - config.rootElement = getElement(config.rootElement); - return config; - } - - _append() { - if (this._isAppended) { - return; - } - - const element = this._getElement(); - - this._config.rootElement.append(element); - - EventHandler.on(element, EVENT_MOUSEDOWN, () => { - execute(this._config.clickCallback); - }); - this._isAppended = true; - } - - _emulateAnimation(callback) { - executeAfterTransition(callback, this._getElement(), this._config.isAnimated); - } - + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' } - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/focustrap.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return - const NAME$8 = 'focustrap'; - const DATA_KEY$5 = 'bs.focustrap'; - const EVENT_KEY$5 = `.${DATA_KEY$5}`; - const EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`; - const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`; - const TAB_KEY = 'Tab'; - const TAB_NAV_FORWARD = 'forward'; - const TAB_NAV_BACKWARD = 'backward'; - const Default$7 = { - autofocus: true, - trapElement: null // The element to trap focus inside of + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') - }; - const DefaultType$7 = { - autofocus: 'boolean', - trapElement: 'element' - }; - /** - * Class definition - */ - - class FocusTrap extends Config { - constructor(config) { - super(); - this._config = this._getConfig(config); - this._isActive = false; - this._lastTabNavDirection = null; - } // Getters - - - static get Default() { - return Default$7; + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return } - static get DefaultType() { - return DefaultType$7; + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) } - static get NAME() { - return NAME$8; - } // Public + var dimension = this.dimension() + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) - activate() { - if (this._isActive) { - return; - } + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) - if (this._config.autofocus) { - this._config.trapElement.focus(); - } + this.transitioning = 1 - EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop - - EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event)); - EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event)); - this._isActive = true; + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') } - deactivate() { - if (!this._isActive) { - return; - } + if (!$.support.transition) return complete.call(this) - this._isActive = false; - EventHandler.off(document, EVENT_KEY$5); - } // Private - - - _handleFocusin(event) { - const { - trapElement - } = this._config; - - if (event.target === document || event.target === trapElement || trapElement.contains(event.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; - } + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) } - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): modal.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return - const NAME$7 = 'modal'; - const DATA_KEY$4 = 'bs.modal'; - const EVENT_KEY$4 = `.${DATA_KEY$4}`; - const DATA_API_KEY$2 = '.data-api'; - const ESCAPE_KEY$1 = 'Escape'; - const EVENT_HIDE$4 = `hide${EVENT_KEY$4}`; - const EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`; - const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`; - const EVENT_SHOW$4 = `show${EVENT_KEY$4}`; - const EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`; - const EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`; - const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`; - const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`; - const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`; - const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`; - 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"]'; - const Default$6 = { - backdrop: true, - focus: true, - keyboard: true - }; - const DefaultType$6 = { - backdrop: '(boolean|string)', - focus: 'boolean', - keyboard: 'boolean' - }; - /** - * Class definition - */ + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return - class Modal extends BaseComponent { - constructor(element, config) { - super(element, config); - this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element); - this._backdrop = this._initializeBackDrop(); - this._focustrap = this._initializeFocusTrap(); - this._isShown = false; - this._isTransitioning = false; - this._scrollBar = new ScrollBarHelper(); + var dimension = this.dimension() - this._addEventListeners(); - } // Getters + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) - static get Default() { - return Default$6; + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') } - static get DefaultType() { - return DefaultType$6; - } - - static get NAME() { - return NAME$7; - } // 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$4, { - relatedTarget - }); - - if (showEvent.defaultPrevented) { - return; - } - - this._isShown = true; - this._isTransitioning = true; - - this._scrollBar.hide(); - - document.body.classList.add(CLASS_NAME_OPEN); - - this._adjustDialog(); - - this._backdrop.show(() => this._showElement(relatedTarget)); - } - - hide() { - if (!this._isShown || this._isTransitioning) { - return; - } - - const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4); - - if (hideEvent.defaultPrevented) { - return; - } - - this._isShown = false; - this._isTransitioning = true; - - this._focustrap.deactivate(); - - this._element.classList.remove(CLASS_NAME_SHOW$4); - - this._queueCallback(() => this._hideModal(), this._element, this._isAnimated()); - } - - dispose() { - for (const htmlElement of [window, this._dialog]) { - EventHandler.off(htmlElement, EVENT_KEY$4); - } - - 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 - }); - } - - _showElement(relatedTarget) { - // try to append dynamic modal - if (!document.body.contains(this._element)) { - 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; - const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog); - - if (modalBody) { - modalBody.scrollTop = 0; - } - - 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$4, { - relatedTarget - }); - }; - - this._queueCallback(transitionComplete, this._dialog, this._isAnimated()); - } - - _addEventListeners() { - EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => { - if (event.key !== ESCAPE_KEY$1) { - return; - } - - if (this._config.keyboard) { - event.preventDefault(); - this.hide(); - return; - } - - this._triggerBackdropTransition(); - }); - EventHandler.on(window, EVENT_RESIZE$1, () => { - if (this._isShown && !this._isTransitioning) { - this._adjustDialog(); - } - }); - EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => { - // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks - EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => { - if (this._element !== event.target || this._element !== event2.target) { - return; - } - - if (this._config.backdrop === 'static') { - this._triggerBackdropTransition(); - - return; - } - - if (this._config.backdrop) { - this.hide(); - } - }); - }); - } - - _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$4); - }); - } - - _isAnimated() { - return this._element.classList.contains(CLASS_NAME_FADE$3); - } - - _triggerBackdropTransition() { - const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1); - - if (hideEvent.defaultPrevented) { - return; - } - - const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; - const initialOverflowY = this._element.style.overflowY; // return if the following background transition hasn't yet completed - - if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) { - return; - } - - if (!isModalOverflowing) { - this._element.style.overflowY = 'hidden'; - } - - this._element.classList.add(CLASS_NAME_STATIC); - - this._queueCallback(() => { - this._element.classList.remove(CLASS_NAME_STATIC); - - this._queueCallback(() => { - this._element.style.overflowY = initialOverflowY; - }, 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) { - const property = isRTL() ? 'paddingLeft' : 'paddingRight'; - this._element.style[property] = `${scrollbarWidth}px`; - } - - if (!isBodyOverflowing && isModalOverflowing) { - const property = isRTL() ? 'paddingRight' : 'paddingLeft'; - this._element.style[property] = `${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); - }); - } + if (!$.support.transition) return complete.call(this) + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(document).find(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(document).find(target) } - /** - * Data API implementation - */ - EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) { - const target = getElementFromSelector(this); + // COLLAPSE PLUGIN DEFINITION + // ========================== - if (['A', 'AREA'].includes(this.tagName)) { - event.preventDefault(); + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + + Plugin.call($target, option) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: dropdown.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + Dropdown.VERSION = '3.4.1' + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } - EventHandler.one(target, EVENT_SHOW$4, showEvent => { - if (showEvent.defaultPrevented) { - // only register focus restorer if modal will actually get shown - return; + var $parent = selector !== '#' ? $(document).find(selector) : null + + return $parent && $parent.length ? $parent : $this.parent() + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) + }) + } + + Dropdown.prototype.toggle = function (e) { + var $this = $(this) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $(document.createElement('div')) + .addClass('dropdown-backdrop') + .insertAfter($(this)) + .on('click', clearMenus) } - EventHandler.one(target, EVENT_HIDDEN$4, () => { - if (isVisible(this)) { - this.focus(); - } - }); - }); // avoid conflict when clicking modal toggler while another one is open + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) - const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1); + if (e.isDefaultPrevented()) return - if (alreadyOpen) { - Modal.getInstance(alreadyOpen).hide(); + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger($.Event('shown.bs.dropdown', relatedTarget)) } - const data = Modal.getOrCreateInstance(target); - data.toggle(this); - }); - enableDismissTrigger(Modal); - /** - * jQuery - */ + return false + } - defineJQueryPlugin(Modal); + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): offcanvas.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ + var $this = $(this) - const NAME$6 = 'offcanvas'; - const DATA_KEY$3 = 'bs.offcanvas'; - const EVENT_KEY$3 = `.${DATA_KEY$3}`; - const DATA_API_KEY$1 = '.data-api'; - const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`; - const ESCAPE_KEY = 'Escape'; - const CLASS_NAME_SHOW$3 = 'show'; - const CLASS_NAME_SHOWING$1 = 'showing'; - const CLASS_NAME_HIDING = 'hiding'; - const CLASS_NAME_BACKDROP = 'offcanvas-backdrop'; - const OPEN_SELECTOR = '.offcanvas.show'; - const EVENT_SHOW$3 = `show${EVENT_KEY$3}`; - const EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`; - const EVENT_HIDE$3 = `hide${EVENT_KEY$3}`; - const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`; - const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`; - const EVENT_RESIZE = `resize${EVENT_KEY$3}`; - const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`; - const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`; - const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="offcanvas"]'; - const Default$5 = { + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + if (!isActive && e.which != 27 || isActive && e.which == 27) { + if (e.which == 27) $parent.find(toggle).trigger('focus') + return $this.trigger('click') + } + + var desc = ' li:not(.disabled):visible a' + var $items = $parent.find('.dropdown-menu' + desc) + + if (!$items.length) return + + var index = $items.index(e.target) + + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items.eq(index).trigger('focus') + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) + .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: modal.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#modals + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$dialog = this.$element.find('.modal-dialog') + this.$backdrop = null + this.isShown = null + this.originalBodyPad = null + this.scrollbarWidth = 0 + this.ignoreBackdropClick = false + this.fixedContent = '.navbar-fixed-top, .navbar-fixed-bottom' + + if (this.options.remote) { + this.$element + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.4.1' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { backdrop: true, keyboard: true, - scroll: false - }; - const DefaultType$5 = { - backdrop: '(boolean|string)', - keyboard: 'boolean', - scroll: 'boolean' - }; - /** - * Class definition - */ - - class Offcanvas extends BaseComponent { - constructor(element, config) { - super(element, config); - this._isShown = false; - this._backdrop = this._initializeBackDrop(); - this._focustrap = this._initializeFocusTrap(); - - this._addEventListeners(); - } // Getters - - - static get Default() { - return Default$5; - } - - static get DefaultType() { - return DefaultType$5; - } - - static get NAME() { - return NAME$6; - } // 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$3, { - relatedTarget - }); - - if (showEvent.defaultPrevented) { - return; - } - - this._isShown = true; - - this._backdrop.show(); - - if (!this._config.scroll) { - new ScrollBarHelper().hide(); - } - - this._element.setAttribute('aria-modal', true); - - this._element.setAttribute('role', 'dialog'); - - this._element.classList.add(CLASS_NAME_SHOWING$1); - - const completeCallBack = () => { - if (!this._config.scroll || this._config.backdrop) { - this._focustrap.activate(); - } - - this._element.classList.add(CLASS_NAME_SHOW$3); - - this._element.classList.remove(CLASS_NAME_SHOWING$1); - - EventHandler.trigger(this._element, EVENT_SHOWN$3, { - relatedTarget - }); - }; - - this._queueCallback(completeCallBack, this._element, true); - } - - hide() { - if (!this._isShown) { - return; - } - - const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3); - - if (hideEvent.defaultPrevented) { - return; - } - - this._focustrap.deactivate(); - - this._element.blur(); - - this._isShown = false; - - this._element.classList.add(CLASS_NAME_HIDING); - - this._backdrop.hide(); - - const completeCallback = () => { - this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING); - - this._element.removeAttribute('aria-modal'); - - this._element.removeAttribute('role'); - - if (!this._config.scroll) { - new ScrollBarHelper().reset(); - } - - EventHandler.trigger(this._element, EVENT_HIDDEN$3); - }; - - this._queueCallback(completeCallback, this._element, true); - } - - dispose() { - this._backdrop.dispose(); - - this._focustrap.deactivate(); - - super.dispose(); - } // Private - - - _initializeBackDrop() { - const clickCallback = () => { - if (this._config.backdrop === 'static') { - EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); - return; - } - - this.hide(); - }; // 'static' option will be translated to true, and booleans will keep their value - - - const isVisible = Boolean(this._config.backdrop); - return new Backdrop({ - className: CLASS_NAME_BACKDROP, - isVisible, - isAnimated: true, - rootElement: this._element.parentNode, - clickCallback: isVisible ? clickCallback : null - }); - } - - _initializeFocusTrap() { - return new FocusTrap({ - trapElement: this._element - }); - } - - _addEventListeners() { - EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => { - if (event.key !== ESCAPE_KEY) { - return; - } - - if (!this._config.keyboard) { - EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); - return; - } - - 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); - }); - } - + show: true } - /** - * Data API implementation - */ + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } - EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) { - const target = getElementFromSelector(this); + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) - if (['A', 'AREA'].includes(this.tagName)) { - event.preventDefault(); - } + this.$element.trigger(e) - if (isDisabled(this)) { - return; - } + if (this.isShown || e.isDefaultPrevented()) return - EventHandler.one(target, EVENT_HIDDEN$3, () => { - // 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 + this.isShown = true - const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR); + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') - if (alreadyOpen && alreadyOpen !== target) { - Offcanvas.getInstance(alreadyOpen).hide(); - } + this.escape() + this.resize() - const data = Offcanvas.getOrCreateInstance(target); - data.toggle(this); - }); - EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => { - for (const selector of SelectorEngine.find(OPEN_SELECTOR)) { - Offcanvas.getOrCreateInstance(selector).show(); - } - }); - EventHandler.on(window, EVENT_RESIZE, () => { - for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) { - if (getComputedStyle(element).position !== 'fixed') { - Offcanvas.getOrCreateInstance(element).hide(); - } - } - }); - enableDismissTrigger(Offcanvas); - /** - * jQuery - */ + this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) - defineJQueryPlugin(Offcanvas); + this.$dialog.on('mousedown.dismiss.bs.modal', function () { + that.$element.one('mouseup.dismiss.bs.modal', function (e) { + if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true + }) + }) - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.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. - * - * Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts - */ + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') - 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. - * - * Shout-out 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)); + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position } - return true; - } // Check if a regular expression validates the attribute. + that.$element + .show() + .scrollTop(0) + + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$dialog // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .off('click.dismiss.bs.modal') + .off('mouseup.dismiss.bs.modal') + + this.$dialog.off('mousedown.dismiss.bs.modal') + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (document !== e.target && + this.$element[0] !== e.target && + !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $(document.createElement('div')) + .addClass('modal-backdrop ' + animate) + .appendTo(this.$body) + + this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { + if (this.ignoreBackdropClick) { + this.ignoreBackdropClick = false + return + } + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus() + : this.hide() + }, this)) + + if (doAnimate) this.$backdrop[0].offsetWidth // force reflow + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + this.adjustDialog() + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + var fullWindowWidth = window.innerWidth + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 + var documentElementRect = document.documentElement.getBoundingClientRect() + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) + } + this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth + this.scrollbarWidth = this.measureScrollbar() + } + + Modal.prototype.setScrollbar = function () { + var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) + this.originalBodyPad = document.body.style.paddingRight || '' + var scrollbarWidth = this.scrollbarWidth + if (this.bodyIsOverflowing) { + this.$body.css('padding-right', bodyPad + scrollbarWidth) + $(this.fixedContent).each(function (index, element) { + var actualPadding = element.style.paddingRight + var calculatedPadding = $(element).css('padding-right') + $(element) + .data('padding-right', actualPadding) + .css('padding-right', parseFloat(calculatedPadding) + scrollbarWidth + 'px') + }) + } + } + + Modal.prototype.resetScrollbar = function () { + this.$body.css('padding-right', this.originalBodyPad) + $(this.fixedContent).each(function (index, element) { + var padding = $(element).data('padding-right') + $(element).removeData('padding-right') + element.style.paddingRight = padding ? padding : '' + }) + } + + Modal.prototype.measureScrollbar = function () { // thx walsh + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } - return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName)); - }; + // MODAL PLUGIN DEFINITION + // ======================= - const DefaultAllowlist = { + function Plugin(option, _relatedTarget) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.modal') + var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data) $this.data('bs.modal', (data = new Modal(this, options))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { + var $this = $(this) + var href = $this.attr('href') + var target = $this.attr('data-target') || + (href && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + + var $target = $(document).find(target) + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + + if ($this.is('a')) e.preventDefault() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tooltip.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#tooltip + * Inspired by the original jQuery.tipsy by Jason Frame + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + ++function ($) { + 'use strict'; + + var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'] + + var uriAttrs = [ + 'background', + 'cite', + 'href', + 'itemtype', + 'longdesc', + 'poster', + 'src', + 'xlink:href' + ] + + var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i + + var DefaultWhitelist = { // Global attributes allowed on any supplied element below. '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], a: ['target', 'href', 'title', 'rel'], @@ -3501,7 +1329,7 @@ h5: [], h6: [], i: [], - img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], + img: ['src', 'alt', 'title', 'width', 'height'], li: [], ol: [], p: [], @@ -3514,1736 +1342,1239 @@ strong: [], u: [], ul: [] - }; - function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) { - if (!unsafeHtml.length) { - return unsafeHtml; - } + } - if (sanitizeFunction && typeof sanitizeFunction === 'function') { - return sanitizeFunction(unsafeHtml); - } + /** + * A pattern that recognizes a commonly useful subset of URLs that are safe. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi - const domParser = new window.DOMParser(); - const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); - const elements = [].concat(...createdDocument.body.querySelectorAll('*')); + /** + * A pattern that matches safe data URLs. Only matches image, video and audio types. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i - for (const element of elements) { - const elementName = element.nodeName.toLowerCase(); + function allowedAttribute(attr, allowedAttributeList) { + var attrName = attr.nodeName.toLowerCase() - if (!Object.keys(allowList).includes(elementName)) { - element.remove(); - continue; + if ($.inArray(attrName, allowedAttributeList) !== -1) { + if ($.inArray(attrName, uriAttrs) !== -1) { + return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)) } - const attributeList = [].concat(...element.attributes); - const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []); + return true + } - for (const attribute of attributeList) { - if (!allowedAttribute(attribute, allowedAttributes)) { - element.removeAttribute(attribute.nodeName); + var regExp = $(allowedAttributeList).filter(function (index, value) { + return value instanceof RegExp + }) + + // Check if a regular expression validates the attribute. + for (var i = 0, l = regExp.length; i < l; i++) { + if (attrName.match(regExp[i])) { + return true + } + } + + return false + } + + function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { + if (unsafeHtml.length === 0) { + return unsafeHtml + } + + if (sanitizeFn && typeof sanitizeFn === 'function') { + return sanitizeFn(unsafeHtml) + } + + // IE 8 and below don't support createHTMLDocument + if (!document.implementation || !document.implementation.createHTMLDocument) { + return unsafeHtml + } + + var createdDocument = document.implementation.createHTMLDocument('sanitization') + createdDocument.body.innerHTML = unsafeHtml + + var whitelistKeys = $.map(whiteList, function (el, i) { return i }) + var elements = $(createdDocument.body).find('*') + + for (var i = 0, len = elements.length; i < len; i++) { + var el = elements[i] + var elName = el.nodeName.toLowerCase() + + if ($.inArray(elName, whitelistKeys) === -1) { + el.parentNode.removeChild(el) + + continue + } + + var attributeList = $.map(el.attributes, function (el) { return el }) + var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []) + + for (var j = 0, len2 = attributeList.length; j < len2; j++) { + if (!allowedAttribute(attributeList[j], whitelistedAttributes)) { + el.removeAttribute(attributeList[j].nodeName) } } } - return createdDocument.body.innerHTML; + return createdDocument.body.innerHTML } - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): util/template-factory.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ + // TOOLTIP PUBLIC CLASS DEFINITION + // =============================== - const NAME$5 = 'TemplateFactory'; - const Default$4 = { - allowList: DefaultAllowlist, - content: {}, - // { selector : text , selector2 : text2 , } - extraClass: '', - html: false, - sanitize: true, - sanitizeFn: null, - template: '
' - }; - const DefaultType$4 = { - allowList: 'object', - content: 'object', - extraClass: '(string|function)', - html: 'boolean', - sanitize: 'boolean', - sanitizeFn: '(null|function)', - template: 'string' - }; - const DefaultContentType = { - entry: '(string|element|function|null)', - selector: '(string|element)' - }; - /** - * Class definition - */ - - class TemplateFactory extends Config { - constructor(config) { - super(); - this._config = this._getConfig(config); - } // Getters - - - static get Default() { - return Default$4; - } - - static get DefaultType() { - return DefaultType$4; - } - - static get NAME() { - return NAME$5; - } // Public - - - getContent() { - return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean); - } - - hasContent() { - return this.getContent().length > 0; - } - - changeContent(content) { - this._checkContent(content); - - this._config.content = { ...this._config.content, - ...content - }; - return this; - } - - toHtml() { - const templateWrapper = document.createElement('div'); - templateWrapper.innerHTML = this._maybeSanitize(this._config.template); - - for (const [selector, text] of Object.entries(this._config.content)) { - this._setContent(templateWrapper, text, selector); - } - - const template = templateWrapper.children[0]; - - const extraClass = this._resolvePossibleFunction(this._config.extraClass); - - if (extraClass) { - template.classList.add(...extraClass.split(' ')); - } - - return template; - } // Private - - - _typeCheckConfig(config) { - super._typeCheckConfig(config); - - this._checkContent(config.content); - } - - _checkContent(arg) { - for (const [selector, content] of Object.entries(arg)) { - super._typeCheckConfig({ - selector, - entry: content - }, DefaultContentType); - } - } - - _setContent(template, content, selector) { - const templateElement = SelectorEngine.findOne(selector, template); - - if (!templateElement) { - return; - } - - content = this._resolvePossibleFunction(content); - - if (!content) { - templateElement.remove(); - return; - } - - if (isElement(content)) { - this._putElementInTemplate(getElement(content), templateElement); - - return; - } - - if (this._config.html) { - templateElement.innerHTML = this._maybeSanitize(content); - return; - } - - templateElement.textContent = content; - } - - _maybeSanitize(arg) { - return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg; - } - - _resolvePossibleFunction(arg) { - return typeof arg === 'function' ? arg(this) : arg; - } - - _putElementInTemplate(element, templateElement) { - if (this._config.html) { - templateElement.innerHTML = ''; - templateElement.append(element); - return; - } - - templateElement.textContent = element.textContent; - } + var Tooltip = function (element, options) { + this.type = null + this.options = null + this.enabled = null + this.timeout = null + this.hoverState = null + this.$element = null + this.inState = null + this.init('tooltip', element, options) } - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): tooltip.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ + Tooltip.VERSION = '3.4.1' - const NAME$4 = 'tooltip'; - const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']); - const CLASS_NAME_FADE$2 = 'fade'; - const CLASS_NAME_MODAL = 'modal'; - const CLASS_NAME_SHOW$2 = 'show'; - 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'; - const EVENT_HIDE$2 = 'hide'; - const EVENT_HIDDEN$2 = 'hidden'; - const EVENT_SHOW$2 = 'show'; - const EVENT_SHOWN$2 = 'shown'; - const EVENT_INSERTED = 'inserted'; - const EVENT_CLICK$1 = 'click'; - const EVENT_FOCUSIN$1 = 'focusin'; - const EVENT_FOCUSOUT$1 = 'focusout'; - const EVENT_MOUSEENTER = 'mouseenter'; - const EVENT_MOUSELEAVE = 'mouseleave'; - const AttachmentMap = { - AUTO: 'auto', - TOP: 'top', - RIGHT: isRTL() ? 'left' : 'right', - BOTTOM: 'bottom', - LEFT: isRTL() ? 'right' : 'left' - }; - const Default$3 = { - allowList: DefaultAllowlist, + Tooltip.TRANSITION_DURATION = 150 + + Tooltip.DEFAULTS = { animation: true, - boundary: 'clippingParents', - container: false, - customClass: '', - delay: 0, - fallbackPlacements: ['top', 'right', 'bottom', 'left'], - html: false, - offset: [0, 0], placement: 'top', - popperConfig: null, - sanitize: true, - sanitizeFn: null, selector: false, - template: '', + template: '', + trigger: 'hover focus', title: '', - trigger: 'hover focus' - }; - const DefaultType$3 = { - allowList: 'object', - animation: 'boolean', - boundary: '(string|element)', - container: '(string|element|boolean)', - customClass: '(string|function)', - delay: '(number|object)', - fallbackPlacements: 'array', - html: 'boolean', - offset: '(array|string|function)', - placement: '(string|function)', - popperConfig: '(null|object|function)', - sanitize: 'boolean', - sanitizeFn: '(null|function)', - selector: '(string|boolean)', - template: 'string', - title: '(string|element|function)', - trigger: 'string' - }; - /** - * Class definition - */ + delay: 0, + html: false, + container: false, + viewport: { + selector: 'body', + padding: 0 + }, + sanitize : true, + sanitizeFn : null, + whiteList : DefaultWhitelist + } - class Tooltip extends BaseComponent { - constructor(element, config) { - if (typeof Popper__namespace === 'undefined') { - throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)'); - } + Tooltip.prototype.init = function (type, element, options) { + this.enabled = true + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.$viewport = this.options.viewport && $(document).find($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) + this.inState = { click: false, hover: false, focus: false } - super(element, config); // Private - - this._isEnabled = true; - this._timeout = 0; - this._isHovered = null; - this._activeTrigger = {}; - this._popper = null; - this._templateFactory = null; - this._newContent = null; // Protected - - this.tip = null; - - this._setListeners(); - - if (!this._config.selector) { - this._fixTitle(); - } - } // Getters - - - static get Default() { - return Default$3; + if (this.$element[0] instanceof document.constructor && !this.options.selector) { + throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') } - static get DefaultType() { - return DefaultType$3; - } + var triggers = this.options.trigger.split(' ') - static get NAME() { - return NAME$4; - } // Public + for (var i = triggers.length; i--;) { + var trigger = triggers[i] + if (trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (trigger != 'manual') { + var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' + var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' - enable() { - this._isEnabled = true; - } - - disable() { - this._isEnabled = false; - } - - toggleEnabled() { - this._isEnabled = !this._isEnabled; - } - - toggle() { - if (!this._isEnabled) { - return; - } - - this._activeTrigger.click = !this._activeTrigger.click; - - if (this._isShown()) { - this._leave(); - - return; - } - - this._enter(); - } - - dispose() { - clearTimeout(this._timeout); - EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); - - if (this._element.getAttribute('data-bs-original-title')) { - this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title')); - } - - 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.eventName(EVENT_SHOW$2)); - const shadowRoot = findShadowRoot(this._element); - - const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element); - - if (showEvent.defaultPrevented || !isInTheDom) { - return; - } // todo v6 remove this OR make it optional - - - this._disposePopper(); - - const tip = this._getTipElement(); - - this._element.setAttribute('aria-describedby', tip.getAttribute('id')); - - const { - container - } = this._config; - - if (!this._element.ownerDocument.documentElement.contains(this.tip)) { - container.append(tip); - EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED)); - } - - this._popper = this._createPopper(tip); - tip.classList.add(CLASS_NAME_SHOW$2); // 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) { - for (const element of [].concat(...document.body.children)) { - EventHandler.on(element, 'mouseover', noop); - } - } - - const complete = () => { - EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2)); - - if (this._isHovered === false) { - this._leave(); - } - - this._isHovered = false; - }; - - this._queueCallback(complete, this.tip, this._isAnimated()); - } - - hide() { - if (!this._isShown()) { - return; - } - - const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2)); - - if (hideEvent.defaultPrevented) { - return; - } - - const tip = this._getTipElement(); - - 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) { - for (const element of [].concat(...document.body.children)) { - EventHandler.off(element, 'mouseover', noop); - } - } - - this._activeTrigger[TRIGGER_CLICK] = false; - this._activeTrigger[TRIGGER_FOCUS] = false; - this._activeTrigger[TRIGGER_HOVER] = false; - this._isHovered = null; // it is a trick to support manual triggering - - const complete = () => { - if (this._isWithActiveTrigger()) { - return; - } - - if (!this._isHovered) { - this._disposePopper(); - } - - this._element.removeAttribute('aria-describedby'); - - EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2)); - }; - - this._queueCallback(complete, this.tip, this._isAnimated()); - } - - update() { - if (this._popper) { - this._popper.update(); - } - } // Protected - - - _isWithContent() { - return Boolean(this._getTitle()); - } - - _getTipElement() { - if (!this.tip) { - this.tip = this._createTipElement(this._newContent || this._getContentForTemplate()); - } - - return this.tip; - } - - _createTipElement(content) { - const tip = this._getTemplateFactory(content).toHtml(); // todo: remove this check on v6 - - - if (!tip) { - return null; - } - - tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2); // todo: on v6 the following can be achieved with CSS only - - tip.classList.add(`bs-${this.constructor.NAME}-auto`); - const tipId = getUID(this.constructor.NAME).toString(); - tip.setAttribute('id', tipId); - - if (this._isAnimated()) { - tip.classList.add(CLASS_NAME_FADE$2); - } - - return tip; - } - - setContent(content) { - this._newContent = content; - - if (this._isShown()) { - this._disposePopper(); - - this.show(); + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) } } - _getTemplateFactory(content) { - if (this._templateFactory) { - this._templateFactory.changeContent(content); - } else { - this._templateFactory = new TemplateFactory({ ...this._config, - // the `content` var has to be after `this._config` - // to override config.content in case of popover - content, - extraClass: this._resolvePossibleFunction(this._config.customClass) - }); + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + Tooltip.prototype.getDefaults = function () { + return Tooltip.DEFAULTS + } + + Tooltip.prototype.getOptions = function (options) { + var dataAttributes = this.$element.data() + + for (var dataAttr in dataAttributes) { + if (dataAttributes.hasOwnProperty(dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) { + delete dataAttributes[dataAttr] + } + } + + options = $.extend({}, this.getDefaults(), dataAttributes, options) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay, + hide: options.delay + } + } + + if (options.sanitize) { + options.template = sanitizeHtml(options.template, options.whiteList, options.sanitizeFn) + } + + return options + } + + Tooltip.prototype.getDelegateOptions = function () { + var options = {} + var defaults = this.getDefaults() + + this._options && $.each(this._options, function (key, value) { + if (defaults[key] != value) options[key] = value + }) + + return options + } + + Tooltip.prototype.enter = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true + } + + if (self.tip().hasClass('in') || self.hoverState == 'in') { + self.hoverState = 'in' + return + } + + clearTimeout(self.timeout) + + self.hoverState = 'in' + + if (!self.options.delay || !self.options.delay.show) return self.show() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + Tooltip.prototype.isInStateTrue = function () { + for (var key in this.inState) { + if (this.inState[key]) return true + } + + return false + } + + Tooltip.prototype.leave = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false + } + + if (self.isInStateTrue()) return + + clearTimeout(self.timeout) + + self.hoverState = 'out' + + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + Tooltip.prototype.show = function () { + var e = $.Event('show.bs.' + this.type) + + if (this.hasContent() && this.enabled) { + this.$element.trigger(e) + + var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) + if (e.isDefaultPrevented() || !inDom) return + var that = this + + var $tip = this.tip() + + var tipId = this.getUID(this.type) + + this.setContent() + $tip.attr('id', tipId) + this.$element.attr('aria-describedby', tipId) + + if (this.options.animation) $tip.addClass('fade') + + var placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + var autoToken = /\s?auto?\s?/i + var autoPlace = autoToken.test(placement) + if (autoPlace) placement = placement.replace(autoToken, '') || 'top' + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + .addClass(placement) + .data('bs.' + this.type, this) + + this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) + this.$element.trigger('inserted.bs.' + this.type) + + var pos = this.getPosition() + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (autoPlace) { + var orgPlacement = placement + var viewportDim = this.getPosition(this.$viewport) + + placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : + placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : + placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : + placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : + placement + + $tip + .removeClass(orgPlacement) + .addClass(placement) } - return this._templateFactory; - } + var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) - _getContentForTemplate() { - return { - [SELECTOR_TOOLTIP_INNER]: this._getTitle() - }; - } + this.applyPlacement(calculatedOffset, placement) - _getTitle() { - return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title'); - } // Private + var complete = function () { + var prevHoverState = that.hoverState + that.$element.trigger('shown.bs.' + that.type) + that.hoverState = null - - _initializeOnDelegatedTarget(event) { - return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig()); - } - - _isAnimated() { - return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2); - } - - _isShown() { - return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2); - } - - _createPopper(tip) { - const placement = typeof this._config.placement === 'function' ? this._config.placement.call(this, tip, this._element) : this._config.placement; - const attachment = AttachmentMap[placement.toUpperCase()]; - return Popper__namespace.createPopper(this._element, tip, this._getPopperConfig(attachment)); - } - - _getOffset() { - const { - offset - } = this._config; - - if (typeof offset === 'string') { - return offset.split(',').map(value => Number.parseInt(value, 10)); + if (prevHoverState == 'out') that.leave(that) } - if (typeof offset === 'function') { - return popperData => offset(popperData, this._element); - } + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + } + } - return offset; + Tooltip.prototype.applyPlacement = function (offset, placement) { + var $tip = this.tip() + var width = $tip[0].offsetWidth + var height = $tip[0].offsetHeight + + // manually read margins because getBoundingClientRect includes difference + var marginTop = parseInt($tip.css('margin-top'), 10) + var marginLeft = parseInt($tip.css('margin-left'), 10) + + // we must check for NaN for ie 8/9 + if (isNaN(marginTop)) marginTop = 0 + if (isNaN(marginLeft)) marginLeft = 0 + + offset.top += marginTop + offset.left += marginLeft + + // $.fn.offset doesn't round pixel values + // so we use setOffset directly with our own function B-0 + $.offset.setOffset($tip[0], $.extend({ + using: function (props) { + $tip.css({ + top: Math.round(props.top), + left: Math.round(props.left) + }) + } + }, offset), 0) + + $tip.addClass('in') + + // check to see if placing tip in new offset caused the tip to resize itself + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (placement == 'top' && actualHeight != height) { + offset.top = offset.top + height - actualHeight } - _resolvePossibleFunction(arg) { - return typeof arg === 'function' ? arg.call(this._element) : arg; - } + var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) - _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: 'preSetPlacement', - enabled: true, - phase: 'beforeMain', - fn: data => { - // Pre-set Popper's placement attribute in order to read the arrow sizes properly. - // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement - this._getTipElement().setAttribute('data-popper-placement', data.state.placement); - } - }] - }; - return { ...defaultBsPopperConfig, - ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig) - }; - } + if (delta.left) offset.left += delta.left + else offset.top += delta.top - _setListeners() { - const triggers = this._config.trigger.split(' '); + var isVertical = /top|bottom/.test(placement) + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' - for (const trigger of triggers) { - if (trigger === 'click') { - EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => { - const context = this._initializeOnDelegatedTarget(event); + $tip.offset(offset) + this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) + } - context.toggle(); - }); - } else if (trigger !== TRIGGER_MANUAL) { - const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1); - const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1); - EventHandler.on(this._element, eventIn, this._config.selector, event => { - const context = this._initializeOnDelegatedTarget(event); + Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { + this.arrow() + .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') + .css(isVertical ? 'top' : 'left', '') + } - context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; + Tooltip.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() - context._enter(); - }); - EventHandler.on(this._element, eventOut, this._config.selector, event => { - const context = this._initializeOnDelegatedTarget(event); - - context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget); - - context._leave(); - }); - } + if (this.options.html) { + if (this.options.sanitize) { + title = sanitizeHtml(title, this.options.whiteList, this.options.sanitizeFn) } - this._hideModalHandler = () => { - if (this._element) { - this.hide(); - } - }; - - EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); + $tip.find('.tooltip-inner').html(title) + } else { + $tip.find('.tooltip-inner').text(title) } - _fixTitle() { - const title = this._element.getAttribute('title'); + $tip.removeClass('fade in top bottom left right') + } - if (!title) { - return; + Tooltip.prototype.hide = function (callback) { + var that = this + var $tip = $(this.$tip) + var e = $.Event('hide.bs.' + this.type) + + function complete() { + if (that.hoverState != 'in') $tip.detach() + if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. + that.$element + .removeAttr('aria-describedby') + .trigger('hidden.bs.' + that.type) } - - if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) { - this._element.setAttribute('aria-label', title); - } - - this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility - - - this._element.removeAttribute('title'); + callback && callback() } - _enter() { - if (this._isShown() || this._isHovered) { - this._isHovered = true; - return; - } + this.$element.trigger(e) - this._isHovered = true; + if (e.isDefaultPrevented()) return - this._setTimeout(() => { - if (this._isHovered) { - this.show(); - } - }, this._config.delay.show); + $tip.removeClass('in') + + $.support.transition && $tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + + this.hoverState = null + + return this + } + + Tooltip.prototype.fixTitle = function () { + var $e = this.$element + if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') } + } - _leave() { - if (this._isWithActiveTrigger()) { - return; - } + Tooltip.prototype.hasContent = function () { + return this.getTitle() + } - this._isHovered = false; + Tooltip.prototype.getPosition = function ($element) { + $element = $element || this.$element - this._setTimeout(() => { - if (!this._isHovered) { - this.hide(); - } - }, this._config.delay.hide); + var el = $element[0] + var isBody = el.tagName == 'BODY' + + var elRect = el.getBoundingClientRect() + if (elRect.width == null) { + // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 + elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) } + var isSvg = window.SVGElement && el instanceof window.SVGElement + // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. + // See https://github.com/twbs/bootstrap/issues/20280 + var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) + var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } + var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null - _setTimeout(handler, timeout) { - clearTimeout(this._timeout); - this._timeout = setTimeout(handler, timeout); - } + return $.extend({}, elRect, scroll, outerDims, elOffset) + } - _isWithActiveTrigger() { - return Object.values(this._activeTrigger).includes(true); - } - - _getConfig(config) { - const dataAttributes = Manipulator.getDataAttributes(this._element); - - for (const dataAttribute of Object.keys(dataAttributes)) { - if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) { - delete dataAttributes[dataAttribute]; - } - } - - config = { ...dataAttributes, - ...(typeof config === 'object' && config ? config : {}) - }; - config = this._mergeConfigObj(config); - config = this._configAfterMerge(config); - - this._typeCheckConfig(config); - - return config; - } - - _configAfterMerge(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(); - } - - return config; - } - - _getDelegateConfig() { - const config = {}; - - for (const key in this._config) { - if (this.constructor.Default[key] !== this._config[key]) { - config[key] = this._config[key]; - } - } - - config.selector = false; - config.trigger = 'manual'; // 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; - } - - _disposePopper() { - if (this._popper) { - this._popper.destroy(); - - this._popper = null; - } - - if (this.tip) { - this.tip.remove(); - this.tip = null; - } - } // Static - - - static jQueryInterface(config) { - return this.each(function () { - const data = Tooltip.getOrCreateInstance(this, config); - - if (typeof config !== 'string') { - return; - } - - if (typeof data[config] === 'undefined') { - throw new TypeError(`No method named "${config}"`); - } - - data[config](); - }); - } + Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { + return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : + /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } } - /** - * jQuery - */ + + Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { + var delta = { top: 0, left: 0 } + if (!this.$viewport) return delta + + var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 + var viewportDimensions = this.getPosition(this.$viewport) + + if (/right|left/.test(placement)) { + var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll + var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight + if (topEdgeOffset < viewportDimensions.top) { // top overflow + delta.top = viewportDimensions.top - topEdgeOffset + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset + } + } else { + var leftEdgeOffset = pos.left - viewportPadding + var rightEdgeOffset = pos.left + viewportPadding + actualWidth + if (leftEdgeOffset < viewportDimensions.left) { // left overflow + delta.left = viewportDimensions.left - leftEdgeOffset + } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset + } + } + + return delta + } + + Tooltip.prototype.getTitle = function () { + var title + var $e = this.$element + var o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + Tooltip.prototype.getUID = function (prefix) { + do prefix += ~~(Math.random() * 1000000) + while (document.getElementById(prefix)) + return prefix + } + + Tooltip.prototype.tip = function () { + if (!this.$tip) { + this.$tip = $(this.options.template) + if (this.$tip.length != 1) { + throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') + } + } + return this.$tip + } + + Tooltip.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) + } + + Tooltip.prototype.enable = function () { + this.enabled = true + } + + Tooltip.prototype.disable = function () { + this.enabled = false + } + + Tooltip.prototype.toggleEnabled = function () { + this.enabled = !this.enabled + } + + Tooltip.prototype.toggle = function (e) { + var self = this + if (e) { + self = $(e.currentTarget).data('bs.' + this.type) + if (!self) { + self = new this.constructor(e.currentTarget, this.getDelegateOptions()) + $(e.currentTarget).data('bs.' + this.type, self) + } + } + + if (e) { + self.inState.click = !self.inState.click + if (self.isInStateTrue()) self.enter(self) + else self.leave(self) + } else { + self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + } + } + + Tooltip.prototype.destroy = function () { + var that = this + clearTimeout(this.timeout) + this.hide(function () { + that.$element.off('.' + that.type).removeData('bs.' + that.type) + if (that.$tip) { + that.$tip.detach() + } + that.$tip = null + that.$arrow = null + that.$viewport = null + that.$element = null + }) + } + + Tooltip.prototype.sanitizeHtml = function (unsafeHtml) { + return sanitizeHtml(unsafeHtml, this.options.whiteList, this.options.sanitizeFn) + } + + // TOOLTIP PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tooltip') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tooltip + + $.fn.tooltip = Plugin + $.fn.tooltip.Constructor = Tooltip - defineJQueryPlugin(Tooltip); + // TOOLTIP NO CONFLICT + // =================== - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): popover.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ + $.fn.tooltip.noConflict = function () { + $.fn.tooltip = old + return this + } - const NAME$3 = 'popover'; - const SELECTOR_TITLE = '.popover-header'; - const SELECTOR_CONTENT = '.popover-body'; - const Default$2 = { ...Tooltip.Default, - content: '', - offset: [0, 8], +}(jQuery); + +/* ======================================================================== + * Bootstrap: popover.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#popovers + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // POPOVER PUBLIC CLASS DEFINITION + // =============================== + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') + + Popover.VERSION = '3.4.1' + + Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { placement: 'right', - template: '', - trigger: 'click' - }; - const DefaultType$2 = { ...Tooltip.DefaultType, - content: '(null|string|element|function)' - }; - /** - * Class definition - */ - - class Popover extends Tooltip { - // Getters - static get Default() { - return Default$2; - } - - static get DefaultType() { - return DefaultType$2; - } - - static get NAME() { - return NAME$3; - } // Overrides + trigger: 'click', + content: '', + template: '' + }) - _isWithContent() { - return this._getTitle() || this._getContent(); - } // Private + // NOTE: POPOVER EXTENDS tooltip.js + // ================================ + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) - _getContentForTemplate() { - return { - [SELECTOR_TITLE]: this._getTitle(), - [SELECTOR_CONTENT]: this._getContent() - }; - } - - _getContent() { - return this._resolvePossibleFunction(this._config.content); - } // Static - - - static jQueryInterface(config) { - return this.each(function () { - const data = Popover.getOrCreateInstance(this, config); - - if (typeof config !== 'string') { - return; - } - - if (typeof data[config] === 'undefined') { - throw new TypeError(`No method named "${config}"`); - } - - data[config](); - }); - } + Popover.prototype.constructor = Popover + Popover.prototype.getDefaults = function () { + return Popover.DEFAULTS } - /** - * jQuery - */ + Popover.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + var content = this.getContent() - defineJQueryPlugin(Popover); + if (this.options.html) { + var typeContent = typeof content - /** - * -------------------------------------------------------------------------- - * Bootstrap (v5.2.3): scrollspy.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - * -------------------------------------------------------------------------- - */ - /** - * Constants - */ + if (this.options.sanitize) { + title = this.sanitizeHtml(title) - const NAME$2 = 'scrollspy'; - const DATA_KEY$2 = 'bs.scrollspy'; - const EVENT_KEY$2 = `.${DATA_KEY$2}`; - const DATA_API_KEY = '.data-api'; - const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`; - const EVENT_CLICK = `click${EVENT_KEY$2}`; - const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`; - const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'; - const CLASS_NAME_ACTIVE$1 = 'active'; - const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]'; - const SELECTOR_TARGET_LINKS = '[href]'; - const SELECTOR_NAV_LIST_GROUP = '.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_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`; - const SELECTOR_DROPDOWN = '.dropdown'; - const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle'; - const Default$1 = { - offset: null, - // TODO: v6 @deprecated, keep it for backwards compatibility reasons - rootMargin: '0px 0px -25%', - smoothScroll: false, - target: null, - threshold: [0.1, 0.5, 1] - }; - const DefaultType$1 = { - offset: '(number|null)', - // TODO v6 @deprecated, keep it for backwards compatibility reasons - rootMargin: 'string', - smoothScroll: 'boolean', - target: 'element', - threshold: 'array' - }; - /** - * Class definition - */ + if (typeContent === 'string') { + content = this.sanitizeHtml(content) + } + } - class ScrollSpy extends BaseComponent { - constructor(element, config) { - super(element, config); // this._element is the observablesContainer and config.target the menu links wrapper - - this._targetLinks = new Map(); - this._observableSections = new Map(); - this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element; - this._activeTarget = null; - this._observer = null; - this._previousScrollData = { - visibleEntryTop: 0, - parentScrollTop: 0 - }; - this.refresh(); // initialize - } // Getters - - - static get Default() { - return Default$1; + $tip.find('.popover-title').html(title) + $tip.find('.popover-content').children().detach().end()[ + typeContent === 'string' ? 'html' : 'append' + ](content) + } else { + $tip.find('.popover-title').text(title) + $tip.find('.popover-content').children().detach().end().text(content) } - static get DefaultType() { - return DefaultType$1; + $tip.removeClass('fade top bottom left right in') + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() + } + + Popover.prototype.hasContent = function () { + return this.getTitle() || this.getContent() + } + + Popover.prototype.getContent = function () { + var $e = this.$element + var o = this.options + + return $e.attr('data-content') + || (typeof o.content == 'function' ? + o.content.call($e[0]) : + o.content) + } + + Popover.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.arrow')) + } + + + // POPOVER PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.popover') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.popover + + $.fn.popover = Plugin + $.fn.popover.Constructor = Popover + + + // POPOVER NO CONFLICT + // =================== + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: scrollspy.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#scrollspy + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // SCROLLSPY CLASS DEFINITION + // ========================== + + function ScrollSpy(element, options) { + this.$body = $(document.body) + this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) + this.options = $.extend({}, ScrollSpy.DEFAULTS, options) + this.selector = (this.options.target || '') + ' .nav li > a' + this.offsets = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 + + this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) + this.refresh() + this.process() + } + + ScrollSpy.VERSION = '3.4.1' + + ScrollSpy.DEFAULTS = { + offset: 10 + } + + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } + + ScrollSpy.prototype.refresh = function () { + var that = this + var offsetMethod = 'offset' + var offsetBase = 0 + + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() + + if (!$.isWindow(this.$scrollElement[0])) { + offsetMethod = 'position' + offsetBase = this.$scrollElement.scrollTop() } - static get NAME() { - return NAME$2; - } // Public + this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + that.offsets.push(this[0]) + that.targets.push(this[1]) + }) + } + + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } + + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) + && this.activate(targets[i]) + } + } + + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target + + this.clear() + + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + var active = $(selector) + .parents('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } + + active.trigger('activate.bs.scrollspy') + } + + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') + } - refresh() { - this._initializeTargetsAndObservables(); + // SCROLLSPY PLUGIN DEFINITION + // =========================== - this._maybeEnableSmoothScroll(); + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option - if (this._observer) { - this._observer.disconnect(); + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.scrollspy + + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy + + + // SCROLLSPY NO CONFLICT + // ===================== + + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } + + + // SCROLLSPY DATA-API + // ================== + + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tab.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#tabs + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TAB CLASS DEFINITION + // ==================== + + var Tab = function (element) { + // jscs:disable requireDollarBeforejQueryAssignment + this.element = $(element) + // jscs:enable requireDollarBeforejQueryAssignment + } + + Tab.VERSION = '3.4.1' + + Tab.TRANSITION_DURATION = 150 + + Tab.prototype.show = function () { + var $this = this.element + var $ul = $this.closest('ul:not(.dropdown-menu)') + var selector = $this.data('target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + if ($this.parent('li').hasClass('active')) return + + var $previous = $ul.find('.active:last a') + var hideEvent = $.Event('hide.bs.tab', { + relatedTarget: $this[0] + }) + var showEvent = $.Event('show.bs.tab', { + relatedTarget: $previous[0] + }) + + $previous.trigger(hideEvent) + $this.trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + var $target = $(document).find(selector) + + this.activate($this.closest('li'), $ul) + this.activate($target, $target.parent(), function () { + $previous.trigger({ + type: 'hidden.bs.tab', + relatedTarget: $this[0] + }) + $this.trigger({ + type: 'shown.bs.tab', + relatedTarget: $previous[0] + }) + }) + } + + Tab.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active') + var transition = callback + && $.support.transition + && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', false) + + element + .addClass('active') + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') } else { - this._observer = this._getNewObserver(); + element.removeClass('fade') } - for (const section of this._observableSections.values()) { - this._observer.observe(section); + if (element.parent('.dropdown-menu').length) { + element + .closest('li.dropdown') + .addClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) } + + callback && callback() } - dispose() { - this._observer.disconnect(); - - super.dispose(); - } // Private - - - _configAfterMerge(config) { - // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case - config.target = getElement(config.target) || document.body; // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only - - config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin; - - if (typeof config.threshold === 'string') { - config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value)); - } - - return config; - } - - _maybeEnableSmoothScroll() { - if (!this._config.smoothScroll) { - return; - } // unregister any previous listeners - - - EventHandler.off(this._config.target, EVENT_CLICK); - EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => { - const observableSection = this._observableSections.get(event.target.hash); - - if (observableSection) { - event.preventDefault(); - const root = this._rootElement || window; - const height = observableSection.offsetTop - this._element.offsetTop; - - if (root.scrollTo) { - root.scrollTo({ - top: height, - behavior: 'smooth' - }); - return; - } // Chrome 60 doesn't support `scrollTo` - - - root.scrollTop = height; - } - }); - } - - _getNewObserver() { - const options = { - root: this._rootElement, - threshold: this._config.threshold, - rootMargin: this._config.rootMargin - }; - return new IntersectionObserver(entries => this._observerCallback(entries), options); - } // The logic of selection - - - _observerCallback(entries) { - const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`); - - const activate = entry => { - this._previousScrollData.visibleEntryTop = entry.target.offsetTop; - - this._process(targetElement(entry)); - }; - - const parentScrollTop = (this._rootElement || document.documentElement).scrollTop; - const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop; - this._previousScrollData.parentScrollTop = parentScrollTop; - - for (const entry of entries) { - if (!entry.isIntersecting) { - this._activeTarget = null; - - this._clearActiveClass(targetElement(entry)); - - continue; - } - - const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; // if we are scrolling down, pick the bigger offsetTop - - if (userScrollsDown && entryIsLowerThanPrevious) { - activate(entry); // if parent isn't scrolled, let's keep the first visible item, breaking the iteration - - if (!parentScrollTop) { - return; - } - - continue; - } // if we are scrolling up, pick the smallest offsetTop - - - if (!userScrollsDown && !entryIsLowerThanPrevious) { - activate(entry); - } - } - } - - _initializeTargetsAndObservables() { - this._targetLinks = new Map(); - this._observableSections = new Map(); - const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target); - - for (const anchor of targetLinks) { - // ensure that the anchor has an id and is not disabled - if (!anchor.hash || isDisabled(anchor)) { - continue; - } - - const observableSection = SelectorEngine.findOne(anchor.hash, this._element); // ensure that the observableSection exists & is visible - - if (isVisible(observableSection)) { - this._targetLinks.set(anchor.hash, anchor); - - this._observableSections.set(anchor.hash, observableSection); - } - } - } - - _process(target) { - if (this._activeTarget === target) { - return; - } - - this._clearActiveClass(this._config.target); - - this._activeTarget = target; - target.classList.add(CLASS_NAME_ACTIVE$1); - - this._activateParents(target); - - EventHandler.trigger(this._element, EVENT_ACTIVATE, { - relatedTarget: target - }); - } - - _activateParents(target) { - // Activate dropdown parents - if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) { - SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1); - return; - } - - for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) { - // Set triggered links parents as active - // With both