margin\n /* istanbul ignore next: difficult to test in JSDOM */\n selectAll(Selector.NAVBAR_TOGGLER).forEach(el => /* istanbul ignore next */ {\n const actualMargin = el.style.marginRight\n setAttr(el, 'data-margin-right', actualMargin)\n el.style.marginRight = `${toFloat(getCS(el).marginRight, 0) + scrollbarWidth}px`\n body._marginChangedForModal.push(el)\n })\n // Adjust body padding\n const actualPadding = body.style.paddingRight\n setAttr(body, 'data-padding-right', actualPadding)\n body.style.paddingRight = `${toFloat(getCS(body).paddingRight, 0) + scrollbarWidth}px`\n }\n },\n resetScrollbar() {\n const body = document.body\n if (body._paddingChangedForModal) {\n // Restore fixed content padding\n body._paddingChangedForModal.forEach(el => {\n /* istanbul ignore next: difficult to test in JSDOM */\n if (hasAttr(el, 'data-padding-right')) {\n el.style.paddingRight = getAttr(el, 'data-padding-right') || ''\n removeAttr(el, 'data-padding-right')\n }\n })\n }\n if (body._marginChangedForModal) {\n // Restore sticky content and navbar-toggler margin\n body._marginChangedForModal.forEach(el => {\n /* istanbul ignore next: difficult to test in JSDOM */\n if (hasAttr(el, 'data-margin-right')) {\n el.style.marginRight = getAttr(el, 'data-margin-right') || ''\n removeAttr(el, 'data-margin-right')\n }\n })\n }\n body._paddingChangedForModal = null\n body._marginChangedForModal = null\n // Restore body padding\n if (hasAttr(body, 'data-padding-right')) {\n body.style.paddingRight = getAttr(body, 'data-padding-right') || ''\n removeAttr(body, 'data-padding-right')\n }\n }\n }\n})\n\n// Create and export our modal manager instance\nexport const modalManager = new ModalManager()\n","import { BvEvent } from '../../../utils/bv-event.class'\nimport { defineProperties, readonlyDescriptor } from '../../../utils/object'\n\nclass BvModalEvent extends BvEvent {\n constructor(type, eventInit = {}) {\n super(type, eventInit)\n // Freeze our new props as readonly, but leave them enumerable\n defineProperties(this, {\n trigger: readonlyDescriptor()\n })\n }\n\n static get Defaults() {\n return {\n ...super.Defaults,\n trigger: null\n }\n }\n}\n\n// Named exports\nexport { BvModalEvent }\n","import Vue from '../../utils/vue'\nimport BVTransition from '../../utils/bv-transition'\nimport KeyCodes from '../../utils/key-codes'\nimport identity from '../../utils/identity'\nimport observeDom from '../../utils/observe-dom'\nimport { arrayIncludes, concat } from '../../utils/array'\nimport { getComponentConfig } from '../../utils/config'\nimport {\n attemptFocus,\n closest,\n contains,\n getActiveElement,\n getTabables,\n requestAF,\n select\n} from '../../utils/dom'\nimport { isBrowser } from '../../utils/env'\nimport { EVENT_OPTIONS_NO_CAPTURE, eventOn, eventOff } from '../../utils/events'\nimport { htmlOrText } from '../../utils/html'\nimport { isString, isUndefinedOrNull } from '../../utils/inspect'\nimport { HTMLElement } from '../../utils/safe-types'\nimport { BTransporterSingle } from '../../utils/transporter'\nimport attrsMixin from '../../mixins/attrs'\nimport idMixin from '../../mixins/id'\nimport listenOnDocumentMixin from '../../mixins/listen-on-document'\nimport listenOnRootMixin from '../../mixins/listen-on-root'\nimport listenOnWindowMixin from '../../mixins/listen-on-window'\nimport normalizeSlotMixin from '../../mixins/normalize-slot'\nimport scopedStyleAttrsMixin from '../../mixins/scoped-style-attrs'\nimport { BButton } from '../button/button'\nimport { BButtonClose } from '../button/button-close'\nimport { modalManager } from './helpers/modal-manager'\nimport { BvModalEvent } from './helpers/bv-modal-event.class'\n\n// --- Constants ---\n\nconst NAME = 'BModal'\n\n// ObserveDom config to detect changes in modal content\n// so that we can adjust the modal padding if needed\nconst OBSERVER_CONFIG = {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['style', 'class']\n}\n\n// --- Props ---\nexport const props = {\n size: {\n type: String,\n default: () => getComponentConfig(NAME, 'size')\n },\n centered: {\n type: Boolean,\n default: false\n },\n scrollable: {\n type: Boolean,\n default: false\n },\n buttonSize: {\n type: String\n // default: ''\n },\n noStacking: {\n type: Boolean,\n default: false\n },\n noFade: {\n type: Boolean,\n default: false\n },\n noCloseOnBackdrop: {\n type: Boolean,\n default: false\n },\n noCloseOnEsc: {\n type: Boolean,\n default: false\n },\n noEnforceFocus: {\n type: Boolean,\n default: false\n },\n ignoreEnforceFocusSelector: {\n type: [Array, String],\n default: ''\n },\n title: {\n type: String,\n default: ''\n },\n titleHtml: {\n type: String\n },\n titleTag: {\n type: String,\n default: () => getComponentConfig(NAME, 'titleTag')\n },\n titleClass: {\n type: [String, Array, Object]\n // default: null\n },\n titleSrOnly: {\n type: Boolean,\n default: false\n },\n ariaLabel: {\n type: String\n // default: null\n },\n headerBgVariant: {\n type: String,\n default: () => getComponentConfig(NAME, 'headerBgVariant')\n },\n headerBorderVariant: {\n type: String,\n default: () => getComponentConfig(NAME, 'headerBorderVariant')\n },\n headerTextVariant: {\n type: String,\n default: () => getComponentConfig(NAME, 'headerTextVariant')\n },\n headerCloseVariant: {\n type: String,\n default: () => getComponentConfig(NAME, 'headerCloseVariant')\n },\n headerClass: {\n type: [String, Array, Object]\n // default: null\n },\n bodyBgVariant: {\n type: String,\n default: () => getComponentConfig(NAME, 'bodyBgVariant')\n },\n bodyTextVariant: {\n type: String,\n default: () => getComponentConfig(NAME, 'bodyTextVariant')\n },\n modalClass: {\n type: [String, Array, Object]\n // default: null\n },\n dialogClass: {\n type: [String, Array, Object]\n // default: null\n },\n contentClass: {\n type: [String, Array, Object]\n // default: null\n },\n bodyClass: {\n type: [String, Array, Object]\n // default: null\n },\n footerBgVariant: {\n type: String,\n default: () => getComponentConfig(NAME, 'footerBgVariant')\n },\n footerBorderVariant: {\n type: String,\n default: () => getComponentConfig(NAME, 'footerBorderVariant')\n },\n footerTextVariant: {\n type: String,\n default: () => getComponentConfig(NAME, 'footerTextVariant')\n },\n footerClass: {\n type: [String, Array, Object]\n // default: null\n },\n // TODO: Rename to `noHeader` and deprecate `hideHeader`\n hideHeader: {\n type: Boolean,\n default: false\n },\n // TODO: Rename to `noFooter` and deprecate `hideFooter`\n hideFooter: {\n type: Boolean,\n default: false\n },\n // TODO: Rename to `noHeaderClose` and deprecate `hideHeaderClose`\n hideHeaderClose: {\n type: Boolean,\n default: false\n },\n // TODO: Rename to `noBackdrop` and deprecate `hideBackdrop`\n hideBackdrop: {\n type: Boolean,\n default: false\n },\n okOnly: {\n type: Boolean,\n default: false\n },\n okDisabled: {\n type: Boolean,\n default: false\n },\n cancelDisabled: {\n type: Boolean,\n default: false\n },\n visible: {\n type: Boolean,\n default: false\n },\n returnFocus: {\n // HTML Element, CSS selector string or Vue component instance\n type: [HTMLElement, String, Object],\n default: null\n },\n headerCloseContent: {\n type: String,\n default: () => getComponentConfig(NAME, 'headerCloseContent')\n },\n headerCloseLabel: {\n type: String,\n default: () => getComponentConfig(NAME, 'headerCloseLabel')\n },\n cancelTitle: {\n type: String,\n default: () => getComponentConfig(NAME, 'cancelTitle')\n },\n cancelTitleHtml: {\n type: String\n },\n okTitle: {\n type: String,\n default: () => getComponentConfig(NAME, 'okTitle')\n },\n okTitleHtml: {\n type: String\n },\n cancelVariant: {\n type: String,\n default: () => getComponentConfig(NAME, 'cancelVariant')\n },\n okVariant: {\n type: String,\n default: () => getComponentConfig(NAME, 'okVariant')\n },\n lazy: {\n type: Boolean,\n default: false\n },\n busy: {\n type: Boolean,\n default: false\n },\n static: {\n type: Boolean,\n default: false\n },\n autoFocusButton: {\n type: String,\n default: null,\n validator /* istanbul ignore next */: val => {\n /* istanbul ignore next */\n return isUndefinedOrNull(val) || arrayIncludes(['ok', 'cancel', 'close'], val)\n }\n }\n}\n\n// @vue/component\nexport const BModal = /*#__PURE__*/ Vue.extend({\n name: NAME,\n mixins: [\n attrsMixin,\n idMixin,\n listenOnDocumentMixin,\n listenOnRootMixin,\n listenOnWindowMixin,\n normalizeSlotMixin,\n scopedStyleAttrsMixin\n ],\n inheritAttrs: false,\n model: {\n prop: 'visible',\n event: 'change'\n },\n props,\n data() {\n return {\n isHidden: true, // If modal should not be in document\n isVisible: false, // Controls modal visible state\n isTransitioning: false, // Used for style control\n isShow: false, // Used for style control\n isBlock: false, // Used for style control\n isOpening: false, // To signal that the modal is in the process of opening\n isClosing: false, // To signal that the modal is in the process of closing\n ignoreBackdropClick: false, // Used to signify if click out listener should ignore the click\n isModalOverflowing: false,\n return_focus: this.returnFocus || null,\n // The following items are controlled by the modalManager instance\n scrollbarWidth: 0,\n zIndex: modalManager.getBaseZIndex(),\n isTop: true,\n isBodyOverflowing: false\n }\n },\n computed: {\n modalId() {\n return this.safeId()\n },\n modalOuterId() {\n return this.safeId('__BV_modal_outer_')\n },\n modalHeaderId() {\n return this.safeId('__BV_modal_header_')\n },\n modalBodyId() {\n return this.safeId('__BV_modal_body_')\n },\n modalTitleId() {\n return this.safeId('__BV_modal_title_')\n },\n modalContentId() {\n return this.safeId('__BV_modal_content_')\n },\n modalFooterId() {\n return this.safeId('__BV_modal_footer_')\n },\n modalBackdropId() {\n return this.safeId('__BV_modal_backdrop_')\n },\n modalClasses() {\n return [\n {\n fade: !this.noFade,\n show: this.isShow\n },\n this.modalClass\n ]\n },\n modalStyles() {\n const sbWidth = `${this.scrollbarWidth}px`\n return {\n paddingLeft: !this.isBodyOverflowing && this.isModalOverflowing ? sbWidth : '',\n paddingRight: this.isBodyOverflowing && !this.isModalOverflowing ? sbWidth : '',\n // Needed to fix issue https://github.com/bootstrap-vue/bootstrap-vue/issues/3457\n // Even though we are using v-show, we must ensure 'none' is restored in the styles\n display: this.isBlock ? 'block' : 'none'\n }\n },\n dialogClasses() {\n return [\n {\n [`modal-${this.size}`]: this.size,\n 'modal-dialog-centered': this.centered,\n 'modal-dialog-scrollable': this.scrollable\n },\n this.dialogClass\n ]\n },\n headerClasses() {\n return [\n {\n [`bg-${this.headerBgVariant}`]: this.headerBgVariant,\n [`text-${this.headerTextVariant}`]: this.headerTextVariant,\n [`border-${this.headerBorderVariant}`]: this.headerBorderVariant\n },\n this.headerClass\n ]\n },\n titleClasses() {\n return [{ 'sr-only': this.titleSrOnly }, this.titleClass]\n },\n bodyClasses() {\n return [\n {\n [`bg-${this.bodyBgVariant}`]: this.bodyBgVariant,\n [`text-${this.bodyTextVariant}`]: this.bodyTextVariant\n },\n this.bodyClass\n ]\n },\n footerClasses() {\n return [\n {\n [`bg-${this.footerBgVariant}`]: this.footerBgVariant,\n [`text-${this.footerTextVariant}`]: this.footerTextVariant,\n [`border-${this.footerBorderVariant}`]: this.footerBorderVariant\n },\n this.footerClass\n ]\n },\n modalOuterStyle() {\n // Styles needed for proper stacking of modals\n return {\n position: 'absolute',\n zIndex: this.zIndex\n }\n },\n slotScope() {\n return {\n ok: this.onOk,\n cancel: this.onCancel,\n close: this.onClose,\n hide: this.hide,\n visible: this.isVisible\n }\n },\n computeIgnoreEnforceFocusSelector() {\n // Normalize to an single selector with selectors separated by `,`\n return concat(this.ignoreEnforceFocusSelector)\n .filter(identity)\n .join(',')\n .trim()\n },\n computedAttrs() {\n // If the parent has a scoped style attribute, and the modal\n // is portalled, add the scoped attribute to the modal wrapper\n const scopedStyleAttrs = !this.static ? this.scopedStyleAttrs : {}\n\n return {\n ...scopedStyleAttrs,\n ...this.bvAttrs,\n id: this.modalOuterId\n }\n },\n computedModalAttrs() {\n const { isVisible, ariaLabel } = this\n\n return {\n id: this.modalId,\n role: 'dialog',\n 'aria-hidden': isVisible ? null : 'true',\n 'aria-modal': isVisible ? 'true' : null,\n 'aria-label': ariaLabel,\n 'aria-labelledby':\n this.hideHeader ||\n ariaLabel ||\n // TODO: Rename slot to `title` and deprecate `modal-title`\n !(this.hasNormalizedSlot('modal-title') || this.titleHtml || this.title)\n ? null\n : this.modalTitleId,\n 'aria-describedby': this.modalBodyId\n }\n }\n },\n watch: {\n visible(newVal, oldVal) {\n if (newVal !== oldVal) {\n this[newVal ? 'show' : 'hide']()\n }\n }\n },\n created() {\n // Define non-reactive properties\n this.$_observer = null\n },\n mounted() {\n // Set initial z-index as queried from the DOM\n this.zIndex = modalManager.getBaseZIndex()\n // Listen for events from others to either open or close ourselves\n // and listen to all modals to enable/disable enforce focus\n this.listenOnRoot('bv::show::modal', this.showHandler)\n this.listenOnRoot('bv::hide::modal', this.hideHandler)\n this.listenOnRoot('bv::toggle::modal', this.toggleHandler)\n // Listen for `bv:modal::show events`, and close ourselves if the\n // opening modal not us\n this.listenOnRoot('bv::modal::show', this.modalListener)\n // Initially show modal?\n if (this.visible === true) {\n this.$nextTick(this.show)\n }\n },\n beforeDestroy() {\n // Ensure everything is back to normal\n this.setObserver(false)\n if (this.isVisible) {\n this.isVisible = false\n this.isShow = false\n this.isTransitioning = false\n }\n },\n methods: {\n setObserver(on = false) {\n this.$_observer && this.$_observer.disconnect()\n this.$_observer = null\n if (on) {\n this.$_observer = observeDom(\n this.$refs.content,\n this.checkModalOverflow.bind(this),\n OBSERVER_CONFIG\n )\n }\n },\n // Private method to update the v-model\n updateModel(val) {\n if (val !== this.visible) {\n this.$emit('change', val)\n }\n },\n // Private method to create a BvModalEvent object\n buildEvent(type, options = {}) {\n return new BvModalEvent(type, {\n // Default options\n cancelable: false,\n target: this.$refs.modal || this.$el || null,\n relatedTarget: null,\n trigger: null,\n // Supplied options\n ...options,\n // Options that can't be overridden\n vueTarget: this,\n componentId: this.modalId\n })\n },\n // Public method to show modal\n show() {\n if (this.isVisible || this.isOpening) {\n // If already open, or in the process of opening, do nothing\n /* istanbul ignore next */\n return\n }\n /* istanbul ignore next */\n if (this.isClosing) {\n // If we are in the process of closing, wait until hidden before re-opening\n /* istanbul ignore next */\n this.$once('hidden', this.show)\n /* istanbul ignore next */\n return\n }\n this.isOpening = true\n // Set the element to return focus to when closed\n this.return_focus = this.return_focus || this.getActiveElement()\n const showEvt = this.buildEvent('show', {\n cancelable: true\n })\n this.emitEvent(showEvt)\n // Don't show if canceled\n if (showEvt.defaultPrevented || this.isVisible) {\n this.isOpening = false\n // Ensure the v-model reflects the current state\n this.updateModel(false)\n return\n }\n // Show the modal\n this.doShow()\n },\n // Public method to hide modal\n hide(trigger = '') {\n if (!this.isVisible || this.isClosing) {\n /* istanbul ignore next */\n return\n }\n this.isClosing = true\n const hideEvt = this.buildEvent('hide', {\n cancelable: trigger !== 'FORCE',\n trigger: trigger || null\n })\n // We emit specific event for one of the three built-in buttons\n if (trigger === 'ok') {\n this.$emit('ok', hideEvt)\n } else if (trigger === 'cancel') {\n this.$emit('cancel', hideEvt)\n } else if (trigger === 'headerclose') {\n this.$emit('close', hideEvt)\n }\n this.emitEvent(hideEvt)\n // Hide if not canceled\n if (hideEvt.defaultPrevented || !this.isVisible) {\n this.isClosing = false\n // Ensure v-model reflects current state\n this.updateModel(true)\n return\n }\n // Stop observing for content changes\n this.setObserver(false)\n // Trigger the hide transition\n this.isVisible = false\n // Update the v-model\n this.updateModel(false)\n },\n // Public method to toggle modal visibility\n toggle(triggerEl) {\n if (triggerEl) {\n this.return_focus = triggerEl\n }\n if (this.isVisible) {\n this.hide('toggle')\n } else {\n this.show()\n }\n },\n // Private method to get the current document active element\n getActiveElement() {\n // Returning focus to `document.body` may cause unwanted scrolls,\n // so we exclude setting focus on body\n const activeElement = getActiveElement(isBrowser ? [document.body] : [])\n // Preset the fallback return focus value if it is not set\n // `document.activeElement` should be the trigger element that was clicked or\n // in the case of using the v-model, which ever element has current focus\n // Will be overridden by some commands such as toggle, etc.\n // Note: On IE 11, `document.activeElement` may be `null`\n // So we test it for truthiness first\n // https://github.com/bootstrap-vue/bootstrap-vue/issues/3206\n return activeElement && activeElement.focus ? activeElement : null\n },\n // Private method to finish showing modal\n doShow() {\n /* istanbul ignore next: commenting out for now until we can test stacking */\n if (modalManager.modalsAreOpen && this.noStacking) {\n // If another modal(s) is already open, wait for it(them) to close\n this.listenOnRootOnce('bv::modal::hidden', this.doShow)\n return\n }\n modalManager.registerModal(this)\n // Place modal in DOM\n this.isHidden = false\n this.$nextTick(() => {\n // We do this in `$nextTick()` to ensure the modal is in DOM first\n // before we show it\n this.isVisible = true\n this.isOpening = false\n // Update the v-model\n this.updateModel(true)\n this.$nextTick(() => {\n // Observe changes in modal content and adjust if necessary\n // In a `$nextTick()` in case modal content is lazy\n this.setObserver(true)\n })\n })\n },\n // Transition handlers\n onBeforeEnter() {\n this.isTransitioning = true\n this.setResizeEvent(true)\n },\n onEnter() {\n this.isBlock = true\n // We add the `show` class 1 frame later\n // `requestAF()` runs the callback before the next repaint, so we need\n // two calls to guarantee the next frame has been rendered\n requestAF(() => {\n requestAF(() => {\n this.isShow = true\n })\n })\n },\n onAfterEnter() {\n this.checkModalOverflow()\n this.isTransitioning = false\n // We use `requestAF()` to allow transition hooks to complete\n // before passing control over to the other handlers\n // This will allow users to not have to use `$nextTick()` or `requestAF()`\n // when trying to pre-focus an element\n requestAF(() => {\n this.emitEvent(this.buildEvent('shown'))\n this.setEnforceFocus(true)\n this.$nextTick(() => {\n // Delayed in a `$nextTick()` to allow users time to pre-focus\n // an element if the wish\n this.focusFirst()\n })\n })\n },\n onBeforeLeave() {\n this.isTransitioning = true\n this.setResizeEvent(false)\n this.setEnforceFocus(false)\n },\n onLeave() {\n // Remove the 'show' class\n this.isShow = false\n },\n onAfterLeave() {\n this.isBlock = false\n this.isTransitioning = false\n this.isModalOverflowing = false\n this.isHidden = true\n this.$nextTick(() => {\n this.isClosing = false\n modalManager.unregisterModal(this)\n this.returnFocusTo()\n // TODO: Need to find a way to pass the `trigger` property\n // to the `hidden` event, not just only the `hide` event\n this.emitEvent(this.buildEvent('hidden'))\n })\n },\n // Event emitter\n emitEvent(bvModalEvt) {\n const type = bvModalEvt.type\n // We emit on root first incase a global listener wants to cancel\n // the event first before the instance emits its event\n this.emitOnRoot(`bv::modal::${type}`, bvModalEvt, bvModalEvt.componentId)\n this.$emit(type, bvModalEvt)\n },\n // UI event handlers\n onDialogMousedown() {\n // Watch to see if the matching mouseup event occurs outside the dialog\n // And if it does, cancel the clickOut handler\n const modal = this.$refs.modal\n const onceModalMouseup = evt => {\n eventOff(modal, 'mouseup', onceModalMouseup, EVENT_OPTIONS_NO_CAPTURE)\n if (evt.target === modal) {\n this.ignoreBackdropClick = true\n }\n }\n eventOn(modal, 'mouseup', onceModalMouseup, EVENT_OPTIONS_NO_CAPTURE)\n },\n onClickOut(evt) {\n if (this.ignoreBackdropClick) {\n // Click was initiated inside the modal content, but finished outside.\n // Set by the above onDialogMousedown handler\n this.ignoreBackdropClick = false\n return\n }\n // Do nothing if not visible, backdrop click disabled, or element\n // that generated click event is no longer in document body\n if (!this.isVisible || this.noCloseOnBackdrop || !contains(document.body, evt.target)) {\n return\n }\n // If backdrop clicked, hide modal\n if (!contains(this.$refs.content, evt.target)) {\n this.hide('backdrop')\n }\n },\n onOk() {\n this.hide('ok')\n },\n onCancel() {\n this.hide('cancel')\n },\n onClose() {\n this.hide('headerclose')\n },\n onEsc(evt) {\n // If ESC pressed, hide modal\n if (evt.keyCode === KeyCodes.ESC && this.isVisible && !this.noCloseOnEsc) {\n this.hide('esc')\n }\n },\n // Document focusin listener\n focusHandler(evt) {\n // If focus leaves modal content, bring it back\n const content = this.$refs.content\n const { target } = evt\n if (\n this.noEnforceFocus ||\n !this.isTop ||\n !this.isVisible ||\n !content ||\n document === target ||\n contains(content, target) ||\n (this.computeIgnoreEnforceFocusSelector &&\n closest(this.computeIgnoreEnforceFocusSelector, target, true))\n ) {\n return\n }\n const tabables = getTabables(this.$refs.content)\n const { bottomTrap, topTrap } = this.$refs\n if (bottomTrap && target === bottomTrap) {\n // If user pressed TAB out of modal into our bottom trab trap element\n // Find the first tabable element in the modal content and focus it\n if (attemptFocus(tabables[0])) {\n // Focus was successful\n return\n }\n } else if (topTrap && target === topTrap) {\n // If user pressed CTRL-TAB out of modal and into our top tab trap element\n // Find the last tabable element in the modal content and focus it\n if (attemptFocus(tabables[tabables.length - 1])) {\n // Focus was successful\n return\n }\n }\n // Otherwise focus the modal content container\n attemptFocus(content, { preventScroll: true })\n },\n // Turn on/off focusin listener\n setEnforceFocus(on) {\n this.listenDocument(on, 'focusin', this.focusHandler)\n },\n // Resize listener\n setResizeEvent(on) {\n this.listenWindow(on, 'resize', this.checkModalOverflow)\n this.listenWindow(on, 'orientationchange', this.checkModalOverflow)\n },\n // Root listener handlers\n showHandler(id, triggerEl) {\n if (id === this.modalId) {\n this.return_focus = triggerEl || this.getActiveElement()\n this.show()\n }\n },\n hideHandler(id) {\n if (id === this.modalId) {\n this.hide('event')\n }\n },\n toggleHandler(id, triggerEl) {\n if (id === this.modalId) {\n this.toggle(triggerEl)\n }\n },\n modalListener(bvEvt) {\n // If another modal opens, close this one if stacking not permitted\n if (this.noStacking && bvEvt.vueTarget !== this) {\n this.hide()\n }\n },\n // Focus control handlers\n focusFirst() {\n // Don't try and focus if we are SSR\n if (isBrowser) {\n requestAF(() => {\n const modal = this.$refs.modal\n const content = this.$refs.content\n const activeElement = this.getActiveElement()\n // If the modal contains the activeElement, we don't do anything\n if (modal && content && !(activeElement && contains(content, activeElement))) {\n const ok = this.$refs['ok-button']\n const cancel = this.$refs['cancel-button']\n const close = this.$refs['close-button']\n // Focus the appropriate button or modal content wrapper\n const autoFocus = this.autoFocusButton\n /* istanbul ignore next */\n const el =\n autoFocus === 'ok' && ok\n ? ok.$el || ok\n : autoFocus === 'cancel' && cancel\n ? cancel.$el || cancel\n : autoFocus === 'close' && close\n ? close.$el || close\n : content\n // Focus the element\n attemptFocus(el)\n if (el === content) {\n // Make sure top of modal is showing (if longer than the viewport)\n this.$nextTick(() => {\n modal.scrollTop = 0\n })\n }\n }\n })\n }\n },\n returnFocusTo() {\n // Prefer `returnFocus` prop over event specified\n // `return_focus` value\n let el = this.returnFocus || this.return_focus || null\n this.return_focus = null\n this.$nextTick(() => {\n // Is el a string CSS selector?\n el = isString(el) ? select(el) : el\n if (el) {\n // Possibly could be a component reference\n el = el.$el || el\n attemptFocus(el)\n }\n })\n },\n checkModalOverflow() {\n if (this.isVisible) {\n const modal = this.$refs.modal\n this.isModalOverflowing = modal.scrollHeight > document.documentElement.clientHeight\n }\n },\n makeModal(h) {\n // Modal header\n let $header = h()\n if (!this.hideHeader) {\n // TODO: Rename slot to `header` and deprecate `modal-header`\n let $modalHeader = this.normalizeSlot('modal-header', this.slotScope)\n if (!$modalHeader) {\n let $closeButton = h()\n if (!this.hideHeaderClose) {\n $closeButton = h(\n BButtonClose,\n {\n props: {\n content: this.headerCloseContent,\n disabled: this.isTransitioning,\n ariaLabel: this.headerCloseLabel,\n textVariant: this.headerCloseVariant || this.headerTextVariant\n },\n on: { click: this.onClose },\n ref: 'close-button'\n },\n // TODO: Rename slot to `header-close` and deprecate `modal-header-close`\n [this.normalizeSlot('modal-header-close')]\n )\n }\n\n $modalHeader = [\n h(\n this.titleTag,\n {\n staticClass: 'modal-title',\n class: this.titleClasses,\n attrs: { id: this.modalTitleId },\n // TODO: Rename slot to `title` and deprecate `modal-title`\n domProps: this.hasNormalizedSlot('modal-title')\n ? {}\n : htmlOrText(this.titleHtml, this.title)\n },\n // TODO: Rename slot to `title` and deprecate `modal-title`\n [this.normalizeSlot('modal-title', this.slotScope)]\n ),\n $closeButton\n ]\n }\n\n $header = h(\n 'header',\n {\n staticClass: 'modal-header',\n class: this.headerClasses,\n attrs: { id: this.modalHeaderId },\n ref: 'header'\n },\n [$modalHeader]\n )\n }\n\n // Modal body\n const $body = h(\n 'div',\n {\n staticClass: 'modal-body',\n class: this.bodyClasses,\n attrs: { id: this.modalBodyId },\n ref: 'body'\n },\n this.normalizeSlot('default', this.slotScope)\n )\n\n // Modal footer\n let $footer = h()\n if (!this.hideFooter) {\n // TODO: Rename slot to `footer` and deprecate `modal-footer`\n let $modalFooter = this.normalizeSlot('modal-footer', this.slotScope)\n if (!$modalFooter) {\n let $cancelButton = h()\n if (!this.okOnly) {\n $cancelButton = h(\n BButton,\n {\n props: {\n variant: this.cancelVariant,\n size: this.buttonSize,\n disabled: this.cancelDisabled || this.busy || this.isTransitioning\n },\n // TODO: Rename slot to `cancel-button` and deprecate `modal-cancel`\n domProps: this.hasNormalizedSlot('modal-cancel')\n ? {}\n : htmlOrText(this.cancelTitleHtml, this.cancelTitle),\n on: { click: this.onCancel },\n ref: 'cancel-button'\n },\n // TODO: Rename slot to `cancel-button` and deprecate `modal-cancel`\n this.normalizeSlot('modal-cancel')\n )\n }\n\n const $okButton = h(\n BButton,\n {\n props: {\n variant: this.okVariant,\n size: this.buttonSize,\n disabled: this.okDisabled || this.busy || this.isTransitioning\n },\n // TODO: Rename slot to `ok-button` and deprecate `modal-ok`\n domProps: this.hasNormalizedSlot('modal-ok')\n ? {}\n : htmlOrText(this.okTitleHtml, this.okTitle),\n on: { click: this.onOk },\n ref: 'ok-button'\n },\n // TODO: Rename slot to `ok-button` and deprecate `modal-ok`\n this.normalizeSlot('modal-ok')\n )\n\n $modalFooter = [$cancelButton, $okButton]\n }\n\n $footer = h(\n 'footer',\n {\n staticClass: 'modal-footer',\n class: this.footerClasses,\n attrs: { id: this.modalFooterId },\n ref: 'footer'\n },\n [$modalFooter]\n )\n }\n\n // Assemble modal content\n const $modalContent = h(\n 'div',\n {\n staticClass: 'modal-content',\n class: this.contentClass,\n attrs: {\n id: this.modalContentId,\n tabindex: '-1'\n },\n ref: 'content'\n },\n [$header, $body, $footer]\n )\n\n // Tab traps to prevent page from scrolling to next element in\n // tab index during enforce-focus tab cycle\n let $tabTrapTop = h()\n let $tabTrapBottom = h()\n if (this.isVisible && !this.noEnforceFocus) {\n $tabTrapTop = h('span', { ref: 'topTrap', attrs: { tabindex: '0' } })\n $tabTrapBottom = h('span', { ref: 'bottomTrap', attrs: { tabindex: '0' } })\n }\n\n // Modal dialog wrapper\n const $modalDialog = h(\n 'div',\n {\n staticClass: 'modal-dialog',\n class: this.dialogClasses,\n on: { mousedown: this.onDialogMousedown },\n ref: 'dialog'\n },\n [$tabTrapTop, $modalContent, $tabTrapBottom]\n )\n\n // Modal\n let $modal = h(\n 'div',\n {\n staticClass: 'modal',\n class: this.modalClasses,\n style: this.modalStyles,\n attrs: this.computedModalAttrs,\n on: { keydown: this.onEsc, click: this.onClickOut },\n directives: [{ name: 'show', value: this.isVisible }],\n ref: 'modal'\n },\n [$modalDialog]\n )\n\n // Wrap modal in transition\n // Sadly, we can't use `BVTransition` here due to the differences in\n // transition durations for `.modal` and `.modal-dialog`\n // At least until https://github.com/vuejs/vue/issues/9986 is resolved\n $modal = h(\n 'transition',\n {\n props: {\n enterClass: '',\n enterToClass: '',\n enterActiveClass: '',\n leaveClass: '',\n leaveActiveClass: '',\n leaveToClass: ''\n },\n on: {\n beforeEnter: this.onBeforeEnter,\n enter: this.onEnter,\n afterEnter: this.onAfterEnter,\n beforeLeave: this.onBeforeLeave,\n leave: this.onLeave,\n afterLeave: this.onAfterLeave\n }\n },\n [$modal]\n )\n\n // Modal backdrop\n let $backdrop = h()\n if (!this.hideBackdrop && this.isVisible) {\n $backdrop = h(\n 'div',\n {\n staticClass: 'modal-backdrop',\n attrs: { id: this.modalBackdropId }\n },\n // TODO: Rename slot to `backdrop` and deprecate `modal-backdrop`\n this.normalizeSlot('modal-backdrop')\n )\n }\n $backdrop = h(BVTransition, { props: { noFade: this.noFade } }, [$backdrop])\n\n // Assemble modal and backdrop in an outer \n return h(\n 'div',\n {\n style: this.modalOuterStyle,\n attrs: this.computedAttrs,\n key: `modal-outer-${this._uid}`\n },\n [$modal, $backdrop]\n )\n }\n },\n render(h) {\n if (this.static) {\n return this.lazy && this.isHidden ? h() : this.makeModal(h)\n } else {\n return this.isHidden ? h() : h(BTransporterSingle, [this.makeModal(h)])\n }\n }\n})\n","import KeyCodes from '../../utils/key-codes'\nimport { getAttr, hasAttr, isDisabled, matches, select, setAttr } from '../../utils/dom'\nimport { EVENT_OPTIONS_PASSIVE, eventOn, eventOff } from '../../utils/events'\nimport { isString } from '../../utils/inspect'\nimport { keys } from '../../utils/object'\n\n// Emitted show event for modal\nconst EVENT_SHOW = 'bv::show::modal'\n\n// Prop name we use to store info on root element\nconst PROPERTY = '__bv_modal_directive__'\n\nconst getTarget = ({ modifiers = {}, arg, value }) => {\n // Try value, then arg, otherwise pick last modifier\n return isString(value) ? value : isString(arg) ? arg : keys(modifiers).reverse()[0]\n}\n\nconst getTriggerElement = el => {\n // If root element is a dropdown-item or nav-item, we\n // need to target the inner link or button instead\n return el && matches(el, '.dropdown-menu > li, li.nav-item') ? select('a, button', el) || el : el\n}\n\nconst setRole = trigger => {\n // Ensure accessibility on non button elements\n if (trigger && trigger.tagName !== 'BUTTON') {\n // Only set a role if the trigger element doesn't have one\n if (!hasAttr(trigger, 'role')) {\n setAttr(trigger, 'role', 'button')\n }\n // Add a tabindex is not a button or link, and tabindex is not provided\n if (trigger.tagName !== 'A' && !hasAttr(trigger, 'tabindex')) {\n setAttr(trigger, 'tabindex', '0')\n }\n }\n}\n\nconst bind = (el, binding, vnode) => {\n const target = getTarget(binding)\n const trigger = getTriggerElement(el)\n if (target && trigger) {\n const handler = evt => {\n // `currentTarget` is the element with the listener on it\n const currentTarget = evt.currentTarget\n if (!isDisabled(currentTarget)) {\n const type = evt.type\n const key = evt.keyCode\n // Open modal only if trigger is not disabled\n if (\n type === 'click' ||\n (type === 'keydown' && (key === KeyCodes.ENTER || key === KeyCodes.SPACE))\n ) {\n vnode.context.$root.$emit(EVENT_SHOW, target, currentTarget)\n }\n }\n }\n el[PROPERTY] = { handler, target, trigger }\n // If element is not a button, we add `role=\"button\"` for accessibility\n setRole(trigger)\n // Listen for click events\n eventOn(trigger, 'click', handler, EVENT_OPTIONS_PASSIVE)\n if (trigger.tagName !== 'BUTTON' && getAttr(trigger, 'role') === 'button') {\n // If trigger isn't a button but has role button,\n // we also listen for `keydown.space` && `keydown.enter`\n eventOn(trigger, 'keydown', handler, EVENT_OPTIONS_PASSIVE)\n }\n }\n}\n\nconst unbind = el => {\n const oldProp = el[PROPERTY] || {}\n const trigger = oldProp.trigger\n const handler = oldProp.handler\n if (trigger && handler) {\n eventOff(trigger, 'click', handler, EVENT_OPTIONS_PASSIVE)\n eventOff(trigger, 'keydown', handler, EVENT_OPTIONS_PASSIVE)\n eventOff(el, 'click', handler, EVENT_OPTIONS_PASSIVE)\n eventOff(el, 'keydown', handler, EVENT_OPTIONS_PASSIVE)\n }\n delete el[PROPERTY]\n}\n\nconst componentUpdated = (el, binding, vnode) => {\n const oldProp = el[PROPERTY] || {}\n const target = getTarget(binding)\n const trigger = getTriggerElement(el)\n if (target !== oldProp.target || trigger !== oldProp.trigger) {\n // We bind and rebind if the target or trigger changes\n unbind(el, binding, vnode)\n bind(el, binding, vnode)\n }\n // If trigger element is not a button, ensure `role=\"button\"`\n // is still set for accessibility\n setRole(trigger)\n}\n\nconst updated = () => {}\n\n/*\n * Export our directive\n */\nexport const VBModal = {\n inserted: componentUpdated,\n updated,\n componentUpdated,\n unbind\n}\n","// Plugin for adding `$bvModal` property to all Vue instances\nimport { BModal, props as modalProps } from '../modal'\nimport { concat } from '../../../utils/array'\nimport { getComponentConfig } from '../../../utils/config'\nimport { isUndefined, isFunction } from '../../../utils/inspect'\nimport {\n assign,\n defineProperties,\n defineProperty,\n hasOwnProperty,\n keys,\n omit,\n readonlyDescriptor\n} from '../../../utils/object'\nimport { pluginFactory } from '../../../utils/plugins'\nimport { warn, warnNotClient, warnNoPromiseSupport } from '../../../utils/warn'\n\n// --- Constants ---\n\nconst PROP_NAME = '$bvModal'\nconst PROP_NAME_PRIV = '_bv__modal'\n\n// Base modal props that are allowed\n// Some may be ignored or overridden on some message boxes\n// Prop ID is allowed, but really only should be used for testing\n// We need to add it in explicitly as it comes from the `idMixin`\nconst BASE_PROPS = [\n 'id',\n ...keys(omit(modalProps, ['busy', 'lazy', 'noStacking', `static`, 'visible']))\n]\n\n// Fallback event resolver (returns undefined)\nconst defaultResolver = () => {}\n\n// Map prop names to modal slot names\nconst propsToSlots = {\n msgBoxContent: 'default',\n title: 'modal-title',\n okTitle: 'modal-ok',\n cancelTitle: 'modal-cancel'\n}\n\n// --- Utility methods ---\n\n// Method to filter only recognized props that are not undefined\nconst filterOptions = options => {\n return BASE_PROPS.reduce((memo, key) => {\n if (!isUndefined(options[key])) {\n memo[key] = options[key]\n }\n return memo\n }, {})\n}\n\n// Method to install `$bvModal` VM injection\nconst plugin = Vue => {\n // Create a private sub-component that extends BModal\n // which self-destructs after hidden\n // @vue/component\n const BMsgBox = Vue.extend({\n name: 'BMsgBox',\n extends: BModal,\n destroyed() {\n // Make sure we not in document any more\n if (this.$el && this.$el.parentNode) {\n this.$el.parentNode.removeChild(this.$el)\n }\n },\n mounted() {\n // Self destruct handler\n const handleDestroy = () => {\n const self = this\n this.$nextTick(() => {\n // In a `setTimeout()` to release control back to application\n setTimeout(() => self.$destroy(), 0)\n })\n }\n // Self destruct if parent destroyed\n this.$parent.$once('hook:destroyed', handleDestroy)\n // Self destruct after hidden\n this.$once('hidden', handleDestroy)\n // Self destruct on route change\n /* istanbul ignore if */\n if (this.$router && this.$route) {\n // Destroy ourselves if route changes\n /* istanbul ignore next */\n this.$once('hook:beforeDestroy', this.$watch('$router', handleDestroy))\n }\n // Show the `BMsgBox`\n this.show()\n }\n })\n\n // Method to generate the on-demand modal message box\n // Returns a promise that resolves to a value returned by the resolve\n const asyncMsgBox = ($parent, props, resolver = defaultResolver) => {\n if (warnNotClient(PROP_NAME) || warnNoPromiseSupport(PROP_NAME)) {\n /* istanbul ignore next */\n return\n }\n // Create an instance of `BMsgBox` component\n const msgBox = new BMsgBox({\n // We set parent as the local VM so these modals can emit events on\n // the app `$root`, as needed by things like tooltips and popovers\n // And it helps to ensure `BMsgBox` is destroyed when parent is destroyed\n parent: $parent,\n // Preset the prop values\n propsData: {\n ...filterOptions(getComponentConfig('BModal') || {}),\n // Defaults that user can override\n hideHeaderClose: true,\n hideHeader: !(props.title || props.titleHtml),\n // Add in (filtered) user supplied props\n ...omit(props, keys(propsToSlots)),\n // Props that can't be overridden\n lazy: false,\n busy: false,\n visible: false,\n noStacking: false,\n noEnforceFocus: false\n }\n })\n // Convert certain props to scoped slots\n keys(propsToSlots).forEach(prop => {\n if (!isUndefined(props[prop])) {\n // Can be a string, or array of VNodes.\n // Alternatively, user can use HTML version of prop to pass an HTML string.\n msgBox.$slots[propsToSlots[prop]] = concat(props[prop])\n }\n })\n // Return a promise that resolves when hidden, or rejects on destroyed\n return new Promise((resolve, reject) => {\n let resolved = false\n msgBox.$once('hook:destroyed', () => {\n if (!resolved) {\n /* istanbul ignore next */\n reject(new Error('BootstrapVue MsgBox destroyed before resolve'))\n }\n })\n msgBox.$on('hide', bvModalEvt => {\n if (!bvModalEvt.defaultPrevented) {\n const result = resolver(bvModalEvt)\n // If resolver didn't cancel hide, we resolve\n if (!bvModalEvt.defaultPrevented) {\n resolved = true\n resolve(result)\n }\n }\n })\n // Create a mount point (a DIV) and mount the msgBo which will trigger it to show\n const div = document.createElement('div')\n document.body.appendChild(div)\n msgBox.$mount(div)\n })\n }\n\n // Private utility method to open a user defined message box and returns a promise.\n // Not to be used directly by consumers, as this method may change calling syntax\n const makeMsgBox = ($parent, content, options = {}, resolver) => {\n if (\n !content ||\n warnNoPromiseSupport(PROP_NAME) ||\n warnNotClient(PROP_NAME) ||\n !isFunction(resolver)\n ) {\n /* istanbul ignore next */\n return\n }\n return asyncMsgBox($parent, { ...filterOptions(options), msgBoxContent: content }, resolver)\n }\n\n // BvModal instance class\n class BvModal {\n constructor(vm) {\n // Assign the new properties to this instance\n assign(this, { _vm: vm, _root: vm.$root })\n // Set these properties as read-only and non-enumerable\n defineProperties(this, {\n _vm: readonlyDescriptor(),\n _root: readonlyDescriptor()\n })\n }\n\n // --- Instance methods ---\n\n // Show modal with the specified ID args are for future use\n show(id, ...args) {\n if (id && this._root) {\n this._root.$emit('bv::show::modal', id, ...args)\n }\n }\n\n // Hide modal with the specified ID args are for future use\n hide(id, ...args) {\n if (id && this._root) {\n this._root.$emit('bv::hide::modal', id, ...args)\n }\n }\n\n // The following methods require Promise support!\n // IE 11 and others do not support Promise natively, so users\n // should have a Polyfill loaded (which they need anyways for IE 11 support)\n\n // Open a message box with OK button only and returns a promise\n msgBoxOk(message, options = {}) {\n // Pick the modal props we support from options\n const props = {\n ...options,\n // Add in overrides and our content prop\n okOnly: true,\n okDisabled: false,\n hideFooter: false,\n msgBoxContent: message\n }\n return makeMsgBox(this._vm, message, props, () => {\n // Always resolve to true for OK\n return true\n })\n }\n\n // Open a message box modal with OK and CANCEL buttons\n // and returns a promise\n msgBoxConfirm(message, options = {}) {\n // Set the modal props we support from options\n const props = {\n ...options,\n // Add in overrides and our content prop\n okOnly: false,\n okDisabled: false,\n cancelDisabled: false,\n hideFooter: false\n }\n return makeMsgBox(this._vm, message, props, bvModalEvt => {\n const trigger = bvModalEvt.trigger\n return trigger === 'ok' ? true : trigger === 'cancel' ? false : null\n })\n }\n }\n\n // Add our instance mixin\n Vue.mixin({\n beforeCreate() {\n // Because we need access to `$root` for `$emits`, and VM for parenting,\n // we have to create a fresh instance of `BvModal` for each VM\n this[PROP_NAME_PRIV] = new BvModal(this)\n }\n })\n\n // Define our read-only `$bvModal` instance property\n // Placed in an if just in case in HMR mode\n if (!hasOwnProperty(Vue.prototype, PROP_NAME)) {\n defineProperty(Vue.prototype, PROP_NAME, {\n get() {\n /* istanbul ignore next */\n if (!this || !this[PROP_NAME_PRIV]) {\n warn(`\"${PROP_NAME}\" must be accessed from a Vue instance \"this\" context.`, 'BModal')\n }\n return this[PROP_NAME_PRIV]\n }\n })\n }\n}\n\nexport const BVModalPlugin = /*#__PURE__*/ pluginFactory({\n plugins: { plugin }\n})\n","import { BModal } from './modal'\nimport { VBModal } from '../../directives/modal/modal'\nimport { BVModalPlugin } from './helpers/bv-modal'\nimport { pluginFactory } from '../../utils/plugins'\n\nconst ModalPlugin = /*#__PURE__*/ pluginFactory({\n components: { BModal },\n directives: { VBModal },\n // $bvModal injection\n plugins: { BVModalPlugin }\n})\n\nexport { ModalPlugin, BModal }\n","import Vue from '../../utils/vue'\nimport { concat } from '../../utils/array'\nimport { getComponentConfig } from '../../utils/config'\nimport { attemptBlur, attemptFocus } from '../../utils/dom'\nimport { isBoolean, isEvent, isFunction, isUndefined } from '../../utils/inspect'\nimport { pluckProps } from '../../utils/props'\nimport { computeHref, computeRel, computeTag, isRouterLink } from '../../utils/router'\nimport attrsMixin from '../../mixins/attrs'\nimport listenersMixin from '../../mixins/listeners'\nimport normalizeSlotMixin from '../../mixins/normalize-slot'\n\n// --- Constants ---\n\nconst NAME = 'BLink'\n\n// --- Props ---\n\n// specific props\nexport const routerLinkProps = {\n to: {\n type: [String, Object],\n default: null\n },\n append: {\n type: Boolean,\n default: false\n },\n replace: {\n type: Boolean,\n default: false\n },\n event: {\n type: [String, Array],\n default: 'click'\n },\n activeClass: {\n type: String\n // default: undefined\n },\n exact: {\n type: Boolean,\n default: false\n },\n exactActiveClass: {\n type: String\n // default: undefined\n },\n routerTag: {\n type: String,\n default: 'a'\n }\n}\n\n// specific props\nexport const nuxtLinkProps = {\n prefetch: {\n type: Boolean,\n // Must be `null` to fall back to the value defined in the\n // `nuxt.config.js` configuration file for `router.prefetchLinks`\n // We convert `null` to `undefined`, so that Nuxt.js will use the\n // compiled default. Vue treats `undefined` as default of `false`\n // for Boolean props, so we must set it as `null` here to be a\n // true tri-state prop\n default: null\n },\n noPrefetch: {\n type: Boolean,\n default: false\n }\n}\n\nexport const props = {\n href: {\n type: String,\n default: null\n },\n rel: {\n type: String,\n // Must be `null` if no value provided\n default: null\n },\n target: {\n type: String,\n default: '_self'\n },\n active: {\n type: Boolean,\n default: false\n },\n disabled: {\n type: Boolean,\n default: false\n },\n ...routerLinkProps,\n ...nuxtLinkProps,\n // To support 3rd party router links based on `` (i.e. `g-link` for Gridsome)\n // Default is to auto choose between `` and ``\n // Gridsome doesn't provide a mechanism to auto detect and has caveats\n // such as not supporting FQDN URLs or hash only URLs\n routerComponentName: {\n type: String,\n default: () => getComponentConfig(NAME, 'routerComponentName')\n }\n}\n\n// --- Main component ---\n// @vue/component\nexport const BLink = /*#__PURE__*/ Vue.extend({\n name: 'BLink',\n // Mixin order is important!\n mixins: [attrsMixin, listenersMixin, normalizeSlotMixin],\n inheritAttrs: false,\n props,\n computed: {\n computedTag() {\n // We don't pass `this` as the first arg as we need reactivity of the props\n const { to, disabled, routerComponentName } = this\n return computeTag({ to, disabled, routerComponentName }, this)\n },\n isRouterLink() {\n return isRouterLink(this.computedTag)\n },\n computedRel() {\n // We don't pass `this` as the first arg as we need reactivity of the props\n return computeRel({ target: this.target, rel: this.rel })\n },\n computedHref() {\n // We don't pass `this` as the first arg as we need reactivity of the props\n return computeHref({ to: this.to, href: this.href }, this.computedTag)\n },\n computedProps() {\n const prefetch = this.prefetch\n return this.isRouterLink\n ? {\n ...pluckProps({ ...routerLinkProps, ...nuxtLinkProps }, this),\n // Coerce `prefetch` value `null` to be `undefined`\n prefetch: isBoolean(prefetch) ? prefetch : undefined,\n // Pass `router-tag` as `tag` prop\n tag: this.routerTag\n }\n : {}\n },\n computedAttrs() {\n const {\n bvAttrs,\n computedHref: href,\n computedRel: rel,\n disabled,\n target,\n routerTag,\n isRouterLink\n } = this\n\n return {\n ...bvAttrs,\n // If `href` attribute exists on `` (even `undefined` or `null`)\n // it fails working on SSR, so we explicitly add it here if needed\n // (i.e. if `computedHref()` is truthy)\n ...(href ? { href } : {}),\n // We don't render `rel` or `target` on non link tags when using `vue-router`\n ...(isRouterLink && routerTag !== 'a' && routerTag !== 'area' ? {} : { rel, target }),\n tabindex: disabled ? '-1' : isUndefined(bvAttrs.tabindex) ? null : bvAttrs.tabindex,\n 'aria-disabled': disabled ? 'true' : null\n }\n },\n computedListeners() {\n return {\n // Transfer all listeners (native) to the root element\n ...this.bvListeners,\n // We want to overwrite any click handler since our callback\n // will invoke the user supplied handler(s) if `!this.disabled`\n click: this.onClick\n }\n }\n },\n methods: {\n onClick(evt) {\n const evtIsEvent = isEvent(evt)\n const isRouterLink = this.isRouterLink\n const suppliedHandler = this.bvListeners.click\n if (evtIsEvent && this.disabled) {\n // Stop event from bubbling up\n evt.stopPropagation()\n // Kill the event loop attached to this specific `EventTarget`\n // Needed to prevent `vue-router` for doing its thing\n evt.stopImmediatePropagation()\n } else {\n /* istanbul ignore next: difficult to test, but we know it works */\n if (isRouterLink && evt.currentTarget.__vue__) {\n // Router links do not emit instance `click` events, so we\n // add in an `$emit('click', evt)` on its Vue instance\n evt.currentTarget.__vue__.$emit('click', evt)\n }\n // Call the suppliedHandler(s), if any provided\n concat(suppliedHandler)\n .filter(h => isFunction(h))\n .forEach(handler => {\n handler(...arguments)\n })\n // Emit the global `$root` click event\n this.$root.$emit('clicked::link', evt)\n }\n // Stop scroll-to-top behavior or navigation on\n // regular links when href is just '#'\n if (evtIsEvent && (this.disabled || (!isRouterLink && this.computedHref === '#'))) {\n evt.preventDefault()\n }\n },\n focus() {\n attemptFocus(this.$el)\n },\n blur() {\n attemptBlur(this.$el)\n }\n },\n render(h) {\n const { active, disabled } = this\n\n return h(\n this.computedTag,\n {\n class: { active, disabled },\n attrs: this.computedAttrs,\n props: this.computedProps,\n // We must use `nativeOn` for ``/`` instead of `on`\n [this.isRouterLink ? 'nativeOn' : 'on']: this.computedListeners\n },\n this.normalizeSlot('default')\n )\n }\n})\n","const RX_HTML_TAGS = /(<([^>]+)>)/gi\n\n// Removes anything that looks like an HTML tag from the supplied string\nexport const stripTags = (text = '') => String(text).replace(RX_HTML_TAGS, '')\n\n// Generate a `domProps` object for either `innerHTML`, `textContent` or an empty object\nexport const htmlOrText = (innerHTML, textContent) => {\n return innerHTML ? { innerHTML } : textContent ? { textContent } : {}\n}\n","//\n// Single point of contact for Vue\n//\n// TODO:\n// Conditionally import Vue if no global Vue\n//\nimport Vue from 'vue'\n\nexport default Vue\n","// @vue/component\nexport default {\n methods: {\n /**\n * Safely register event listeners on the root Vue node\n * While Vue automatically removes listeners for individual components,\n * when a component registers a listener on root and is destroyed,\n * this orphans a callback because the node is gone,\n * but the root does not clear the callback\n *\n * When registering a `$root` listener, it also registers a listener on\n * the component's `beforeDestroy()` hook to automatically remove the\n * event listener from the `$root` instance\n *\n * @param {string} event\n * @param {function} callback\n */\n listenOnRoot(event, callback) {\n this.$root.$on(event, callback)\n this.$on('hook:beforeDestroy', () => {\n this.$root.$off(event, callback)\n })\n },\n\n /**\n * Safely register a `$once()` event listener on the root Vue node\n * While Vue automatically removes listeners for individual components,\n * when a component registers a listener on root and is destroyed,\n * this orphans a callback because the node is gone,\n * but the root does not clear the callback\n *\n * When registering a $root listener, it also registers a listener on\n * the component's `beforeDestroy` hook to automatically remove the\n * event listener from the $root instance.\n *\n * @param {string} event\n * @param {function} callback\n */\n listenOnRootOnce(event, callback) {\n this.$root.$once(event, callback)\n this.$on('hook:beforeDestroy', () => {\n this.$root.$off(event, callback)\n })\n },\n\n /**\n * Convenience method for calling `vm.$emit()` on `vm.$root`\n *\n * @param {string} event\n * @param {*} args\n */\n emitOnRoot(event, ...args) {\n this.$root.$emit(event, ...args)\n }\n }\n}\n","import { isBrowser, hasPromiseSupport, hasMutationObserverSupport, getNoWarn } from './env'\n\n/**\n * Log a warning message to the console with BootstrapVue formatting\n * @param {string} message\n */\nexport const warn = (message, source = null) => /* istanbul ignore next */ {\n if (!getNoWarn()) {\n console.warn(`[BootstrapVue warn]: ${source ? `${source} - ` : ''}${message}`)\n }\n}\n\n/**\n * Warn when no Promise support is given\n * @param {string} source\n * @returns {boolean} warned\n */\nexport const warnNotClient = source => {\n /* istanbul ignore else */\n if (isBrowser) {\n return false\n } else {\n warn(`${source}: Can not be called during SSR.`)\n return true\n }\n}\n\n/**\n * Warn when no Promise support is given\n * @param {string} source\n * @returns {boolean} warned\n */\nexport const warnNoPromiseSupport = source => {\n /* istanbul ignore else */\n if (hasPromiseSupport) {\n return false\n } else {\n warn(`${source}: Requires Promise support.`)\n return true\n }\n}\n\n/**\n * Warn when no MutationObserver support is given\n * @param {string} source\n * @returns {boolean} warned\n */\nexport const warnNoMutationObserverSupport = source => {\n /* istanbul ignore else */\n if (hasMutationObserverSupport) {\n return false\n } else {\n warn(`${source}: Requires MutationObserver support.`)\n return true\n }\n}\n"],"sourceRoot":""}
\ No newline at end of file
diff --git a/ui/dist/async_vendor_7274e1de.c8a5d568b3002b296cb0.bundle.js.map.gz b/ui/dist/async_vendor_7274e1de.c8a5d568b3002b296cb0.bundle.js.map.gz
new file mode 100644
index 0000000..e76a2dc
Binary files /dev/null and b/ui/dist/async_vendor_7274e1de.c8a5d568b3002b296cb0.bundle.js.map.gz differ
diff --git a/ui/dist/async_vendor_7274e1de.dc63956c75681b023819.bundle.js.map.gz b/ui/dist/async_vendor_7274e1de.dc63956c75681b023819.bundle.js.map.gz
deleted file mode 100644
index 4cac37f..0000000
Binary files a/ui/dist/async_vendor_7274e1de.dc63956c75681b023819.bundle.js.map.gz and /dev/null differ
diff --git a/ui/dist/async_vendor_9c5b28f6.dc63956c75681b023819.bundle.css b/ui/dist/async_vendor_9c5b28f6.c8a5d568b3002b296cb0.bundle.css
similarity index 100%
rename from ui/dist/async_vendor_9c5b28f6.dc63956c75681b023819.bundle.css
rename to ui/dist/async_vendor_9c5b28f6.c8a5d568b3002b296cb0.bundle.css
diff --git a/ui/dist/async_vendor_9c5b28f6.dc63956c75681b023819.bundle.css.gz b/ui/dist/async_vendor_9c5b28f6.c8a5d568b3002b296cb0.bundle.css.gz
similarity index 100%
rename from ui/dist/async_vendor_9c5b28f6.dc63956c75681b023819.bundle.css.gz
rename to ui/dist/async_vendor_9c5b28f6.c8a5d568b3002b296cb0.bundle.css.gz
diff --git a/ui/dist/async_vendor_9c5b28f6.dc63956c75681b023819.bundle.js b/ui/dist/async_vendor_9c5b28f6.c8a5d568b3002b296cb0.bundle.js
similarity index 99%
rename from ui/dist/async_vendor_9c5b28f6.dc63956c75681b023819.bundle.js
rename to ui/dist/async_vendor_9c5b28f6.c8a5d568b3002b296cb0.bundle.js
index 334bbe7..b7c9f95 100644
--- a/ui/dist/async_vendor_9c5b28f6.dc63956c75681b023819.bundle.js
+++ b/ui/dist/async_vendor_9c5b28f6.c8a5d568b3002b296cb0.bundle.js
@@ -48,4 +48,4 @@ const n=Symbol.prototype.valueOf,i=r("7104");e.exports=function(e,r){switch(i(e)
*/void 0===(i="function"==typeof(n=function(){var e,t,r,n,i,o={},a={},s={currentLocale:"en",zeroFormat:null,nullFormat:null,defaultFormat:"0,0",scalePercentBy100:!0},u={currentLocale:s.currentLocale,zeroFormat:s.zeroFormat,nullFormat:s.nullFormat,defaultFormat:s.defaultFormat,scalePercentBy100:s.scalePercentBy100};function f(e,t){this._input=e,this._value=t}return(e=function(r){var n,i,a,s;if(e.isNumeral(r))n=r.value();else if(0===r||void 0===r)n=0;else if(null===r||t.isNaN(r))n=null;else if("string"==typeof r)if(u.zeroFormat&&r===u.zeroFormat)n=0;else if(u.nullFormat&&r===u.nullFormat||!r.replace(/[^0-9]+/g,"").length)n=null;else{for(i in o)if((s="function"==typeof o[i].regexps.unformat?o[i].regexps.unformat():o[i].regexps.unformat)&&r.match(s)){a=o[i].unformat;break}n=(a=a||e._.stringToNumber)(r)}else n=Number(r)||null;return new f(r,n)}).version="2.0.6",e.isNumeral=function(e){return e instanceof f},e._=t={numberToFormat:function(t,r,n){var i,o,s,u,f,c,l,h,d=a[e.options.currentLocale],p=!1,g=!1,m="",y="",b=!1;if(t=t||0,s=Math.abs(t),e._.includes(r,"(")?(p=!0,r=r.replace(/[\(|\)]/g,"")):(e._.includes(r,"+")||e._.includes(r,"-"))&&(c=e._.includes(r,"+")?r.indexOf("+"):t<0?r.indexOf("-"):-1,r=r.replace(/[\+|\-]/g,"")),e._.includes(r,"a")&&(o=!!(o=r.match(/a(k|m|b|t)?/))&&o[1],e._.includes(r," a")&&(m=" "),r=r.replace(new RegExp(m+"a[kmbt]?"),""),s>=1e12&&!o||"t"===o?(m+=d.abbreviations.trillion,t/=1e12):s<1e12&&s>=1e9&&!o||"b"===o?(m+=d.abbreviations.billion,t/=1e9):s<1e9&&s>=1e6&&!o||"m"===o?(m+=d.abbreviations.million,t/=1e6):(s<1e6&&s>=1e3&&!o||"k"===o)&&(m+=d.abbreviations.thousand,t/=1e3)),e._.includes(r,"[.]")&&(g=!0,r=r.replace("[.]",".")),u=t.toString().split(".")[0],f=r.split(".")[1],l=r.indexOf(","),i=(r.split(".")[0].split(",")[0].match(/0/g)||[]).length,f?(e._.includes(f,"[")?(f=(f=f.replace("]","")).split("["),y=e._.toFixed(t,f[0].length+f[1].length,n,f[1].length)):y=e._.toFixed(t,f.length,n),u=y.split(".")[0],y=e._.includes(y,".")?d.delimiters.decimal+y.split(".")[1]:"",g&&0===Number(y.slice(1))&&(y="")):u=e._.toFixed(t,0,n),m&&!o&&Number(u)>=1e3&&m!==d.abbreviations.trillion)switch(u=String(Number(u)/1e3),m){case d.abbreviations.thousand:m=d.abbreviations.million;break;case d.abbreviations.million:m=d.abbreviations.billion;break;case d.abbreviations.billion:m=d.abbreviations.trillion}if(e._.includes(u,"-")&&(u=u.slice(1),b=!0),u.length0;v--)u="0"+u;return l>-1&&(u=u.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+d.delimiters.thousands)),0===r.indexOf(".")&&(u=""),h=u+y+(m||""),p?h=(p&&b?"(":"")+h+(p&&b?")":""):c>=0?h=0===c?(b?"-":"+")+h:h+(b?"-":"+"):b&&(h="-"+h),h},stringToNumber:function(e){var t,r,n,i=a[u.currentLocale],o=e,s={thousand:3,million:6,billion:9,trillion:12};if(u.zeroFormat&&e===u.zeroFormat)r=0;else if(u.nullFormat&&e===u.nullFormat||!e.replace(/[^0-9]+/g,"").length)r=null;else{for(t in r=1,"."!==i.delimiters.decimal&&(e=e.replace(/\./g,"").replace(i.delimiters.decimal,".")),s)if(n=new RegExp("[^a-zA-Z]"+i.abbreviations[t]+"(?:\\)|(\\"+i.currency.symbol+")?(?:\\))?)?$"),o.match(n)){r*=Math.pow(10,s[t]);break}r*=(e.split("-").length+Math.min(e.split("(").length-1,e.split(")").length-1))%2?1:-1,e=e.replace(/[^0-9\.]+/g,""),r*=Number(e)}return r},isNaN:function(e){return"number"==typeof e&&isNaN(e)},includes:function(e,t){return-1!==e.indexOf(t)},insert:function(e,t,r){return e.slice(0,r)+t+e.slice(r)},reduce:function(e,t){if(null===this)throw new TypeError("Array.prototype.reduce called on null or undefined");if("function"!=typeof t)throw new TypeError(t+" is not a function");var r,n=Object(e),i=n.length>>>0,o=0;if(3===arguments.length)r=arguments[2];else{for(;o=i)throw new TypeError("Reduce of empty array with no initial value");r=n[o++]}for(;on?e:n}),1)},toFixed:function(e,t,r,n){var i,o,a,s,u=e.toString().split("."),f=t-(n||0);return i=2===u.length?Math.min(Math.max(u[1].length,f),t):f,a=Math.pow(10,i),s=(r(e+"e+"+i)/a).toFixed(i),n>t-i&&(o=new RegExp("\\.?0{1,"+(n-(t-i))+"}$"),s=s.replace(o,"")),s}},e.options=u,e.formats=o,e.locales=a,e.locale=function(e){return e&&(u.currentLocale=e.toLowerCase()),u.currentLocale},e.localeData=function(e){if(!e)return a[u.currentLocale];if(e=e.toLowerCase(),!a[e])throw new Error("Unknown locale : "+e);return a[e]},e.reset=function(){for(var e in s)u[e]=s[e]},e.zeroFormat=function(e){u.zeroFormat="string"==typeof e?e:null},e.nullFormat=function(e){u.nullFormat="string"==typeof e?e:null},e.defaultFormat=function(e){u.defaultFormat="string"==typeof e?e:"0.0"},e.register=function(e,t,r){if(t=t.toLowerCase(),this[e+"s"][t])throw new TypeError(t+" "+e+" already registered.");return this[e+"s"][t]=r,r},e.validate=function(t,r){var n,i,o,a,s,u,f,c;if("string"!=typeof t&&(t+="",console.warn&&console.warn("Numeral.js: Value is not string. It has been co-erced to: ",t)),(t=t.trim()).match(/^\d+$/))return!0;if(""===t)return!1;try{f=e.localeData(r)}catch(t){f=e.localeData(e.locale())}return o=f.currency.symbol,s=f.abbreviations,n=f.delimiters.decimal,i="."===f.delimiters.thousands?"\\.":f.delimiters.thousands,!(null!==(c=t.match(/^[^\d]+/))&&(t=t.substr(1),c[0]!==o)||null!==(c=t.match(/[^\d]+$/))&&(t=t.slice(0,-1),c[0]!==s.thousand&&c[0]!==s.million&&c[0]!==s.billion&&c[0]!==s.trillion)||(u=new RegExp(i+"{2}"),t.match(/[^\d.,]/g)||(a=t.split(n)).length>2||(a.length<2?!a[0].match(/^\d+.*\d$/)||a[0].match(u):1===a[0].length?!a[0].match(/^\d+$/)||a[0].match(u)||!a[1].match(/^\d+$/):!a[0].match(/^\d+.*\d$/)||a[0].match(u)||!a[1].match(/^\d+$/))))},e.fn=f.prototype={clone:function(){return e(this)},format:function(t,r){var n,i,a,s=this._value,f=t||u.defaultFormat;if(r=r||Math.round,0===s&&null!==u.zeroFormat)i=u.zeroFormat;else if(null===s&&null!==u.nullFormat)i=u.nullFormat;else{for(n in o)if(f.match(o[n].regexps.format)){a=o[n].format;break}i=(a=a||e._.numberToFormat)(s,f,r)}return i},value:function(){return this._value},input:function(){return this._input},set:function(e){return this._value=Number(e),this},add:function(e){var r=t.correctionFactor.call(null,this._value,e);return this._value=t.reduce([this._value,e],(function(e,t,n,i){return e+Math.round(r*t)}),0)/r,this},subtract:function(e){var r=t.correctionFactor.call(null,this._value,e);return this._value=t.reduce([e],(function(e,t,n,i){return e-Math.round(r*t)}),Math.round(this._value*r))/r,this},multiply:function(e){return this._value=t.reduce([this._value,e],(function(e,r,n,i){var o=t.correctionFactor(e,r);return Math.round(e*o)*Math.round(r*o)/Math.round(o*o)}),1),this},divide:function(e){return this._value=t.reduce([this._value,e],(function(e,r,n,i){var o=t.correctionFactor(e,r);return Math.round(e*o)/Math.round(r*o)})),this},difference:function(t){return Math.abs(e(this._value).subtract(t).value())}},e.register("locale","en",{delimiters:{thousands:",",decimal:"."},abbreviations:{thousand:"k",million:"m",billion:"b",trillion:"t"},ordinal:function(e){var t=e%10;return 1==~~(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th"},currency:{symbol:"$"}}),e.register("format","bps",{regexps:{format:/(BPS)/,unformat:/(BPS)/},format:function(t,r,n){var i,o=e._.includes(r," BPS")?" ":"";return t*=1e4,r=r.replace(/\s?BPS/,""),i=e._.numberToFormat(t,r,n),e._.includes(i,")")?((i=i.split("")).splice(-1,0,o+"BPS"),i=i.join("")):i=i+o+"BPS",i},unformat:function(t){return+(1e-4*e._.stringToNumber(t)).toFixed(15)}}),n={base:1024,suffixes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},i="("+(i=(r={base:1e3,suffixes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}).suffixes.concat(n.suffixes.filter((function(e){return r.suffixes.indexOf(e)<0}))).join("|")).replace("B","B(?!PS)")+")",e.register("format","bytes",{regexps:{format:/([0\s]i?b)/,unformat:new RegExp(i)},format:function(t,i,o){var a,s,u,f=e._.includes(i,"ib")?n:r,c=e._.includes(i," b")||e._.includes(i," ib")?" ":"";for(i=i.replace(/\s?i?b/,""),a=0;a<=f.suffixes.length;a++)if(s=Math.pow(f.base,a),u=Math.pow(f.base,a+1),null===t||0===t||t>=s&&t0&&(t/=s);break}return e._.numberToFormat(t,i,o)+c},unformat:function(t){var i,o,a=e._.stringToNumber(t);if(a){for(i=r.suffixes.length-1;i>=0;i--){if(e._.includes(t,r.suffixes[i])){o=Math.pow(r.base,i);break}if(e._.includes(t,n.suffixes[i])){o=Math.pow(n.base,i);break}}a*=o||1}return a}}),e.register("format","currency",{regexps:{format:/(\$)/},format:function(t,r,n){var i,o,a=e.locales[e.options.currentLocale],s={before:r.match(/^([\+|\-|\(|\s|\$]*)/)[0],after:r.match(/([\+|\-|\)|\s|\$]*)$/)[0]};for(r=r.replace(/\s?\$\s?/,""),i=e._.numberToFormat(t,r,n),t>=0?(s.before=s.before.replace(/[\-\(]/,""),s.after=s.after.replace(/[\-\)]/,"")):t<0&&!e._.includes(s.before,"-")&&!e._.includes(s.before,"(")&&(s.before="-"+s.before),o=0;o=0;o--)switch(s.after[o]){case"$":i=o===s.after.length-1?i+a.currency.symbol:e._.insert(i,a.currency.symbol,-(s.after.length-(1+o)));break;case" ":i=o===s.after.length-1?i+" ":e._.insert(i," ",-(s.after.length-(1+o)+a.currency.symbol.length-1))}return i}}),e.register("format","exponential",{regexps:{format:/(e\+|e-)/,unformat:/(e\+|e-)/},format:function(t,r,n){var i=("number"!=typeof t||e._.isNaN(t)?"0e+0":t.toExponential()).split("e");return r=r.replace(/e[\+|\-]{1}0/,""),e._.numberToFormat(Number(i[0]),r,n)+"e"+i[1]},unformat:function(t){var r=e._.includes(t,"e+")?t.split("e+"):t.split("e-"),n=Number(r[0]),i=Number(r[1]);return i=e._.includes(t,"e-")?i*=-1:i,e._.reduce([n,Math.pow(10,i)],(function(t,r,n,i){var o=e._.correctionFactor(t,r);return t*o*(r*o)/(o*o)}),1)}}),e.register("format","ordinal",{regexps:{format:/(o)/},format:function(t,r,n){var i=e.locales[e.options.currentLocale],o=e._.includes(r," o")?" ":"";return r=r.replace(/\s?o/,""),o+=i.ordinal(t),e._.numberToFormat(t,r,n)+o}}),e.register("format","percentage",{regexps:{format:/(%)/,unformat:/(%)/},format:function(t,r,n){var i,o=e._.includes(r," %")?" ":"";return e.options.scalePercentBy100&&(t*=100),r=r.replace(/\s?\%/,""),i=e._.numberToFormat(t,r,n),e._.includes(i,")")?((i=i.split("")).splice(-1,0,o+"%"),i=i.join("")):i=i+o+"%",i},unformat:function(t){var r=e._.stringToNumber(t);return e.options.scalePercentBy100?.01*r:r}}),e.register("format","time",{regexps:{format:/(:)/,unformat:/(:)/},format:function(e,t,r){var n=Math.floor(e/60/60),i=Math.floor((e-60*n*60)/60),o=Math.round(e-60*n*60-60*i);return n+":"+(i<10?"0"+i:i)+":"+(o<10?"0"+o:o)},unformat:function(e){var t=e.split(":"),r=0;return 3===t.length?(r+=60*Number(t[0])*60,r+=60*Number(t[1]),r+=Number(t[2])):2===t.length&&(r+=60*Number(t[0]),r+=Number(t[1])),Number(r)}}),e})?n.call(t,r,t,e):n)||(e.exports=i)},aCH8:function(e,t,r){var n,i,o,a,s;n=r("ANhw"),i=r("mmNF").utf8,o=r("BEtg"),a=r("mmNF").bin,(s=function(e,t){e.constructor==String?e=t&&"binary"===t.encoding?a.stringToBytes(e):i.stringToBytes(e):o(e)?e=Array.prototype.slice.call(e,0):Array.isArray(e)||e.constructor===Uint8Array||(e=e.toString());for(var r=n.bytesToWords(e),u=8*e.length,f=1732584193,c=-271733879,l=-1732584194,h=271733878,d=0;d>>24)|4278255360&(r[d]<<24|r[d]>>>8);r[u>>>5]|=128<>>9<<4)]=u;var p=s._ff,g=s._gg,m=s._hh,y=s._ii;for(d=0;d>>0,c=c+v>>>0,l=l+w>>>0,h=h+_>>>0}return n.endian([f,c,l,h])})._ff=function(e,t,r,n,i,o,a){var s=e+(t&r|~t&n)+(i>>>0)+a;return(s<>>32-o)+t},s._gg=function(e,t,r,n,i,o,a){var s=e+(t&n|r&~n)+(i>>>0)+a;return(s<>>32-o)+t},s._hh=function(e,t,r,n,i,o,a){var s=e+(t^r^n)+(i>>>0)+a;return(s<