1/*! 2 * Bootstrap tooltip.js (https://getbootstrap.com/) 3 * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 */ 6(function (global, factory) { 7 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core')) : 8 typeof define === 'function' && define.amd ? define(['@popperjs/core'], factory) : 9 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory(global.Popper)); 10}(this, (function (Popper) { 'use strict'; 11 12 function _interopNamespace(e) { 13 if (e && e.__esModule) return e; 14 var n = Object.create(null); 15 if (e) { 16 Object.keys(e).forEach(function (k) { 17 if (k !== 'default') { 18 var d = Object.getOwnPropertyDescriptor(e, k); 19 Object.defineProperty(n, k, d.get ? d : { 20 enumerable: true, 21 get: function () { 22 return e[k]; 23 } 24 }); 25 } 26 }); 27 } 28 n['default'] = e; 29 return Object.freeze(n); 30 } 31 32 var Popper__namespace = /*#__PURE__*/_interopNamespace(Popper); 33 34 /** 35 * ------------------------------------------------------------------------ 36 * Constants 37 * ------------------------------------------------------------------------ 38 */ 39 const NODE_TEXT = 3; 40 const SelectorEngine = { 41 find(selector, element = document.documentElement) { 42 return [].concat(...Element.prototype.querySelectorAll.call(element, selector)); 43 }, 44 45 findOne(selector, element = document.documentElement) { 46 return Element.prototype.querySelector.call(element, selector); 47 }, 48 49 children(element, selector) { 50 return [].concat(...element.children).filter(child => child.matches(selector)); 51 }, 52 53 parents(element, selector) { 54 const parents = []; 55 let ancestor = element.parentNode; 56 57 while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) { 58 if (ancestor.matches(selector)) { 59 parents.push(ancestor); 60 } 61 62 ancestor = ancestor.parentNode; 63 } 64 65 return parents; 66 }, 67 68 prev(element, selector) { 69 let previous = element.previousElementSibling; 70 71 while (previous) { 72 if (previous.matches(selector)) { 73 return [previous]; 74 } 75 76 previous = previous.previousElementSibling; 77 } 78 79 return []; 80 }, 81 82 next(element, selector) { 83 let next = element.nextElementSibling; 84 85 while (next) { 86 if (next.matches(selector)) { 87 return [next]; 88 } 89 90 next = next.nextElementSibling; 91 } 92 93 return []; 94 } 95 96 }; 97 98 /** 99 * -------------------------------------------------------------------------- 100 * Bootstrap (v5.0.2): util/index.js 101 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 102 * -------------------------------------------------------------------------- 103 */ 104 105 const MAX_UID = 1000000; 106 const MILLISECONDS_MULTIPLIER = 1000; 107 const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp) 108 109 const toType = obj => { 110 if (obj === null || obj === undefined) { 111 return `${obj}`; 112 } 113 114 return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase(); 115 }; 116 /** 117 * -------------------------------------------------------------------------- 118 * Public Util Api 119 * -------------------------------------------------------------------------- 120 */ 121 122 const getUID = prefix => { 123 do { 124 prefix += Math.floor(Math.random() * MAX_UID); 125 } while (document.getElementById(prefix)); 126 127 return prefix; 128 }; 129 130 const getTransitionDurationFromElement = element => { 131 if (!element) { 132 return 0; 133 } // Get transition-duration of the element 134 135 136 let { 137 transitionDuration, 138 transitionDelay 139 } = window.getComputedStyle(element); 140 const floatTransitionDuration = Number.parseFloat(transitionDuration); 141 const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found 142 143 if (!floatTransitionDuration && !floatTransitionDelay) { 144 return 0; 145 } // If multiple durations are defined, take the first 146 147 148 transitionDuration = transitionDuration.split(',')[0]; 149 transitionDelay = transitionDelay.split(',')[0]; 150 return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; 151 }; 152 153 const triggerTransitionEnd = element => { 154 element.dispatchEvent(new Event(TRANSITION_END)); 155 }; 156 157 const isElement = obj => { 158 if (!obj || typeof obj !== 'object') { 159 return false;
vendor: 16,050 bytes, lines 160-689
160 } 161 162 if (typeof obj.jquery !== 'undefined') { 163 obj = obj[0]; 164 } 165 166 return typeof obj.nodeType !== 'undefined'; 167 }; 168 169 const getElement = obj => { 170 if (isElement(obj)) { 171 // it's a jQuery object or a node element 172 return obj.jquery ? obj[0] : obj; 173 } 174 175 if (typeof obj === 'string' && obj.length > 0) { 176 return SelectorEngine.findOne(obj); 177 } 178 179 return null; 180 }; 181 182 const typeCheckConfig = (componentName, config, configTypes) => { 183 Object.keys(configTypes).forEach(property => { 184 const expectedTypes = configTypes[property]; 185 const value = config[property]; 186 const valueType = value && isElement(value) ? 'element' : toType(value); 187 188 if (!new RegExp(expectedTypes).test(valueType)) { 189 throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`); 190 } 191 }); 192 }; 193 194 const findShadowRoot = element => { 195 if (!document.documentElement.attachShadow) { 196 return null; 197 } // Can find the shadow root otherwise it'll return the document 198 199 200 if (typeof element.getRootNode === 'function') { 201 const root = element.getRootNode(); 202 return root instanceof ShadowRoot ? root : null; 203 } 204 205 if (element instanceof ShadowRoot) { 206 return element; 207 } // when we don't find a shadow root 208 209 210 if (!element.parentNode) { 211 return null; 212 } 213 214 return findShadowRoot(element.parentNode); 215 }; 216 217 const noop = () => {}; 218 219 const getjQuery = () => { 220 const { 221 jQuery 222 } = window; 223 224 if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) { 225 return jQuery; 226 } 227 228 return null; 229 }; 230 231 const isRTL = () => document.documentElement.dir === 'rtl'; 232 233 const execute = callback => { 234 if (typeof callback === 'function') { 235 callback(); 236 } 237 }; 238 239 const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => { 240 if (!waitForTransition) { 241 execute(callback); 242 return; 243 } 244 245 const durationPadding = 5; 246 const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding; 247 let called = false; 248 249 const handler = ({ 250 target 251 }) => { 252 if (target !== transitionElement) { 253 return; 254 } 255 256 called = true; 257 transitionElement.removeEventListener(TRANSITION_END, handler); 258 execute(callback); 259 }; 260 261 transitionElement.addEventListener(TRANSITION_END, handler); 262 setTimeout(() => { 263 if (!called) { 264 triggerTransitionEnd(transitionElement); 265 } 266 }, emulatedDuration); 267 }; 268 /** 269 * -------------------------------------------------------------------------- 270 * Bootstrap (v5.0.2): dom/event-handler.js 271 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 272 * -------------------------------------------------------------------------- 273 */ 274 /** 275 * ------------------------------------------------------------------------ 276 * Constants 277 * ------------------------------------------------------------------------ 278 */ 279 280 const namespaceRegex = /[^.]*(?=\..*)\.|.*/; 281 const stripNameRegex = /\..*/; 282 const stripUidRegex = /::\d+$/; 283 const eventRegistry = {}; // Events storage 284 285 let uidEvent = 1; 286 const customEvents = { 287 mouseenter: 'mouseover', 288 mouseleave: 'mouseout' 289 }; 290 const customEventsRegex = /^(mouseenter|mouseleave)/i; 291 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']); 292 /** 293 * ------------------------------------------------------------------------ 294 * Private methods 295 * ------------------------------------------------------------------------ 296 */ 297 298 function getUidEvent(element, uid) { 299 return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++; 300 } 301 302 function getEvent(element) { 303 const uid = getUidEvent(element); 304 element.uidEvent = uid; 305 eventRegistry[uid] = eventRegistry[uid] || {}; 306 return eventRegistry[uid]; 307 } 308 309 function bootstrapHandler(element, fn) { 310 return function handler(event) { 311 event.delegateTarget = element; 312 313 if (handler.oneOff) { 314 EventHandler.off(element, event.type, fn); 315 } 316 317 return fn.apply(element, [event]); 318 }; 319 } 320 321 function bootstrapDelegationHandler(element, selector, fn) { 322 return function handler(event) { 323 const domElements = element.querySelectorAll(selector); 324 325 for (let { 326 target 327 } = event; target && target !== this; target = target.parentNode) { 328 for (let i = domElements.length; i--;) { 329 if (domElements[i] === target) { 330 event.delegateTarget = target; 331 332 if (handler.oneOff) { 333 // eslint-disable-next-line unicorn/consistent-destructuring 334 EventHandler.off(element, event.type, selector, fn); 335 } 336 337 return fn.apply(target, [event]); 338 } 339 } 340 } // To please ESLint 341 342 343 return null; 344 }; 345 } 346 347 function findHandler(events, handler, delegationSelector = null) { 348 const uidEventList = Object.keys(events); 349 350 for (let i = 0, len = uidEventList.length; i < len; i++) { 351 const event = events[uidEventList[i]]; 352 353 if (event.originalHandler === handler && event.delegationSelector === delegationSelector) { 354 return event; 355 } 356 } 357 358 return null; 359 } 360 361 function normalizeParams(originalTypeEvent, handler, delegationFn) { 362 const delegation = typeof handler === 'string'; 363 const originalHandler = delegation ? delegationFn : handler; 364 let typeEvent = getTypeEvent(originalTypeEvent); 365 const isNative = nativeEvents.has(typeEvent); 366 367 if (!isNative) { 368 typeEvent = originalTypeEvent; 369 } 370 371 return [delegation, originalHandler, typeEvent]; 372 } 373 374 function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) { 375 if (typeof originalTypeEvent !== 'string' || !element) { 376 return; 377 } 378 379 if (!handler) { 380 handler = delegationFn; 381 delegationFn = null; 382 } // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position 383 // this prevents the handler from being dispatched the same way as mouseover or mouseout does 384 385 386 if (customEventsRegex.test(originalTypeEvent)) { 387 const wrapFn = fn => { 388 return function (event) { 389 if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) { 390 return fn.call(this, event); 391 } 392 }; 393 }; 394 395 if (delegationFn) { 396 delegationFn = wrapFn(delegationFn); 397 } else { 398 handler = wrapFn(handler); 399 } 400 } 401 402 const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn); 403 const events = getEvent(element); 404 const handlers = events[typeEvent] || (events[typeEvent] = {}); 405 const previousFn = findHandler(handlers, originalHandler, delegation ? handler : null); 406 407 if (previousFn) { 408 previousFn.oneOff = previousFn.oneOff && oneOff; 409 return; 410 } 411 412 const uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, '')); 413 const fn = delegation ? bootstrapDelegationHandler(element, handler, delegationFn) : bootstrapHandler(element, handler); 414 fn.delegationSelector = delegation ? handler : null; 415 fn.originalHandler = originalHandler; 416 fn.oneOff = oneOff; 417 fn.uidEvent = uid; 418 handlers[uid] = fn; 419 element.addEventListener(typeEvent, fn, delegation); 420 } 421 422 function removeHandler(element, events, typeEvent, handler, delegationSelector) { 423 const fn = findHandler(events[typeEvent], handler, delegationSelector); 424 425 if (!fn) { 426 return; 427 } 428 429 element.removeEventListener(typeEvent, fn, Boolean(delegationSelector)); 430 delete events[typeEvent][fn.uidEvent]; 431 } 432 433 function removeNamespacedHandlers(element, events, typeEvent, namespace) { 434 const storeElementEvent = events[typeEvent] || {}; 435 Object.keys(storeElementEvent).forEach(handlerKey => { 436 if (handlerKey.includes(namespace)) { 437 const event = storeElementEvent[handlerKey]; 438 removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector); 439 } 440 }); 441 } 442 443 function getTypeEvent(event) { 444 // allow to get the native events from namespaced events ('click.bs.button' --> 'click') 445 event = event.replace(stripNameRegex, ''); 446 return customEvents[event] || event; 447 } 448 449 const EventHandler = { 450 on(element, event, handler, delegationFn) { 451 addHandler(element, event, handler, delegationFn, false); 452 }, 453 454 one(element, event, handler, delegationFn) { 455 addHandler(element, event, handler, delegationFn, true); 456 }, 457 458 off(element, originalTypeEvent, handler, delegationFn) { 459 if (typeof originalTypeEvent !== 'string' || !element) { 460 return; 461 } 462 463 const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn); 464 const inNamespace = typeEvent !== originalTypeEvent; 465 const events = getEvent(element); 466 const isNamespace = originalTypeEvent.startsWith('.'); 467 468 if (typeof originalHandler !== 'undefined') { 469 // Simplest case: handler is passed, remove that listener ONLY. 470 if (!events || !events[typeEvent]) { 471 return; 472 } 473 474 removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null); 475 return; 476 } 477 478 if (isNamespace) { 479 Object.keys(events).forEach(elementEvent => { 480 removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1)); 481 }); 482 } 483 484 const storeElementEvent = events[typeEvent] || {}; 485 Object.keys(storeElementEvent).forEach(keyHandlers => { 486 const handlerKey = keyHandlers.replace(stripUidRegex, ''); 487 488 if (!inNamespace || originalTypeEvent.includes(handlerKey)) { 489 const event = storeElementEvent[keyHandlers]; 490 removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector); 491 } 492 }); 493 }, 494 495 trigger(element, event, args) { 496 if (typeof event !== 'string' || !element) { 497 return null; 498 } 499 500 const $ = getjQuery(); 501 const typeEvent = getTypeEvent(event); 502 const inNamespace = event !== typeEvent; 503 const isNative = nativeEvents.has(typeEvent); 504 let jQueryEvent; 505 let bubbles = true; 506 let nativeDispatch = true; 507 let defaultPrevented = false; 508 let evt = null; 509 510 if (inNamespace && $) { 511 jQueryEvent = $.Event(event, args); 512 $(element).trigger(jQueryEvent); 513 bubbles = !jQueryEvent.isPropagationStopped(); 514 nativeDispatch = !jQueryEvent.isImmediatePropagationStopped(); 515 defaultPrevented = jQueryEvent.isDefaultPrevented(); 516 } 517 518 if (isNative) { 519 evt = document.createEvent('HTMLEvents'); 520 evt.initEvent(typeEvent, bubbles, true); 521 } else { 522 evt = new CustomEvent(event, { 523 bubbles, 524 cancelable: true 525 }); 526 } // merge custom information in our event 527 528 529 if (typeof args !== 'undefined') { 530 Object.keys(args).forEach(key => { 531 Object.defineProperty(evt, key, { 532 get() { 533 return args[key]; 534 } 535 536 }); 537 }); 538 } 539 540 if (defaultPrevented) { 541 evt.preventDefault(); 542 } 543 544 if (nativeDispatch) { 545 element.dispatchEvent(evt); 546 } 547 548 if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') { 549 jQueryEvent.preventDefault(); 550 } 551 552 return evt; 553 } 554 555 }; 556 557 /** 558 * -------------------------------------------------------------------------- 559 * Bootstrap (v5.0.2): dom/data.js 560 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 561 * -------------------------------------------------------------------------- 562 */ 563 564 /** 565 * ------------------------------------------------------------------------ 566 * Constants 567 * ------------------------------------------------------------------------ 568 */ 569 const elementMap = new Map(); 570 var Data = { 571 set(element, key, instance) { 572 if (!elementMap.has(element)) { 573 elementMap.set(element, new Map()); 574 } 575 576 const instanceMap = elementMap.get(element); // make it clear we only want one instance per element 577 // can be removed later when multiple key/instances are fine to be used 578 579 if (!instanceMap.has(key) && instanceMap.size !== 0) { 580 // eslint-disable-next-line no-console 581 console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`); 582 return; 583 } 584 585 instanceMap.set(key, instance); 586 }, 587 588 get(element, key) { 589 if (elementMap.has(element)) { 590 return elementMap.get(element).get(key) || null; 591 } 592 593 return null; 594 }, 595 596 remove(element, key) { 597 if (!elementMap.has(element)) { 598 return; 599 } 600 601 const instanceMap = elementMap.get(element); 602 instanceMap.delete(key); // free up element references if there are no instances left for an element 603 604 if (instanceMap.size === 0) { 605 elementMap.delete(element); 606 } 607 } 608 609 }; 610 611 /** 612 * -------------------------------------------------------------------------- 613 * Bootstrap (v5.0.2): base-component.js 614 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 615 * -------------------------------------------------------------------------- 616 */ 617 /** 618 * ------------------------------------------------------------------------ 619 * Constants 620 * ------------------------------------------------------------------------ 621 */ 622 623 const VERSION = '5.0.2'; 624 625 class BaseComponent { 626 constructor(element) { 627 element = getElement(element); 628 629 if (!element) { 630 return; 631 } 632 633 this._element = element; 634 Data.set(this._element, this.constructor.DATA_KEY, this); 635 } 636 637 dispose() { 638 Data.remove(this._element, this.constructor.DATA_KEY); 639 EventHandler.off(this._element, this.constructor.EVENT_KEY); 640 Object.getOwnPropertyNames(this).forEach(propertyName => { 641 this[propertyName] = null; 642 }); 643 } 644 645 _queueCallback(callback, element, isAnimated = true) { 646 executeAfterTransition(callback, element, isAnimated); 647 } 648 /** Static */ 649 650 651 static getInstance(element) { 652 return Data.get(element, this.DATA_KEY); 653 } 654 655 static getOrCreateInstance(element, config = {}) { 656 return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null); 657 } 658 659 static get VERSION() { 660 return VERSION; 661 } 662 663 static get NAME() { 664 throw new Error('You have to implement the static method "NAME", for each component!'); 665 } 666 667 static get DATA_KEY() { 668 return `bs.${this.NAME}`; 669 } 670 671 static get EVENT_KEY() { 672 return `.${this.DATA_KEY}`; 673 } 674 675 } 676 677 /** 678 * -------------------------------------------------------------------------- 679 * Bootstrap (v5.0.2): dom/manipulator.js 680 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 681 * -------------------------------------------------------------------------- 682 */ 683 function normalizeData(val) { 684 if (val === 'true') { 685 return true; 686 } 687 688 if (val === 'false') { 689 return false;
690 } 691 692 if (val === Number(val).toString()) { 693 return Number(val); 694 } 695 696 if (val === '' || val === 'null') { 697 return null; 698 } 699 700 return val; 701 } 702 703 function normalizeDataKey(key) { 704 return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`); 705 } 706 707 const Manipulator = { 708 setDataAttribute(element, key, value) { 709 element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value); 710 }, 711 712 removeDataAttribute(element, key) { 713 element.removeAttribute(`data-bs-${normalizeDataKey(key)}`); 714 }, 715 716 getDataAttributes(element) { 717 if (!element) { 718 return {}; 719 } 720 721 const attributes = {}; 722 Object.keys(element.dataset).filter(key => key.startsWith('bs')).forEach(key => { 723 let pureKey = key.replace(/^bs/, ''); 724 pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length); 725 attributes[pureKey] = normalizeData(element.dataset[key]); 726 }); 727 return attributes; 728 }, 729 730 getDataAttribute(element, key) { 731 return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`)); 732 }, 733 734 offset(element) { 735 const rect = element.getBoundingClientRect(); 736 return { 737 top: rect.top + document.body.scrollTop, 738 left: rect.left + document.body.scrollLeft 739 }; 740 }, 741 742 position(element) { 743 return { 744 top: element.offsetTop, 745 left: element.offsetLeft 746 }; 747 } 748 749 }; 750 751 /** 752 * -------------------------------------------------------------------------- 753 * Bootstrap (v5.0.2): util/sanitizer.js 754 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 755 * -------------------------------------------------------------------------- 756 */ 757 const uriAttrs = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']); 758 const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; 759 760 const allowedAttribute = (attr, allowedAttributeList) => { 761 const attrName = attr.nodeName.toLowerCase(); 762 763 if (allowedAttributeList.includes(attrName)) { 764 if (uriAttrs.has(attrName)) { 765 return Boolean(SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue)); 766 } 767 768 return true; 769 } 770 771 const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp); // Check if a regular expression validates the attribute. 772 773 for (let i = 0, len = regExp.length; i < len; i++) { 774 if (regExp[i].test(attrName)) { 775 return true; 776 } 777 } 778 779 return false; 780 }; 781 782 const DefaultAllowlist = { 783 // Global attributes allowed on any supplied element below. 784 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], 785 a: ['target', 'href', 'title', 'rel'], 786 area: [], 787 b: [], 788 br: [], 789 col: [], 790 code: [], 791 div: [], 792 em: [], 793 hr: [], 794 h1: [], 795 h2: [], 796 h3: [], 797 h4: [], 798 h5: [], 799 h6: [], 800 i: [], 801 img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], 802 li: [], 803 ol: [], 804 p: [], 805 pre: [], 806 s: [], 807 small: [], 808 span: [], 809 sub: [], 810 sup: [], 811 strong: [], 812 u: [], 813 ul: [] 814 }; 815 function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) { 816 if (!unsafeHtml.length) { 817 return unsafeHtml; 818 } 819 820 if (sanitizeFn && typeof sanitizeFn === 'function') { 821 return sanitizeFn(unsafeHtml); 822 } 823 824 const domParser = new window.DOMParser(); 825 const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); 826 const allowlistKeys = Object.keys(allowList); 827 const elements = [].concat(...createdDocument.body.querySelectorAll('*')); 828 829 for (let i = 0, len = elements.length; i < len; i++) { 830 const el = elements[i]; 831 const elName = el.nodeName.toLowerCase(); 832 833 if (!allowlistKeys.includes(elName)) { 834 el.remove(); 835 continue; 836 } 837 838 const attributeList = [].concat(...el.attributes); 839 const allowedAttributes = [].concat(allowList['*'] || [], allowList[elName] || []); 840 attributeList.forEach(attr => { 841 if (!allowedAttribute(attr, allowedAttributes)) { 842 el.removeAttribute(attr.nodeName); 843 } 844 }); 845 } 846 847 return createdDocument.body.innerHTML; 848 } 849 850 /** 851 * -------------------------------------------------------------------------- 852 * Bootstrap (v5.0.2): tooltip.js 853 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 854 * -------------------------------------------------------------------------- 855 */ 856 /** 857 * ------------------------------------------------------------------------ 858 * Constants 859 * ------------------------------------------------------------------------ 860 */ 861 862 const NAME$4 = 'tooltip'; 863 const DATA_KEY$4 = 'bs.tooltip'; 864 const EVENT_KEY$4 = `.${DATA_KEY$4}`; 865 const CLASS_PREFIX$1 = 'bs-tooltip'; 866 const BSCLS_PREFIX_REGEX$1 = new RegExp(`(^|\\s)${CLASS_PREFIX$1}\\S+`, 'g'); 867 const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']); 868 const DefaultType$3 = { 869 animation: 'boolean', 870 template: 'string', 871 title: '(string|element|function)', 872 trigger: 'string', 873 delay: '(number|object)', 874 html: 'boolean', 875 selector: '(string|boolean)', 876 placement: '(string|function)', 877 offset: '(array|string|function)', 878 container: '(string|element|boolean)', 879 fallbackPlacements: 'array', 880 boundary: '(string|element)', 881 customClass: '(string|function)', 882 sanitize: 'boolean', 883 sanitizeFn: '(null|function)', 884 allowList: 'object', 885 popperConfig: '(null|object|function)' 886 }; 887 const AttachmentMap = { 888 AUTO: 'auto', 889 TOP: 'top', 890 RIGHT: isRTL() ? 'left' : 'right', 891 BOTTOM: 'bottom', 892 LEFT: isRTL() ? 'right' : 'left' 893 }; 894 const Default$3 = { 895 animation: true, 896 template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>', 897 trigger: 'hover focus', 898 title: '', 899 delay: 0, 900 html: false, 901 selector: false, 902 placement: 'top', 903 offset: [0, 0], 904 container: false, 905 fallbackPlacements: ['top', 'right', 'bottom', 'left'], 906 boundary: 'clippingParents', 907 customClass: '', 908 sanitize: true, 909 sanitizeFn: null, 910 allowList: DefaultAllowlist, 911 popperConfig: null 912 }; 913 const Event$2 = { 914 HIDE: `hide${EVENT_KEY$4}`, 915 HIDDEN: `hidden${EVENT_KEY$4}`, 916 SHOW: `show${EVENT_KEY$4}`, 917 SHOWN: `shown${EVENT_KEY$4}`, 918 INSERTED: `inserted${EVENT_KEY$4}`, 919 CLICK: `click${EVENT_KEY$4}`, 920 FOCUSIN: `focusin${EVENT_KEY$4}`, 921 FOCUSOUT: `focusout${EVENT_KEY$4}`, 922 MOUSEENTER: `mouseenter${EVENT_KEY$4}`, 923 MOUSELEAVE: `mouseleave${EVENT_KEY$4}` 924 }; 925 const CLASS_NAME_FADE$3 = 'fade';
926 const CLASS_NAME_MODAL = 'modal'; 927 const CLASS_NAME_SHOW$3 = 'show'; 928 const HOVER_STATE_SHOW = 'show'; 929 const HOVER_STATE_OUT = 'out'; 930 const SELECTOR_TOOLTIP_INNER = '.tooltip-inner'; 931 const TRIGGER_HOVER = 'hover'; 932 const TRIGGER_FOCUS = 'focus'; 933 const TRIGGER_CLICK = 'click'; 934 const TRIGGER_MANUAL = 'manual'; 935 /** 936 * ------------------------------------------------------------------------ 937 * Class Definition 938 * ------------------------------------------------------------------------ 939 */ 940 941 class Tooltip extends BaseComponent { 942 constructor(element, config) { 943 if (typeof Popper__namespace === 'undefined') { 944 throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)'); 945 } 946 947 super(element); // private 948 949 this._isEnabled = true; 950 this._timeout = 0; 951 this._hoverState = ''; 952 this._activeTrigger = {}; 953 this._popper = null; // Protected 954 955 this._config = this._getConfig(config); 956 this.tip = null; 957 958 this._setListeners(); 959 } // Getters 960 961 962 static get Default() { 963 return Default$3; 964 } 965 966 static get NAME() { 967 return NAME$4; 968 } 969 970 static get Event() { 971 return Event$2; 972 } 973 974 static get DefaultType() { 975 return DefaultType$3; 976 } // Public 977 978 979 enable() { 980 this._isEnabled = true; 981 } 982 983 disable() { 984 this._isEnabled = false; 985 } 986 987 toggleEnabled() { 988 this._isEnabled = !this._isEnabled; 989 } 990 991 toggle(event) { 992 if (!this._isEnabled) { 993 return; 994 } 995 996 if (event) { 997 const context = this._initializeOnDelegatedTarget(event); 998 999 context._activeTrigger.click = !context._activeTrigger.click; 1000 1001 if (context._isWithActiveTrigger()) { 1002 context._enter(null, context); 1003 } else { 1004 context._leave(null, context); 1005 } 1006 } else { 1007 if (this.getTipElement().classList.contains(CLASS_NAME_SHOW$3)) { 1008 this._leave(null, this); 1009 1010 return; 1011 } 1012 1013 this._enter(null, this); 1014 } 1015 } 1016 1017 dispose() { 1018 clearTimeout(this._timeout); 1019 EventHandler.off(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler); 1020 1021 if (this.tip) { 1022 this.tip.remove(); 1023 } 1024 1025 if (this._popper) { 1026 this._popper.destroy(); 1027 } 1028 1029 super.dispose(); 1030 } 1031 1032 show() { 1033 if (this._element.style.display === 'none') { 1034 throw new Error('Please use show on visible elements'); 1035 } 1036 1037 if (!(this.isWithContent() && this._isEnabled)) { 1038 return; 1039 } 1040 1041 const showEvent = EventHandler.trigger(this._element, this.constructor.Event.SHOW); 1042 const shadowRoot = findShadowRoot(this._element); 1043 const isInTheDom = shadowRoot === null ? this._element.ownerDocument.documentElement.contains(this._element) : shadowRoot.contains(this._element); 1044 1045 if (showEvent.defaultPrevented || !isInTheDom) { 1046 return; 1047 } 1048 1049 const tip = this.getTipElement(); 1050 const tipId = getUID(this.constructor.NAME);
1051 tip.setAttribute('id', tipId); 1052 1053 this._element.setAttribute('aria-describedby', tipId); 1054 1055 this.setContent(); 1056 1057 if (this._config.animation) { 1058 tip.classList.add(CLASS_NAME_FADE$3); 1059 } 1060 1061 const placement = typeof this._config.placement === 'function' ? this._config.placement.call(this, tip, this._element) : this._config.placement; 1062 1063 const attachment = this._getAttachment(placement); 1064 1065 this._addAttachmentClass(attachment); 1066 1067 const { 1068 container 1069 } = this._config; 1070 Data.set(tip, this.constructor.DATA_KEY, this); 1071 1072 if (!this._element.ownerDocument.documentElement.contains(this.tip)) { 1073 container.appendChild(tip); 1074 EventHandler.trigger(this._element, this.constructor.Event.INSERTED); 1075 } 1076 1077 if (this._popper) { 1078 this._popper.update(); 1079 } else { 1080 this._popper = Popper__namespace.createPopper(this._element, tip, this._getPopperConfig(attachment)); 1081 } 1082 1083 tip.classList.add(CLASS_NAME_SHOW$3); 1084 const customClass = typeof this._config.customClass === 'function' ? this._config.customClass() : this._config.customClass; 1085 1086 if (customClass) { 1087 tip.classList.add(...customClass.split(' ')); 1088 } // If this is a touch-enabled device we add extra 1089 // empty mouseover listeners to the body's immediate children; 1090 // only needed because of broken event delegation on iOS 1091 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 1092 1093 1094 if ('ontouchstart' in document.documentElement) { 1095 [].concat(...document.body.children).forEach(element => { 1096 EventHandler.on(element, 'mouseover', noop); 1097 }); 1098 } 1099 1100 const complete = () => { 1101 const prevHoverState = this._hoverState; 1102 this._hoverState = null; 1103 EventHandler.trigger(this._element, this.constructor.Event.SHOWN); 1104 1105 if (prevHoverState === HOVER_STATE_OUT) { 1106 this._leave(null, this); 1107 } 1108 }; 1109 1110 const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE$3); 1111 1112 this._queueCallback(complete, this.tip, isAnimated); 1113 } 1114 1115 hide() { 1116 if (!this._popper) { 1117 return; 1118 } 1119 1120 const tip = this.getTipElement(); 1121 1122 const complete = () => { 1123 if (this._isWithActiveTrigger()) { 1124 return; 1125 } 1126 1127 if (this._hoverState !== HOVER_STATE_SHOW) { 1128 tip.remove(); 1129 } 1130 1131 this._cleanTipClass(); 1132 1133 this._element.removeAttribute('aria-describedby'); 1134 1135 EventHandler.trigger(this._element, this.constructor.Event.HIDDEN); 1136 1137 if (this._popper) { 1138 this._popper.destroy(); 1139 1140 this._popper = null; 1141 } 1142 }; 1143 1144 const hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE); 1145 1146 if (hideEvent.defaultPrevented) { 1147 return; 1148 } 1149 1150 tip.classList.remove(CLASS_NAME_SHOW$3); // If this is a touch-enabled device we remove the extra 1151 // empty mouseover listeners we added for iOS support 1152 1153 if ('ontouchstart' in document.documentElement) { 1154 [].concat(...document.body.children).forEach(element => EventHandler.off(element, 'mouseover', noop)); 1155 } 1156 1157 this._activeTrigger[TRIGGER_CLICK] = false; 1158 this._activeTrigger[TRIGGER_FOCUS] = false; 1159 this._activeTrigger[TRIGGER_HOVER] = false; 1160 const isAnimated = this.tip.classList.contains(CLASS_NAME_FADE$3); 1161 1162 this._queueCallback(complete, this.tip, isAnimated); 1163 1164 this._hoverState = ''; 1165 } 1166 1167 update() { 1168 if (this._popper !== null) { 1169 this._popper.update(); 1170 } 1171 } // Protected 1172 1173 1174 isWithContent() { 1175 return Boolean(this.getTitle()); 1176 } 1177 1178 getTipElement() { 1179 if (this.tip) { 1180 return this.tip; 1181 } 1182 1183 const element = document.createElement('div'); 1184 element.innerHTML = this._config.template; 1185 this.tip = element.children[0]; 1186 return this.tip; 1187 } 1188 1189 setContent() { 1190 const tip = this.getTipElement(); 1191 this.setElementContent(SelectorEngine.findOne(SELECTOR_TOOLTIP_INNER, tip), this.getTitle()); 1192 tip.classList.remove(CLASS_NAME_FADE$3, CLASS_NAME_SHOW$3); 1193 } 1194 1195 setElementContent(element, content) { 1196 if (element === null) { 1197 return; 1198 } 1199 1200 if (isElement(content)) { 1201 content = getElement(content); // content is a DOM node or a jQuery 1202 1203 if (this._config.html) { 1204 if (content.parentNode !== element) { 1205 element.innerHTML = ''; 1206 element.appendChild(content); 1207 } 1208 } else { 1209 element.textContent = content.textContent; 1210 } 1211 1212 return; 1213 } 1214 1215 if (this._config.html) { 1216 if (this._config.sanitize) { 1217 content = sanitizeHtml(content, this._config.allowList, this._config.sanitizeFn); 1218 } 1219 1220 element.innerHTML = content; 1221 } else { 1222 element.textContent = content; 1223 } 1224 } 1225 1226 getTitle() { 1227 let title = this._element.getAttribute('data-bs-original-title'); 1228 1229 if (!title) { 1230 title = typeof this._config.title === 'function' ? this._config.title.call(this._element) : this._config.title; 1231 } 1232 1233 return title; 1234 } 1235 1236 updateAttachment(attachment) { 1237 if (attachment === 'right') { 1238 return 'end'; 1239 } 1240 1241 if (attachment === 'left') { 1242 return 'start'; 1243 } 1244 1245 return attachment; 1246 } // Private 1247 1248 1249 _initializeOnDelegatedTarget(event, context) { 1250 const dataKey = this.constructor.DATA_KEY; 1251 context = context || Data.get(event.delegateTarget, dataKey); 1252 1253 if (!context) { 1254 context = new this.constructor(event.delegateTarget, this._getDelegateConfig()); 1255 Data.set(event.delegateTarget, dataKey, context); 1256 } 1257 1258 return context; 1259 } 1260 1261 _getOffset() { 1262 const { 1263 offset 1264 } = this._config; 1265 1266 if (typeof offset === 'string') { 1267 return offset.split(',').map(val => Number.parseInt(val, 10)); 1268 } 1269 1270 if (typeof offset === 'function') { 1271 return popperData => offset(popperData, this._element); 1272 } 1273 1274 return offset; 1275 } 1276 1277 _getPopperConfig(attachment) { 1278 const defaultBsPopperConfig = { 1279 placement: attachment, 1280 modifiers: [{ 1281 name: 'flip', 1282 options: { 1283 fallbackPlacements: this._config.fallbackPlacements 1284 } 1285 }, { 1286 name: 'offset', 1287 options: { 1288 offset: this._getOffset() 1289 } 1290 }, { 1291 name: 'preventOverflow', 1292 options: {
1293 boundary: this._config.boundary 1294 } 1295 }, { 1296 name: 'arrow', 1297 options: { 1298 element: `.${this.constructor.NAME}-arrow` 1299 } 1300 }, { 1301 name: 'onChange', 1302 enabled: true, 1303 phase: 'afterWrite', 1304 fn: data => this._handlePopperPlacementChange(data) 1305 }], 1306 onFirstUpdate: data => { 1307 if (data.options.placement !== data.placement) { 1308 this._handlePopperPlacementChange(data); 1309 } 1310 } 1311 }; 1312 return { ...defaultBsPopperConfig, 1313 ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig) 1314 }; 1315 } 1316 1317 _addAttachmentClass(attachment) { 1318 this.getTipElement().classList.add(`${CLASS_PREFIX$1}-${this.updateAttachment(attachment)}`); 1319 } 1320 1321 _getAttachment(placement) { 1322 return AttachmentMap[placement.toUpperCase()]; 1323 } 1324 1325 _setListeners() { 1326 const triggers = this._config.trigger.split(' '); 1327 1328 triggers.forEach(trigger => { 1329 if (trigger === 'click') { 1330 EventHandler.on(this._element, this.constructor.Event.CLICK, this._config.selector, event => this.toggle(event)); 1331 } else if (trigger !== TRIGGER_MANUAL) { 1332 const eventIn = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSEENTER : this.constructor.Event.FOCUSIN; 1333 const eventOut = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSELEAVE : this.constructor.Event.FOCUSOUT; 1334 EventHandler.on(this._element, eventIn, this._config.selector, event => this._enter(event)); 1335 EventHandler.on(this._element, eventOut, this._config.selector, event => this._leave(event)); 1336 } 1337 }); 1338 1339 this._hideModalHandler = () => { 1340 if (this._element) { 1341 this.hide(); 1342 } 1343 }; 1344 1345 EventHandler.on(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler); 1346 1347 if (this._config.selector) { 1348 this._config = { ...this._config, 1349 trigger: 'manual', 1350 selector: '' 1351 }; 1352 } else { 1353 this._fixTitle(); 1354 } 1355 } 1356 1357 _fixTitle() { 1358 const title = this._element.getAttribute('title'); 1359 1360 const originalTitleType = typeof this._element.getAttribute('data-bs-original-title'); 1361 1362 if (title || originalTitleType !== 'string') { 1363 this._element.setAttribute('data-bs-original-title', title || ''); 1364 1365 if (title && !this._element.getAttribute('aria-label') && !this._element.textContent) { 1366 this._element.setAttribute('aria-label', title); 1367 } 1368 1369 this._element.setAttribute('title', ''); 1370 } 1371 } 1372 1373 _enter(event, context) { 1374 context = this._initializeOnDelegatedTarget(event, context); 1375 1376 if (event) { 1377 context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; 1378 } 1379 1380 if (context.getTipElement().classList.contains(CLASS_NAME_SHOW$3) || context._hoverState === HOVER_STATE_SHOW) { 1381 context._hoverState = HOVER_STATE_SHOW; 1382 return; 1383 } 1384 1385 clearTimeout(context._timeout); 1386 context._hoverState = HOVER_STATE_SHOW; 1387 1388 if (!context._config.delay || !context._config.delay.show) { 1389 context.show(); 1390 return; 1391 } 1392 1393 context._timeout = setTimeout(() => { 1394 if (context._hoverState === HOVER_STATE_SHOW) { 1395 context.show(); 1396 } 1397 }, context._config.delay.show); 1398 } 1399 1400 _leave(event, context) { 1401 context = this._initializeOnDelegatedTarget(event, context); 1402 1403 if (event) { 1404 context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget); 1405 } 1406 1407 if (context._isWithActiveTrigger()) { 1408 return; 1409 } 1410 1411 clearTimeout(context._timeout); 1412 context._hoverState = HOVER_STATE_OUT; 1413 1414 if (!context._config.delay || !context._config.delay.hide) { 1415 context.hide(); 1416 return; 1417 } 1418 1419 context._timeout = setTimeout(() => { 1420 if (context._hoverState === HOVER_STATE_OUT) { 1421 context.hide(); 1422 } 1423 }, context._config.delay.hide); 1424 } 1425 1426 _isWithActiveTrigger() { 1427 for (const trigger in this._activeTrigger) { 1428 if (this._activeTrigger[trigger]) { 1429 return true; 1430 } 1431 } 1432 1433 return false;
1434 } 1435 1436 _getConfig(config) { 1437 const dataAttributes = Manipulator.getDataAttributes(this._element); 1438 Object.keys(dataAttributes).forEach(dataAttr => { 1439 if (DISALLOWED_ATTRIBUTES.has(dataAttr)) { 1440 delete dataAttributes[dataAttr]; 1441 } 1442 }); 1443 config = { ...this.constructor.Default, 1444 ...dataAttributes, 1445 ...(typeof config === 'object' && config ? config : {}) 1446 }; 1447 config.container = config.container === false ? document.body : getElement(config.container); 1448 1449 if (typeof config.delay === 'number') { 1450 config.delay = { 1451 show: config.delay, 1452 hide: config.delay 1453 }; 1454 } 1455 1456 if (typeof config.title === 'number') { 1457 config.title = config.title.toString(); 1458 } 1459 1460 if (typeof config.content === 'number') { 1461 config.content = config.content.toString(); 1462 } 1463 1464 typeCheckConfig(NAME$4, config, this.constructor.DefaultType); 1465 1466 if (config.sanitize) { 1467 config.template = sanitizeHtml(config.template, config.allowList, config.sanitizeFn); 1468 } 1469 1470 return config; 1471 } 1472 1473 _getDelegateConfig() { 1474 const config = {}; 1475 1476 if (this._config) { 1477 for (const key in this._config) { 1478 if (this.constructor.Default[key] !== this._config[key]) { 1479 config[key] = this._config[key]; 1480 } 1481 } 1482 } 1483 1484 return config; 1485 } 1486 1487 _cleanTipClass() { 1488 const tip = this.getTipElement(); 1489 const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX$1); 1490 1491 if (tabClass !== null && tabClass.length > 0) { 1492 tabClass.map(token => token.trim()).forEach(tClass => tip.classList.remove(tClass)); 1493 } 1494 } 1495 1496 _handlePopperPlacementChange(popperData) { 1497 const { 1498 state 1499 } = popperData; 1500 1501 if (!state) { 1502 return; 1503 } 1504 1505 this.tip = state.elements.popper; 1506 1507 this._cleanTipClass(); 1508 1509 this._addAttachmentClass(this._getAttachment(state.placement)); 1510 } // Static 1511 1512 static jQueryInterface(config) { 1513 return this.each(function () { 1514 const data = Tooltip.getOrCreateInstance(this, config); 1515 1516 if (typeof config === 'string') { 1517 if (typeof data[config] === 'undefined') { 1518 throw new TypeError(`No method named "${config}"`); 1519 } 1520 1521 data[config](); 1522 } 1523 }); 1524 } 1525 1526 } 1527 1528 /** 1529 * -------------------------------------------------------------------------- 1530 * Bootstrap (v5.0.2): index.umd.js 1531 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 1532 * -------------------------------------------------------------------------- 1533 */ 1534 var index_umd = { 1535 Tooltip 1536 }; 1537 1538 return index_umd; 1539 1540}))); 1541//# sourceMappingURL=bootstrap.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.