/*! * BootstrapVue 2.5.0 * * @link https://bootstrap-vue.js.org * @source https://github.com/bootstrap-vue/bootstrap-vue * @copyright (c) 2016-2020 BootstrapVue * @license MIT * https://github.com/bootstrap-vue/bootstrap-vue/blob/master/LICENSE */ import Vue from 'vue'; import { mergeData } from 'vue-functional-data-merge'; import Popper from 'popper.js'; import { Wormhole, PortalTarget, Portal } from 'portal-vue'; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; }; } else { _typeof = function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } // // --- Static --- var from = function from() { return Array.from.apply(Array, arguments); }; var isArray = function isArray(val) { return Array.isArray(val); }; // --- Instance --- var arrayIncludes = function arrayIncludes(array, value) { return array.indexOf(value) !== -1; }; var concat = function concat() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return Array.prototype.concat.apply([], args); }; var assign = function assign() { return Object.assign.apply(Object, arguments); }; var create = function create(proto, optionalProps) { return Object.create(proto, optionalProps); }; var defineProperties = function defineProperties(obj, props) { return Object.defineProperties(obj, props); }; var defineProperty = function defineProperty(obj, prop, descr) { return Object.defineProperty(obj, prop, descr); }; var freeze = function freeze(obj) { return Object.freeze(obj); }; var getOwnPropertyNames = function getOwnPropertyNames(obj) { return Object.getOwnPropertyNames(obj); }; var keys = function keys(obj) { return Object.keys(obj); }; // --- "Instance" --- var hasOwnProperty = function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }; var toString = function toString(obj) { return Object.prototype.toString.call(obj); }; // --- Utilities --- /** * Quick object check - this is primarily used to tell * Objects from primitive values when we know the value * is a JSON-compliant type. * Note object could be a complex type like array, date, etc. */ var isObject = function isObject(obj) { return obj !== null && _typeof(obj) === 'object'; }; /** * Strict object type check. Only returns true * for plain JavaScript objects. */ var isPlainObject = function isPlainObject(obj) { return Object.prototype.toString.call(obj) === '[object Object]'; }; /** * Shallow copy an object. If the passed in object * is null or undefined, returns an empty object */ var clone = function clone(obj) { return _objectSpread2({}, obj); }; /** * Return a shallow copy of object with * the specified properties omitted * @link https://gist.github.com/bisubus/2da8af7e801ffd813fab7ac221aa7afc */ var omit = function omit(obj, props) { return keys(obj).filter(function (key) { return props.indexOf(key) === -1; }).reduce(function (result, key) { return _objectSpread2({}, result, _defineProperty({}, key, obj[key])); }, {}); }; /** * Convenience method to create a read-only descriptor */ var readonlyDescriptor = function readonlyDescriptor() { return { enumerable: true, configurable: false, writable: false }; }; /** * Deep-freezes and object, making it immutable / read-only. * Returns the same object passed-in, but frozen. * Freezes inner object/array/values first. * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze * Note: this method will not work for property values using Symbol() as a key */ var deepFreeze = function deepFreeze(obj) { // Retrieve the property names defined on object/array // Note: `keys` will ignore properties that are keyed by a `Symbol()` var props = keys(obj); // Iterate over each prop and recursively freeze it props.forEach(function (prop) { var value = obj[prop]; // If value is a plain object or array, we deepFreeze it obj[prop] = value && (isPlainObject(value) || isArray(value)) ? deepFreeze(value) : value; }); return freeze(obj); }; /** * Utilities to get information about the current environment */ // --- Constants --- var hasWindowSupport = typeof window !== 'undefined'; var hasDocumentSupport = typeof document !== 'undefined'; var hasNavigatorSupport = typeof navigator !== 'undefined'; var hasPromiseSupport = typeof Promise !== 'undefined'; var hasMutationObserverSupport = typeof MutationObserver !== 'undefined' || typeof WebKitMutationObserver !== 'undefined' || typeof MozMutationObserver !== 'undefined'; var isBrowser = hasWindowSupport && hasDocumentSupport && hasNavigatorSupport; // Browser type sniffing var userAgent = isBrowser ? window.navigator.userAgent.toLowerCase() : ''; var isJSDOM = userAgent.indexOf('jsdom') > 0; var isIE = /msie|trident/.test(userAgent); // Determine if the browser supports the option passive for events var hasPassiveEventSupport = function () { var passiveEventSupported = false; if (isBrowser) { try { var options = { get passive() { // This function will be called when the browser // attempts to access the passive property. /* istanbul ignore next: will never be called in JSDOM */ passiveEventSupported = true; } }; window.addEventListener('test', options, options); window.removeEventListener('test', options, options); } catch (err) { /* istanbul ignore next: will never be called in JSDOM */ passiveEventSupported = false; } } return passiveEventSupported; }(); var hasTouchSupport = isBrowser && ('ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0); var hasPointerEventSupport = isBrowser && Boolean(window.PointerEvent || window.MSPointerEvent); var hasIntersectionObserverSupport = isBrowser && 'IntersectionObserver' in window && 'IntersectionObserverEntry' in window && // Edge 15 and UC Browser lack support for `isIntersecting` // but we an use intersectionRatio > 0 instead // 'isIntersecting' in window.IntersectionObserverEntry.prototype && 'intersectionRatio' in window.IntersectionObserverEntry.prototype; // --- Getters --- var getEnv = function getEnv(key) { var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var env = typeof process !== 'undefined' && process ? process.env || {} : {}; if (!key) { /* istanbul ignore next */ return env; } return env[key] || fallback; }; var getNoWarn = function getNoWarn() { return getEnv('BOOTSTRAP_VUE_NO_WARN'); }; var w = hasWindowSupport ? window : {}; var Element$1 = hasWindowSupport ? w.Element : /*#__PURE__*/ function (_Object) { _inherits(Element, _Object); function Element() { _classCallCheck(this, Element); return _possibleConstructorReturn(this, _getPrototypeOf(Element).apply(this, arguments)); } return Element; }(_wrapNativeSuper(Object)); var HTMLElement = hasWindowSupport ? w.HTMLElement : /*#__PURE__*/ function (_Element) { _inherits(HTMLElement, _Element); function HTMLElement() { _classCallCheck(this, HTMLElement); return _possibleConstructorReturn(this, _getPrototypeOf(HTMLElement).apply(this, arguments)); } return HTMLElement; }(Element$1); var SVGElement = hasWindowSupport ? w.SVGElement : /*#__PURE__*/ function (_Element2) { _inherits(SVGElement, _Element2); function SVGElement() { _classCallCheck(this, SVGElement); return _possibleConstructorReturn(this, _getPrototypeOf(SVGElement).apply(this, arguments)); } return SVGElement; }(Element$1); var File = hasWindowSupport ? w.File : /*#__PURE__*/ function (_Object2) { _inherits(File, _Object2); function File() { _classCallCheck(this, File); return _possibleConstructorReturn(this, _getPrototypeOf(File).apply(this, arguments)); } return File; }(_wrapNativeSuper(Object)); var toType = function toType(val) { return _typeof(val); }; var toRawType = function toRawType(val) { return Object.prototype.toString.call(val).slice(8, -1); }; var isUndefined = function isUndefined(val) { return val === undefined; }; var isNull = function isNull(val) { return val === null; }; var isUndefinedOrNull = function isUndefinedOrNull(val) { return isUndefined(val) || isNull(val); }; var isFunction = function isFunction(val) { return toType(val) === 'function'; }; var isBoolean = function isBoolean(val) { return toType(val) === 'boolean'; }; var isString = function isString(val) { return toType(val) === 'string'; }; var isNumber = function isNumber(val) { return toType(val) === 'number'; }; var isDate = function isDate(val) { return val instanceof Date; }; var isEvent = function isEvent(val) { return val instanceof Event; }; var isFile = function isFile(val) { return val instanceof File; }; var isRegExp = function isRegExp(val) { return toRawType(val) === 'RegExp'; }; var isPromise = function isPromise(val) { return !isUndefinedOrNull(val) && isFunction(val.then) && isFunction(val.catch); }; // Extra convenience named re-exports var cloneDeep = function cloneDeep(obj) { var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : obj; if (isArray(obj)) { return obj.reduce(function (result, val) { return [].concat(_toConsumableArray(result), [cloneDeep(val, val)]); }, []); } if (isPlainObject(obj)) { return keys(obj).reduce(function (result, key) { return _objectSpread2({}, result, _defineProperty({}, key, cloneDeep(obj[key], obj[key]))); }, {}); } return defaultValue; }; var identity = function identity(x) { return x; }; var RX_ARRAY_NOTATION = /\[(\d+)]/g; /** * Get property defined by dot/array notation in string. * * @link https://gist.github.com/jeneg/9767afdcca45601ea44930ea03e0febf#gistcomment-1935901 * * @param {Object} obj * @param {string|Array} path * @param {*} defaultValue (optional) * @return {*} */ var get = function get(obj, path) { var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; // Handle array of path values path = isArray(path) ? path.join('.') : path; // If no path or no object passed if (!path || !isObject(obj)) { return defaultValue; } // Handle edge case where user has dot(s) in top-level item field key // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2762 // Switched to `in` operator vs `hasOwnProperty` to handle obj.prototype getters // https://github.com/bootstrap-vue/bootstrap-vue/issues/3463 if (path in obj) { return obj[path]; } // Handle string array notation (numeric indices only) path = String(path).replace(RX_ARRAY_NOTATION, '.$1'); var steps = path.split('.').filter(identity); // Handle case where someone passes a string of only dots if (steps.length === 0) { return defaultValue; } // Traverse path in object to find result // We use `!=` vs `!==` to test for both `null` and `undefined` // Switched to `in` operator vs `hasOwnProperty` to handle obj.prototype getters // https://github.com/bootstrap-vue/bootstrap-vue/issues/3463 return steps.every(function (step) { return isObject(obj) && step in obj && (obj = obj[step]) != null; }) ? obj : defaultValue; }; /** * Log a warning message to the console with BootstrapVue formatting * @param {string} message */ var warn = function warn(message) /* istanbul ignore next */ { var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; if (!getNoWarn()) { console.warn("[BootstrapVue warn]: ".concat(source ? "".concat(source, " - ") : '').concat(message)); } }; /** * Warn when no Promise support is given * @param {string} source * @returns {boolean} warned */ var warnNotClient = function warnNotClient(source) { /* istanbul ignore else */ if (isBrowser) { return false; } else { warn("".concat(source, ": Can not be called during SSR.")); return true; } }; /** * Warn when no Promise support is given * @param {string} source * @returns {boolean} warned */ var warnNoPromiseSupport = function warnNoPromiseSupport(source) { /* istanbul ignore else */ if (hasPromiseSupport) { return false; } else { warn("".concat(source, ": Requires Promise support.")); return true; } }; /** * Warn when no MutationObserver support is given * @param {string} source * @returns {boolean} warned */ var warnNoMutationObserverSupport = function warnNoMutationObserverSupport(source) { /* istanbul ignore else */ if (hasMutationObserverSupport) { return false; } else { warn("".concat(source, ": Requires MutationObserver support.")); return true; } }; // NOTES // // The global config SHALL NOT be used to set defaults for Boolean props, as the props // would loose their semantic meaning, and force people writing 3rd party components to // explicity set a true or false value using the v-bind syntax on boolean props // // Supported config values (depending on the prop's supported type(s)): // `String`, `Array`, `Object`, `null` or `undefined` // BREAKPOINT DEFINITIONS // // Some components (`` and ``) generate props based on breakpoints, // and this occurs when the component is first loaded (evaluated), which may happen // before the config is created/modified // // To get around this we make these components' props async (lazy evaluation) // The component definition is only called/executed when the first access to the // component is used (and cached on subsequent uses) // PROP DEFAULTS // // For default values on props, we use the default value factory function approach so // that the default values are pulled in at each component instantiation // // props: { // variant: { // type: String, // default: () => getConfigComponent('BAlert', 'variant') // } // } // // We also provide a cached getter for breakpoints, which are "frozen" on first access // prettier-ignore var DEFAULTS = deepFreeze({ // Breakpoints breakpoints: ['xs', 'sm', 'md', 'lg', 'xl'], // Form controls formControls: { size: null }, // Component specific defaults are keyed by the component // name (PascalCase) and prop name (camelCase) BAlert: { dismissLabel: 'Close', variant: 'info' }, BBadge: { variant: 'secondary' }, BButton: { size: null, variant: 'secondary' }, BButtonClose: { content: '×', // `textVariant` is `null` to inherit the current text color textVariant: null, ariaLabel: 'Close' }, BCalendar: { // BFormDate will choose these first if not provided in BFormDate section labelPrevYear: 'Previous year', labelPrevMonth: 'Previous month', labelCurrentMonth: 'Current month', labelNextMonth: 'Next month', labelNextYear: 'Next year', labelToday: 'Today', labelSelected: 'Selected date', labelNoDateSelected: 'No date selected', labelCalendar: 'Calendar', labelNav: 'Calendar navigation', labelHelp: 'Use cursor keys to navigate calendar dates' }, BCardSubTitle: { // `` and `` also inherit this prop subTitleTextVariant: 'muted' }, BCarousel: { labelPrev: 'Previous Slide', labelNext: 'Next Slide', labelGotoSlide: 'Goto Slide', labelIndicators: 'Select a slide to display' }, BDropdown: { toggleText: 'Toggle Dropdown', size: null, variant: 'secondary', splitVariant: null }, BFormDatepicker: { // BFormDatepicker will choose from BCalendar first if not provided in BFormDatepicker section labelPrevYear: null, labelPrevMonth: null, labelCurrentMonth: null, labelNextMonth: null, labelNextYear: null, labelToday: null, labelSelected: null, labelNoDateSelected: null, labelCalendar: null, labelNav: null, labelHelp: null, // These props are specific to BFormDatepicker labelTodayButton: 'Select today', labelResetButton: 'Reset', labelCloseButton: 'Close' }, BFormFile: { browseText: 'Browse', // Chrome default file prompt placeholder: 'No file chosen', dropPlaceholder: 'Drop files here' }, BFormSpinbutton: { labelDecrement: 'Decrement', labelIncrement: 'Increment' }, BFormTag: { removeLabel: 'Remove tag', variant: 'secondary' }, BFormTags: { addButtonText: 'Add', addButtonVariant: 'outline-secondary', duplicateTagText: 'Duplicate tag(s)', invalidTagText: 'Invalid tag(s)', placeholder: 'Add tag...', tagRemoveLabel: 'Remove tag', tagRemovedLabel: 'Tag removed', tagVariant: 'secondary' }, BFormText: { textVariant: 'muted' }, BImg: { blankColor: 'transparent' }, BImgLazy: { blankColor: 'transparent' }, BInputGroup: { size: null }, BJumbotron: { bgVariant: null, borderVariant: null, textVariant: null }, BListGroupItem: { variant: null }, BModal: { titleTag: 'h5', size: 'md', headerBgVariant: null, headerBorderVariant: null, headerTextVariant: null, headerCloseVariant: null, bodyBgVariant: null, bodyTextVariant: null, footerBgVariant: null, footerBorderVariant: null, footerTextVariant: null, cancelTitle: 'Cancel', cancelVariant: 'secondary', okTitle: 'OK', okVariant: 'primary', headerCloseContent: '×', headerCloseLabel: 'Close' }, BNavbar: { variant: null }, BNavbarToggle: { label: 'Toggle navigation' }, BPagination: { size: null }, BPaginationNav: { size: null }, BPopover: { boundary: 'scrollParent', boundaryPadding: 5, customClass: null, delay: 50, variant: null }, BProgress: { variant: null }, BProgressBar: { variant: null }, BSpinner: { variant: null }, BTable: { selectedVariant: 'active', headVariant: null, footVariant: null }, BToast: { toaster: 'b-toaster-top-right', autoHideDelay: 5000, variant: null, toastClass: null, headerClass: null, bodyClass: null }, BToaster: { ariaLive: null, ariaAtomic: null, role: null }, BTooltip: { boundary: 'scrollParent', boundaryPadding: 5, customClass: null, delay: 50, variant: null } }); var NAME = 'BvConfig'; var PROP_NAME = '$bvConfig'; // Config manager class var BvConfig = /*#__PURE__*/ function () { function BvConfig() { _classCallCheck(this, BvConfig); // TODO: pre-populate with default config values (needs updated tests) // this.$_config = cloneDeep(DEFAULTS) this.$_config = {}; this.$_cachedBreakpoints = null; } _createClass(BvConfig, [{ key: "getDefaults", // Returns the defaults value: function getDefaults() /* istanbul ignore next */ { return this.defaults; } // Method to merge in user config parameters }, { key: "setConfig", value: function setConfig() { var _this = this; var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (!isPlainObject(config)) { /* istanbul ignore next */ return; } var configKeys = getOwnPropertyNames(config); configKeys.forEach(function (cmpName) { /* istanbul ignore next */ if (!hasOwnProperty(DEFAULTS, cmpName)) { warn("Unknown config property \"".concat(cmpName, "\""), NAME); return; } var cmpConfig = config[cmpName]; if (cmpName === 'breakpoints') { // Special case for breakpoints var breakpoints = config.breakpoints; /* istanbul ignore if */ if (!isArray(breakpoints) || breakpoints.length < 2 || breakpoints.some(function (b) { return !isString(b) || b.length === 0; })) { warn('"breakpoints" must be an array of at least 2 breakpoint names', NAME); } else { _this.$_config.breakpoints = cloneDeep(breakpoints); } } else if (isPlainObject(cmpConfig)) { // Component prop defaults var props = getOwnPropertyNames(cmpConfig); props.forEach(function (prop) { /* istanbul ignore if */ if (!hasOwnProperty(DEFAULTS[cmpName], prop)) { warn("Unknown config property \"".concat(cmpName, ".").concat(prop, "\""), NAME); } else { // TODO: If we pre-populate the config with defaults, we can skip this line _this.$_config[cmpName] = _this.$_config[cmpName] || {}; if (!isUndefined(cmpConfig[prop])) { _this.$_config[cmpName][prop] = cloneDeep(cmpConfig[prop]); } } }); } }); } // Clear the config. For testing purposes only }, { key: "resetConfig", value: function resetConfig() { this.$_config = {}; } // Returns a deep copy of the user config }, { key: "getConfig", value: function getConfig() { return cloneDeep(this.$_config); } }, { key: "getConfigValue", value: function getConfigValue(key) { // First we try the user config, and if key not found we fall back to default value // NOTE: If we deep clone DEFAULTS into config, then we can skip the fallback for get return cloneDeep(get(this.$_config, key, get(DEFAULTS, key))); } }, { key: "defaults", get: function get() /* istanbul ignore next */ { return DEFAULTS; } }], [{ key: "Defaults", get: function get() /* istanbul ignore next */ { return DEFAULTS; } }]); return BvConfig; }(); // Method for applying a global config var setConfig = function setConfig() { var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var Vue$1 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Vue; // Ensure we have a $bvConfig Object on the Vue prototype. // We set on Vue and OurVue just in case consumer has not set an alias of `vue`. Vue$1.prototype[PROP_NAME] = Vue.prototype[PROP_NAME] = Vue$1.prototype[PROP_NAME] || Vue.prototype[PROP_NAME] || new BvConfig(); // Apply the config values Vue$1.prototype[PROP_NAME].setConfig(config); }; // Method for resetting the user config. Exported for testing purposes only. /** * Checks if there are multiple instances of Vue, and warns (once) about possible issues. * @param {object} Vue */ var checkMultipleVue = function () { var checkMultipleVueWarned = false; var MULTIPLE_VUE_WARNING = ['Multiple instances of Vue detected!', 'You may need to set up an alias for Vue in your bundler config.', 'See: https://bootstrap-vue.js.org/docs#using-module-bundlers'].join('\n'); return function (Vue$1) { /* istanbul ignore next */ if (!checkMultipleVueWarned && Vue !== Vue$1 && !isJSDOM) { warn(MULTIPLE_VUE_WARNING); } checkMultipleVueWarned = true; }; }(); /** * Plugin install factory function. * @param {object} { components, directives } * @returns {function} plugin install function */ var installFactory = function installFactory() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, components = _ref.components, directives = _ref.directives, plugins = _ref.plugins; var install = function install(Vue) { var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (install.installed) { /* istanbul ignore next */ return; } install.installed = true; checkMultipleVue(Vue); setConfig(config, Vue); registerComponents(Vue, components); registerDirectives(Vue, directives); registerPlugins(Vue, plugins); }; install.installed = false; return install; }; /** * Plugin install factory function (no plugin config option). * @param {object} { components, directives } * @returns {function} plugin install function */ var installFactoryNoConfig = function installFactoryNoConfig() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, components = _ref2.components, directives = _ref2.directives, plugins = _ref2.plugins; var install = function install(Vue) { if (install.installed) { /* istanbul ignore next */ return; } install.installed = true; checkMultipleVue(Vue); registerComponents(Vue, components); registerDirectives(Vue, directives); registerPlugins(Vue, plugins); }; install.installed = false; return install; }; /** * Plugin object factory function. * @param {object} { components, directives, plugins } * @returns {object} plugin install object */ var pluginFactory = function pluginFactory() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var extend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return _objectSpread2({}, extend, { install: installFactory(options) }); }; /** * Plugin object factory function (no config option). * @param {object} { components, directives, plugins } * @returns {object} plugin install object */ var pluginFactoryNoConfig = function pluginFactoryNoConfig() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var extend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return _objectSpread2({}, extend, { install: installFactoryNoConfig(options) }); }; /** * Load a group of plugins. * @param {object} Vue * @param {object} Plugin definitions */ var registerPlugins = function registerPlugins(Vue) { var plugins = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; for (var plugin in plugins) { if (plugin && plugins[plugin]) { Vue.use(plugins[plugin]); } } }; /** * Load a component. * @param {object} Vue * @param {string} Component name * @param {object} Component definition */ var registerComponent = function registerComponent(Vue, name, def) { if (Vue && name && def) { Vue.component(name, def); } }; /** * Load a group of components. * @param {object} Vue * @param {object} Object of component definitions */ var registerComponents = function registerComponents(Vue) { var components = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; for (var component in components) { registerComponent(Vue, component, components[component]); } }; /** * Load a directive. * @param {object} Vue * @param {string} Directive name * @param {object} Directive definition */ var registerDirective = function registerDirective(Vue, name, def) { if (Vue && name && def) { // Ensure that any leading V is removed from the // name, as Vue adds it automatically Vue.directive(name.replace(/^VB/, 'B'), def); } }; /** * Load a group of directives. * @param {object} Vue * @param {object} Object of directive definitions */ var registerDirectives = function registerDirectives(Vue) { var directives = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; for (var directive in directives) { registerDirective(Vue, directive, directives[directive]); } }; var memoize = function memoize(fn) { var cache = create(null); return function () { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var argsKey = JSON.stringify(args); return cache[argsKey] = cache[argsKey] || fn.apply(null, args); }; }; var PROP_NAME$1 = '$bvConfig'; var VueProto = Vue.prototype; // --- Getter methods --- var getConfigValue = function getConfigValue(key) { return VueProto[PROP_NAME$1] ? VueProto[PROP_NAME$1].getConfigValue(key) : cloneDeep(get(DEFAULTS, key)); }; // Method to grab a config value for a particular component var getComponentConfig = function getComponentConfig(cmpName) { var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; // Return the particular config value for key for if specified, // otherwise we return the full config (or an empty object if not found) return key ? getConfigValue("".concat(cmpName, ".").concat(key)) : getConfigValue(cmpName) || {}; }; // Convenience method for getting all breakpoint names var getBreakpoints = function getBreakpoints() { return getConfigValue('breakpoints'); }; // Private function for caching / locking-in breakpoint names var _getBreakpointsCached = memoize(function () { return getBreakpoints(); }); // Convenience method for getting all breakpoint names. // Caches the results after first access. var getBreakpointsCached = function getBreakpointsCached() { return cloneDeep(_getBreakpointsCached()); }; // Convenience method for getting breakpoints with // the smallest breakpoint set as ''. // Useful for components that create breakpoint specific props. // Caches the results after first access. var getBreakpointsUpCached = memoize(function () { var breakpoints = getBreakpointsCached(); breakpoints[0] = ''; return breakpoints; }); // Convenience method for getting breakpoints with var w$1 = hasWindowSupport ? window : {}; var d = hasDocumentSupport ? document : {}; var elProto = typeof Element !== 'undefined' ? Element.prototype : {}; // --- Normalization utils --- // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill /* istanbul ignore next */ var matchesEl = elProto.matches || elProto.msMatchesSelector || elProto.webkitMatchesSelector; // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/closest /* istanbul ignore next */ var closestEl = elProto.closest || function (sel) /* istanbul ignore next */ { var el = this; do { // Use our "patched" matches function if (matches(el, sel)) { return el; } el = el.parentElement || el.parentNode; } while (!isNull(el) && el.nodeType === Node.ELEMENT_NODE); return null; }; // `requestAnimationFrame()` convenience method var requestAF = w$1.requestAnimationFrame || w$1.webkitRequestAnimationFrame || w$1.mozRequestAnimationFrame || w$1.msRequestAnimationFrame || w$1.oRequestAnimationFrame || // Fallback, but not a true polyfill // Only needed for Opera Mini /* istanbul ignore next */ function (cb) { return setTimeout(cb, 16); }; var MutationObs = w$1.MutationObserver || w$1.WebKitMutationObserver || w$1.MozMutationObserver || null; // --- Utils --- // Remove a node from DOM var removeNode = function removeNode(el) { return el && el.parentNode && el.parentNode.removeChild(el); }; // Determine if an element is an HTML element var isElement = function isElement(el) { return !!(el && el.nodeType === Node.ELEMENT_NODE); }; // Determine if an HTML element is visible - Faster than CSS check var isVisible = function isVisible(el) { if (!isElement(el) || !el.parentNode || !contains(d.body, el)) { // Note this can fail for shadow dom elements since they // are not a direct descendant of document.body return false; } if (el.style.display === 'none') { // We do this check to help with vue-test-utils when using v-show /* istanbul ignore next */ return false; } // All browsers support getBoundingClientRect(), except JSDOM as it returns all 0's for values :( // So any tests that need isVisible will fail in JSDOM // Except when we override the getBCR prototype in some tests var bcr = getBCR(el); return !!(bcr && bcr.height > 0 && bcr.width > 0); }; // Determine if an element is disabled var isDisabled = function isDisabled(el) { return !isElement(el) || el.disabled || hasAttr(el, 'disabled') || hasClass(el, 'disabled'); }; // Cause/wait-for an element to reflow its content (adjusting its height/width) var reflow = function reflow(el) { // Requesting an elements offsetHight will trigger a reflow of the element content /* istanbul ignore next: reflow doesn't happen in JSDOM */ return isElement(el) && el.offsetHeight; }; // Select all elements matching selector. Returns `[]` if none found var selectAll = function selectAll(selector, root) { return from((isElement(root) ? root : d).querySelectorAll(selector)); }; // Select a single element, returns `null` if not found var select = function select(selector, root) { return (isElement(root) ? root : d).querySelector(selector) || null; }; // Determine if an element matches a selector var matches = function matches(el, selector) { return isElement(el) ? matchesEl.call(el, selector) : false; }; // Finds closest element matching selector. Returns `null` if not found var closest = function closest(selector, root) { var includeRoot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; if (!isElement(root)) { return null; } var el = closestEl.call(root, selector); // Native closest behaviour when `includeRoot` is truthy, // else emulate jQuery closest and return `null` if match is // the passed in root element when `includeRoot` is falsey return includeRoot ? el : el === root ? null : el; }; // Returns true if the parent element contains the child element var contains = function contains(parent, child) { return parent && isFunction(parent.contains) ? parent.contains(child) : false; }; // Get an element given an ID var getById = function getById(id) { return d.getElementById(/^#/.test(id) ? id.slice(1) : id) || null; }; // Add a class to an element var addClass = function addClass(el, className) { // We are checking for `el.classList` existence here since IE 11 // returns `undefined` for some elements (e.g. SVG elements) // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2713 if (className && isElement(el) && el.classList) { el.classList.add(className); } }; // Remove a class from an element var removeClass = function removeClass(el, className) { // We are checking for `el.classList` existence here since IE 11 // returns `undefined` for some elements (e.g. SVG elements) // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2713 if (className && isElement(el) && el.classList) { el.classList.remove(className); } }; // Test if an element has a class var hasClass = function hasClass(el, className) { // We are checking for `el.classList` existence here since IE 11 // returns `undefined` for some elements (e.g. SVG elements) // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2713 if (className && isElement(el) && el.classList) { return el.classList.contains(className); } return false; }; // Set an attribute on an element var setAttr = function setAttr(el, attr, val) { if (attr && isElement(el)) { el.setAttribute(attr, val); } }; // Remove an attribute from an element var removeAttr = function removeAttr(el, attr) { if (attr && isElement(el)) { el.removeAttribute(attr); } }; // Get an attribute value from an element // Returns `null` if not found var getAttr = function getAttr(el, attr) { return attr && isElement(el) ? el.getAttribute(attr) : null; }; // Determine if an attribute exists on an element // Returns `true` or `false`, or `null` if element not found var hasAttr = function hasAttr(el, attr) { return attr && isElement(el) ? el.hasAttribute(attr) : null; }; // Return the Bounding Client Rect of an element // Returns `null` if not an element /* istanbul ignore next: getBoundingClientRect() doesn't work in JSDOM */ var getBCR = function getBCR(el) { return isElement(el) ? el.getBoundingClientRect() : null; }; // Get computed style object for an element /* istanbul ignore next: getComputedStyle() doesn't work in JSDOM */ var getCS = function getCS(el) { return hasWindowSupport && isElement(el) ? w$1.getComputedStyle(el) : {}; }; // Returns a `Selection` object representing the range of text selected // Returns `null` if no window support is given /* istanbul ignore next: getSelection() doesn't work in JSDOM */ var getSel = function getSel() { return hasWindowSupport && w$1.getSelection ? w$1.getSelection() : null; }; // Return an element's offset with respect to document element // https://j11y.io/jquery/#v=git&fn=jQuery.fn.offset var offset = function offset(el) /* istanbul ignore next: getBoundingClientRect(), getClientRects() doesn't work in JSDOM */ { var _offset = { top: 0, left: 0 }; if (!isElement(el) || el.getClientRects().length === 0) { return _offset; } var bcr = getBCR(el); if (bcr) { var win = el.ownerDocument.defaultView; _offset.top = bcr.top + win.pageYOffset; _offset.left = bcr.left + win.pageXOffset; } return _offset; }; // Return an element's offset with respect to to its offsetParent // https://j11y.io/jquery/#v=git&fn=jQuery.fn.position var position = function position(el) /* istanbul ignore next: getBoundingClientRect() doesn't work in JSDOM */ { var _offset = { top: 0, left: 0 }; if (!isElement(el)) { return _offset; } var parentOffset = { top: 0, left: 0 }; var elStyles = getCS(el); if (elStyles.position === 'fixed') { _offset = getBCR(el) || _offset; } else { _offset = offset(el); var doc = el.ownerDocument; var offsetParent = el.offsetParent || doc.documentElement; while (offsetParent && (offsetParent === doc.body || offsetParent === doc.documentElement) && getCS(offsetParent).position === 'static') { offsetParent = offsetParent.parentNode; } if (offsetParent && offsetParent !== el && offsetParent.nodeType === Node.ELEMENT_NODE) { parentOffset = offset(offsetParent); var offsetParentStyles = getCS(offsetParent); parentOffset.top += parseFloat(offsetParentStyles.borderTopWidth); parentOffset.left += parseFloat(offsetParentStyles.borderLeftWidth); } } return { top: _offset.top - parentOffset.top - parseFloat(elStyles.marginTop), left: _offset.left - parentOffset.left - parseFloat(elStyles.marginLeft) }; }; // Number utilities // Converts a value (string, number, etc) to an integer number // Assumes radix base 10 // Returns NaN if the value cannot be converted var toInteger = function toInteger(val) { return parseInt(val, 10); }; // Converts a value (string, number, etc) to a number // Returns NaN if the value cannot be converted var toFloat = function toFloat(val) { return parseFloat(val); }; // Converts a value (string, number, etc) to a string // representation with 'precision' digits after the decimal // Returns the string 'NaN' if the value cannot be converted var toFixed = function toFixed(val, precision) { return toFloat(val).toFixed(toInteger(precision) || 0); }; var NO_FADE_PROPS = { name: '', enterClass: '', enterActiveClass: '', enterToClass: 'show', leaveClass: 'show', leaveActiveClass: '', leaveToClass: '' }; var FADE_PROPS = _objectSpread2({}, NO_FADE_PROPS, { enterActiveClass: 'fade', leaveActiveClass: 'fade' }); // @vue/component var BVTransition = /*#__PURE__*/ Vue.extend({ name: 'BVTransition', functional: true, props: { noFade: { // Only applicable to the built in transition // Has no effect if `trans-props` provided type: Boolean, default: false }, appear: { // Has no effect if `trans-props` provided type: Boolean, default: false }, mode: { // Can be overridden by user supplied trans-props type: String // default: undefined }, // For user supplied transitions (if needed) transProps: { type: Object, default: null } }, render: function render(h, _ref) { var children = _ref.children, data = _ref.data, props = _ref.props; var transProps = props.transProps; if (!isPlainObject(transProps)) { transProps = props.noFade ? NO_FADE_PROPS : FADE_PROPS; if (props.appear) { // Default the appear classes to equal the enter classes transProps = _objectSpread2({}, transProps, { appear: true, appearClass: transProps.enterClass, appearActiveClass: transProps.enterActiveClass, appearToClass: transProps.enterToClass }); } } transProps = _objectSpread2({ mode: props.mode }, transProps, { // We always need `css` true css: true }); return h('transition', // Any transition event listeners will get merged here mergeData(data, { props: transProps }), children); } }); // In functional components, `slots` is a function so it must be called // first before passing to the below methods. `scopedSlots` is always an // object and may be undefined (for Vue < 2.6.x) /** * Returns true if either scoped or unscoped named slot exists * * @param {String, Array} name or name[] * @param {Object} scopedSlots * @param {Object} slots * @returns {Array|undefined} VNodes */ var hasNormalizedSlot = function hasNormalizedSlot(names) { var $scopedSlots = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var $slots = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; // Ensure names is an array names = concat(names).filter(identity); // Returns true if the either a $scopedSlot or $slot exists with the specified name return names.some(function (name) { return $scopedSlots[name] || $slots[name]; }); }; /** * Returns VNodes for named slot either scoped or unscoped * * @param {String, Array} name or name[] * @param {String} scope * @param {Object} scopedSlots * @param {Object} slots * @returns {Array|undefined} VNodes */ var normalizeSlot = function normalizeSlot(names) { var scope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var $scopedSlots = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var $slots = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; // Ensure names is an array names = concat(names).filter(identity); var slot; for (var i = 0; i < names.length && !slot; i++) { var name = names[i]; slot = $scopedSlots[name] || $slots[name]; } // Note: in Vue 2.6.x, all named slots are also scoped slots return isFunction(slot) ? slot(scope) : slot; }; // Named exports var normalizeSlotMixin = { methods: { hasNormalizedSlot: function hasNormalizedSlot$1(names) { // Returns true if the either a $scopedSlot or $slot exists with the specified name // `names` can be a string name or an array of names return hasNormalizedSlot(names, this.$scopedSlots, this.$slots); }, normalizeSlot: function normalizeSlot$1(names) { var scope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; // Returns an array of rendered VNodes if slot found. // Returns undefined if not found. // `names` can be a string name or an array of names var vNodes = normalizeSlot(names, scope, this.$scopedSlots, this.$slots); return vNodes ? concat(vNodes) : vNodes; } } }; var NAME$1 = 'BButtonClose'; var props = { content: { type: String, default: function _default() { return getComponentConfig(NAME$1, 'content'); } }, disabled: { type: Boolean, default: false }, ariaLabel: { type: String, default: function _default() { return getComponentConfig(NAME$1, 'ariaLabel'); } }, textVariant: { type: String, default: function _default() { return getComponentConfig(NAME$1, 'textVariant'); } } }; // @vue/component var BButtonClose = /*#__PURE__*/ Vue.extend({ name: NAME$1, functional: true, props: props, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, slots = _ref.slots, scopedSlots = _ref.scopedSlots; var $slots = slots(); var $scopedSlots = scopedSlots || {}; var componentData = { staticClass: 'close', class: _defineProperty({}, "text-".concat(props.textVariant), props.textVariant), attrs: { type: 'button', disabled: props.disabled, 'aria-label': props.ariaLabel ? String(props.ariaLabel) : null }, on: { click: function click(evt) { // Ensure click on button HTML content is also disabled /* istanbul ignore if: bug in JSDOM still emits click on inner element */ if (props.disabled && isEvent(evt)) { evt.stopPropagation(); evt.preventDefault(); } } } }; // Careful not to override the default slot with innerHTML if (!hasNormalizedSlot('default', $scopedSlots, $slots)) { componentData.domProps = { innerHTML: props.content }; } return h('button', mergeData(data, componentData), normalizeSlot('default', {}, $scopedSlots, $slots)); } }); var NAME$2 = 'BAlert'; // Convert `show` value to a number var parseCountDown = function parseCountDown(show) { if (show === '' || isBoolean(show)) { return 0; } show = toInteger(show); return show > 0 ? show : 0; }; // Convert `show` value to a boolean var parseShow = function parseShow(show) { if (show === '' || show === true) { return true; } if (toInteger(show) < 1) { // Boolean will always return false for the above comparison return false; } return !!show; }; // Is a value number like (i.e. a number or a number as string) var isNumericLike = function isNumericLike(value) { return !isNaN(toInteger(value)); }; // @vue/component var BAlert = /*#__PURE__*/ Vue.extend({ name: NAME$2, mixins: [normalizeSlotMixin], model: { prop: 'show', event: 'input' }, props: { variant: { type: String, default: function _default() { return getComponentConfig(NAME$2, 'variant'); } }, dismissible: { type: Boolean, default: false }, dismissLabel: { type: String, default: function _default() { return getComponentConfig(NAME$2, 'dismissLabel'); } }, show: { type: [Boolean, Number, String], default: false }, fade: { type: Boolean, default: false } }, data: function data() { return { countDownTimerId: null, countDown: 0, // If initially shown, we need to set these for SSR localShow: parseShow(this.show) }; }, watch: { show: function show(newVal) { this.countDown = parseCountDown(newVal); this.localShow = parseShow(newVal); }, countDown: function countDown(newVal) { var _this = this; this.clearTimer(); if (isNumericLike(this.show)) { // Ignore if this.show transitions to a boolean value. this.$emit('dismiss-count-down', newVal); if (this.show !== newVal) { // Update the v-model if needed this.$emit('input', newVal); } if (newVal > 0) { this.localShow = true; this.countDownTimerId = setTimeout(function () { _this.countDown--; }, 1000); } else { // Slightly delay the hide to allow any UI updates this.$nextTick(function () { requestAF(function () { _this.localShow = false; }); }); } } }, localShow: function localShow(newVal) { if (!newVal && (this.dismissible || isNumericLike(this.show))) { // Only emit dismissed events for dismissible or auto dismissing alerts this.$emit('dismissed'); } if (!isNumericLike(this.show) && this.show !== newVal) { // Only emit booleans if we weren't passed a number via `this.show` this.$emit('input', newVal); } } }, created: function created() { this.countDown = parseCountDown(this.show); this.localShow = parseShow(this.show); }, mounted: function mounted() { this.countDown = parseCountDown(this.show); this.localShow = parseShow(this.show); }, beforeDestroy: function beforeDestroy() { this.clearTimer(); }, methods: { dismiss: function dismiss() { this.clearTimer(); this.countDown = 0; this.localShow = false; }, clearTimer: function clearTimer() { if (this.countDownTimerId) { clearInterval(this.countDownTimerId); this.countDownTimerId = null; } } }, render: function render(h) { var $alert; // undefined if (this.localShow) { var $dismissBtn = h(); if (this.dismissible) { // Add dismiss button $dismissBtn = h(BButtonClose, { attrs: { 'aria-label': this.dismissLabel }, on: { click: this.dismiss } }, [this.normalizeSlot('dismiss')]); } $alert = h('div', { key: this._uid, staticClass: 'alert', class: _defineProperty({ 'alert-dismissible': this.dismissible }, "alert-".concat(this.variant), this.variant), attrs: { role: 'alert', 'aria-live': 'polite', 'aria-atomic': true } }, [$dismissBtn, this.normalizeSlot('default')]); $alert = [$alert]; } return h(BVTransition, { props: { noFade: !this.fade } }, $alert); } }); var AlertPlugin = /*#__PURE__*/ pluginFactory({ components: { BAlert: BAlert } }); /** * Given an array of properties or an object of property keys, * plucks all the values off the target object, returning a new object * that has props that reference the original prop values * * @param {{}|string[]} keysToPluck * @param {{}} objToPluck * @param {Function} transformFn * @return {{}} */ var pluckProps = function pluckProps(keysToPluck, objToPluck) { var transformFn = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : identity; return (isArray(keysToPluck) ? keysToPluck.slice() : keys(keysToPluck)).reduce(function (memo, prop) { memo[transformFn(prop)] = objToPluck[prop]; return memo; }, {}); }; // String utilities var RX_TRIM_LEFT = /^\s+/; var RX_REGEXP_REPLACE = /[-/\\^$*+?.()|[\]{}]/g; var RX_UN_KEBAB = /-(\w)/g; var RX_HYPHENATE = /\B([A-Z])/g; // --- Utilities --- // Converts PascalCase or camelCase to kebab-case var kebabCase = function kebabCase(str) { return str.replace(RX_HYPHENATE, '-$1').toLowerCase(); }; // Converts a kebab-case or camelCase string to PascalCase var pascalCase = function pascalCase(str) { str = kebabCase(str).replace(RX_UN_KEBAB, function (_, c) { return c ? c.toUpperCase() : ''; }); return str.charAt(0).toUpperCase() + str.slice(1); }; // Lowercases the first letter of a string and returns a new string var lowerFirst = function lowerFirst(str) { str = isString(str) ? str.trim() : String(str); return str.charAt(0).toLowerCase() + str.slice(1); }; // Uppercases the first letter of a string and returns a new string var upperFirst = function upperFirst(str) { str = isString(str) ? str.trim() : String(str); return str.charAt(0).toUpperCase() + str.slice(1); }; // Escape characters to be used in building a regular expression var escapeRegExp = function escapeRegExp(str) { return str.replace(RX_REGEXP_REPLACE, '\\$&'); }; // Convert a value to a string that can be rendered // `undefined`/`null` will be converted to `''` // Plain objects and arrays will be JSON stringified var toString$1 = function toString(val) { var spaces = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; return isUndefinedOrNull(val) ? '' : isArray(val) || isPlainObject(val) && val.toString === Object.prototype.toString ? JSON.stringify(val, null, spaces) : String(val); }; // Remove leading white space from a string var trimLeft = function trimLeft(str) { return toString$1(str).replace(RX_TRIM_LEFT, ''); }; // Remove Trailing white space from a string var trim = function trim(str) { return toString$1(str).trim(); }; // Lower case a string var lowerCase = function lowerCase(str) { return toString$1(str).toLowerCase(); }; // Upper case a string var ANCHOR_TAG = 'a'; // Precompile RegExp var commaRE = /%2C/g; var encodeReserveRE = /[!'()*]/g; var plusRE = /\+/g; var queryStartRE = /^(\?|#|&)/; // Method to replace reserved chars var encodeReserveReplacer = function encodeReserveReplacer(c) { return '%' + c.charCodeAt(0).toString(16); }; // Fixed encodeURIComponent which is more conformant to RFC3986: // - escapes [!'()*] // - preserve commas var encode = function encode(str) { return encodeURIComponent(toString$1(str)).replace(encodeReserveRE, encodeReserveReplacer).replace(commaRE, ','); }; var decode = decodeURIComponent; // Stringifies an object of query parameters // See: https://github.com/vuejs/vue-router/blob/dev/src/util/query.js var stringifyQueryObj = function stringifyQueryObj(obj) { if (!isPlainObject(obj)) { return ''; } var query = keys(obj).map(function (key) { var val = obj[key]; if (isUndefined(val)) { return ''; } else if (isNull(val)) { return encode(key); } else if (isArray(val)) { return val.reduce(function (results, val2) { if (isNull(val2)) { results.push(encode(key)); } else if (!isUndefined(val2)) { // Faster than string interpolation results.push(encode(key) + '=' + encode(val2)); } return results; }, []).join('&'); } // Faster than string interpolation return encode(key) + '=' + encode(val); }) /* must check for length, as we only want to filter empty strings, not things that look falsey! */ .filter(function (x) { return x.length > 0; }).join('&'); return query ? "?".concat(query) : ''; }; var parseQuery = function parseQuery(query) { var parsed = {}; query = toString$1(query).trim().replace(queryStartRE, ''); if (!query) { return parsed; } query.split('&').forEach(function (param) { var parts = param.replace(plusRE, ' ').split('='); var key = decode(parts.shift()); var val = parts.length > 0 ? decode(parts.join('=')) : null; if (isUndefined(parsed[key])) { parsed[key] = val; } else if (isArray(parsed[key])) { parsed[key].push(val); } else { parsed[key] = [parsed[key], val]; } }); return parsed; }; var isRouterLink = function isRouterLink(tag) { return toString$1(tag).toLowerCase() !== ANCHOR_TAG; }; var computeTag = function computeTag() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, to = _ref.to, disabled = _ref.disabled; var thisOrParent = arguments.length > 1 ? arguments[1] : undefined; return thisOrParent.$router && to && !disabled ? thisOrParent.$nuxt ? 'nuxt-link' : 'router-link' : ANCHOR_TAG; }; var computeRel = function computeRel() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, target = _ref2.target, rel = _ref2.rel; if (target === '_blank' && isNull(rel)) { return 'noopener'; } return rel || null; }; var computeHref = function computeHref() { var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, href = _ref3.href, to = _ref3.to; var tag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ANCHOR_TAG; var fallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '#'; var toFallback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '/'; // We've already checked the $router in computeTag(), so isRouterLink() indicates a live router. // When deferring to Vue Router's router-link, don't use the href attribute at all. // We return null, and then remove href from the attributes passed to router-link if (isRouterLink(tag)) { return null; } // Return `href` when explicitly provided if (href) { return href; } // Reconstruct `href` when `to` used, but no router if (to) { // Fallback to `to` prop (if `to` is a string) if (isString(to)) { return to || toFallback; } // Fallback to `to.path + to.query + to.hash` prop (if `to` is an object) if (isPlainObject(to) && (to.path || to.query || to.hash)) { var path = toString$1(to.path); var query = stringifyQueryObj(to.query); var hash = toString$1(to.hash); hash = !hash || hash.charAt(0) === '#' ? hash : "#".concat(hash); return "".concat(path).concat(query).concat(hash) || toFallback; } } // If nothing is provided return the fallback return fallback; }; /** * The Link component is used in many other BV components. * As such, sharing its props makes supporting all its features easier. * However, some components need to modify the defaults for their own purpose. * Prefer sharing a fresh copy of the props to ensure mutations * do not affect other component references to the props. * * https://github.com/vuejs/vue-router/blob/dev/src/components/link.js * @return {{}} */ var propsFactory = function propsFactory() { return { href: { type: String, default: null }, rel: { type: String, default: null }, target: { type: String, default: '_self' }, active: { type: Boolean, default: false }, disabled: { type: Boolean, default: false }, // router-link specific props to: { type: [String, Object], default: null }, append: { type: Boolean, default: false }, replace: { type: Boolean, default: false }, event: { type: [String, Array], default: 'click' }, activeClass: { type: String // default: undefined }, exact: { type: Boolean, default: false }, exactActiveClass: { type: String // default: undefined }, routerTag: { type: String, default: 'a' }, // nuxt-link specific prop(s) noPrefetch: { type: Boolean, default: false } }; }; var BLink = /*#__PURE__*/ Vue.extend({ name: 'BLink', mixins: [normalizeSlotMixin], inheritAttrs: false, props: propsFactory(), computed: { computedTag: function computedTag() { // We don't pass `this` as the first arg as we need reactivity of the props return computeTag({ to: this.to, disabled: this.disabled }, this); }, isRouterLink: function isRouterLink$1() { return isRouterLink(this.computedTag); }, computedRel: function computedRel() { // We don't pass `this` as the first arg as we need reactivity of the props return computeRel({ target: this.target, rel: this.rel }); }, computedHref: function computedHref() { // We don't pass `this` as the first arg as we need reactivity of the props return computeHref({ to: this.to, href: this.href }, this.computedTag); }, computedProps: function computedProps() { return this.isRouterLink ? _objectSpread2({}, this.$props, { tag: this.routerTag }) : {}; } }, methods: { onClick: function onClick(evt) { var _arguments = arguments; var evtIsEvent = isEvent(evt); var isRouterLink = this.isRouterLink; var suppliedHandler = this.$listeners.click; if (evtIsEvent && this.disabled) { // Stop event from bubbling up evt.stopPropagation(); // Kill the event loop attached to this specific `EventTarget` // Needed to prevent `vue-router` for doing its thing evt.stopImmediatePropagation(); } else { /* istanbul ignore next: difficult to test, but we know it works */ if (isRouterLink && evt.currentTarget.__vue__) { // Router links do not emit instance `click` events, so we // add in an `$emit('click', evt)` on its Vue instance evt.currentTarget.__vue__.$emit('click', evt); } // Call the suppliedHandler(s), if any provided concat(suppliedHandler).filter(function (h) { return isFunction(h); }).forEach(function (handler) { handler.apply(void 0, _toConsumableArray(_arguments)); }); // Emit the global `$root` click event this.$root.$emit('clicked::link', evt); } // Stop scroll-to-top behavior or navigation on // regular links when href is just '#' if (evtIsEvent && (this.disabled || !isRouterLink && this.computedHref === '#')) { evt.preventDefault(); } }, focus: function focus() { if (this.$el && this.$el.focus) { this.$el.focus(); } }, blur: function blur() { if (this.$el && this.$el.blur) { this.$el.blur(); } } }, render: function render(h) { var tag = this.computedTag; var rel = this.computedRel; var href = this.computedHref; var isRouterLink = this.isRouterLink; var componentData = { class: { active: this.active, disabled: this.disabled }, attrs: _objectSpread2({}, this.$attrs, { rel: rel, target: this.target, tabindex: this.disabled ? '-1' : isUndefined(this.$attrs.tabindex) ? null : this.$attrs.tabindex, 'aria-disabled': this.disabled ? 'true' : null }), props: this.computedProps }; // Add the event handlers. We must use `nativeOn` for // ``/`` instead of `on` componentData[isRouterLink ? 'nativeOn' : 'on'] = _objectSpread2({}, this.$listeners, { // We want to overwrite any click handler since our callback // will invoke the user supplied handler(s) if `!this.disabled` click: this.onClick }); // If href attribute exists on (even undefined or null) it fails working on // SSR, so we explicitly add it here if needed (i.e. if computedHref() is truthy) if (href) { componentData.attrs.href = href; } else { // Ensure the prop HREF does not exist for router links delete componentData.props.href; } return h(tag, componentData, this.normalizeSlot('default')); } }); var NAME$3 = 'BBadge'; var linkProps = propsFactory(); delete linkProps.href.default; delete linkProps.to.default; var props$1 = _objectSpread2({}, linkProps, { tag: { type: String, default: 'span' }, variant: { type: String, default: function _default() { return getComponentConfig(NAME$3, 'variant'); } }, pill: { type: Boolean, default: false } }); // @vue/component var BBadge = /*#__PURE__*/ Vue.extend({ name: NAME$3, functional: true, props: props$1, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; var isBLink = props.href || props.to; var tag = isBLink ? BLink : props.tag; var componentData = { staticClass: 'badge', class: [props.variant ? "badge-".concat(props.variant) : 'badge-secondary', { 'badge-pill': props.pill, active: props.active, disabled: props.disabled }], props: isBLink ? pluckProps(linkProps, props) : {} }; return h(tag, mergeData(data, componentData), children); } }); var BadgePlugin = /*#__PURE__*/ pluginFactory({ components: { BBadge: BBadge } }); var stripTagsRegex = /(<([^>]+)>)/gi; // Removes any thing that looks like an HTML tag from the supplied string var stripTags = function stripTags() { var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; return String(text).replace(stripTagsRegex, ''); }; // Generate a domProps object for either innerHTML, textContent or nothing var htmlOrText = function htmlOrText(innerHTML, textContent) { return innerHTML ? { innerHTML: innerHTML } : textContent ? { textContent: textContent } : {}; }; var props$2 = _objectSpread2({}, propsFactory(), { text: { type: String, default: null }, html: { type: String, default: null }, ariaCurrent: { type: String, default: 'location' } }); // @vue/component var BBreadcrumbLink = /*#__PURE__*/ Vue.extend({ name: 'BBreadcrumbLink', functional: true, props: props$2, render: function render(h, _ref) { var suppliedProps = _ref.props, data = _ref.data, children = _ref.children; var tag = suppliedProps.active ? 'span' : BLink; var componentData = { props: pluckProps(props$2, suppliedProps) }; if (suppliedProps.active) { componentData.attrs = { 'aria-current': suppliedProps.ariaCurrent }; } if (!children) { componentData.domProps = htmlOrText(suppliedProps.html, suppliedProps.text); } return h(tag, mergeData(data, componentData), children); } }); var BBreadcrumbItem = /*#__PURE__*/ Vue.extend({ name: 'BBreadcrumbItem', functional: true, props: props$2, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h('li', mergeData(data, { staticClass: 'breadcrumb-item', class: { active: props.active } }), [h(BBreadcrumbLink, { props: props }, children)]); } }); var props$3 = { items: { type: Array, default: null } }; // @vue/component var BBreadcrumb = /*#__PURE__*/ Vue.extend({ name: 'BBreadcrumb', functional: true, props: props$3, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; var childNodes = children; // Build child nodes from items if given. if (isArray(props.items)) { var activeDefined = false; childNodes = props.items.map(function (item, idx) { if (!isObject(item)) { item = { text: toString$1(item) }; } // Copy the value here so we can normalize it. var active = item.active; if (active) { activeDefined = true; } if (!active && !activeDefined) { // Auto-detect active by position in list. active = idx + 1 === props.items.length; } return h(BBreadcrumbItem, { props: _objectSpread2({}, item, { active: active }) }); }); } return h('ol', mergeData(data, { staticClass: 'breadcrumb' }), childNodes); } }); var BreadcrumbPlugin = /*#__PURE__*/ pluginFactory({ components: { BBreadcrumb: BBreadcrumb, BBreadcrumbItem: BBreadcrumbItem, BBreadcrumbLink: BBreadcrumbLink } }); /* * Key Codes (events) */ var KEY_CODES = freeze({ SPACE: 32, ENTER: 13, ESC: 27, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, PAGEUP: 33, PAGEDOWN: 34, HOME: 36, END: 35, TAB: 9, SHIFT: 16, CTRL: 17, BACKSPACE: 8, ALT: 18, PAUSE: 19, BREAK: 19, INSERT: 45, INS: 45, DELETE: 46 }); var NAME$4 = 'BButton'; var btnProps = { block: { type: Boolean, default: false }, disabled: { type: Boolean, default: false }, size: { type: String, default: function _default() { return getComponentConfig(NAME$4, 'size'); } }, variant: { type: String, default: function _default() { return getComponentConfig(NAME$4, 'variant'); } }, type: { type: String, default: 'button' }, tag: { type: String, default: 'button' }, pill: { type: Boolean, default: false }, squared: { type: Boolean, default: false }, pressed: { // Tri-state: `true`, `false` or `null` // => On, off, not a toggle type: Boolean, default: null } }; var linkProps$1 = propsFactory(); delete linkProps$1.href.default; delete linkProps$1.to.default; var linkPropKeys = keys(linkProps$1); var props$4 = _objectSpread2({}, linkProps$1, {}, btnProps); // --- Helper methods --- // Returns `true` if a tag's name equals `name` var tagIs = function tagIs(tag, name) { return toString$1(tag).toLowerCase() === toString$1(name).toLowerCase(); }; // Focus handler for toggle buttons // Needs class of 'focus' when focused var handleFocus = function handleFocus(evt) { if (evt.type === 'focusin') { addClass(evt.target, 'focus'); } else if (evt.type === 'focusout') { removeClass(evt.target, 'focus'); } }; // Is the requested button a link? // If tag prop is set to `a`, we use a to get proper disabled handling var isLink = function isLink(props) { return props.href || props.to || tagIs(props.tag, 'a'); }; // Is the button to be a toggle button? var isToggle = function isToggle(props) { return isBoolean(props.pressed); }; // Is the button "really" a button? var isButton = function isButton(props) { return !(isLink(props) || props.tag && !tagIs(props.tag, 'button')); }; // Is the requested tag not a button or link? var isNonStandardTag = function isNonStandardTag(props) { return !isLink(props) && !isButton(props); }; // Compute required classes (non static classes) var computeClass = function computeClass(props) { var _ref; return ["btn-".concat(props.variant || getComponentConfig(NAME$4, 'variant')), (_ref = {}, _defineProperty(_ref, "btn-".concat(props.size), props.size), _defineProperty(_ref, 'btn-block', props.block), _defineProperty(_ref, 'rounded-pill', props.pill), _defineProperty(_ref, 'rounded-0', props.squared && !props.pill), _defineProperty(_ref, "disabled", props.disabled), _defineProperty(_ref, "active", props.pressed), _ref)]; }; // Compute the link props to pass to b-link (if required) var computeLinkProps = function computeLinkProps(props) { return isLink(props) ? pluckProps(linkPropKeys, props) : null; }; // Compute the attributes for a button var computeAttrs = function computeAttrs(props, data) { var button = isButton(props); var link = isLink(props); var toggle = isToggle(props); var nonStandardTag = isNonStandardTag(props); var hashLink = link && props.href === '#'; var role = data.attrs && data.attrs.role ? data.attrs.role : null; var tabindex = data.attrs ? data.attrs.tabindex : null; if (nonStandardTag || hashLink) { tabindex = '0'; } return { // Type only used for "real" buttons type: button && !link ? props.type : null, // Disabled only set on "real" buttons disabled: button ? props.disabled : null, // We add a role of button when the tag is not a link or button for ARIA // Don't bork any role provided in `data.attrs` when `isLink` or `isButton` // Except when link has `href` of `#` role: nonStandardTag || hashLink ? 'button' : role, // We set the `aria-disabled` state for non-standard tags 'aria-disabled': nonStandardTag ? String(props.disabled) : null, // For toggles, we need to set the pressed state for ARIA 'aria-pressed': toggle ? String(props.pressed) : null, // `autocomplete="off"` is needed in toggle mode to prevent some browsers // from remembering the previous setting when using the back button autocomplete: toggle ? 'off' : null, // `tabindex` is used when the component is not a button // Links are tabbable, but don't allow disabled, while non buttons or links // are not tabbable, so we mimic that functionality by disabling tabbing // when disabled, and adding a `tabindex="0"` to non buttons or non links tabindex: props.disabled && !button ? '-1' : tabindex }; }; // @vue/component var BButton = /*#__PURE__*/ Vue.extend({ name: NAME$4, functional: true, props: props$4, render: function render(h, _ref2) { var props = _ref2.props, data = _ref2.data, listeners = _ref2.listeners, children = _ref2.children; var toggle = isToggle(props); var link = isLink(props); var nonStandardTag = isNonStandardTag(props); var hashLink = link && props.href === '#'; var on = { keydown: function keydown(evt) { // When the link is a `href="#"` or a non-standard tag (has `role="button"`), // we add a keydown handlers for SPACE/ENTER /* istanbul ignore next */ if (props.disabled || !(nonStandardTag || hashLink)) { return; } var keyCode = evt.keyCode; // Add SPACE handler for `href="#"` and ENTER handler for non-standard tags if (keyCode === KEY_CODES.SPACE || keyCode === KEY_CODES.ENTER && nonStandardTag) { var target = evt.currentTarget || evt.target; evt.preventDefault(); target.click(); } }, click: function click(evt) { /* istanbul ignore if: blink/button disabled should handle this */ if (props.disabled && isEvent(evt)) { evt.stopPropagation(); evt.preventDefault(); } else if (toggle && listeners && listeners['update:pressed']) { // Send `.sync` updates to any "pressed" prop (if `.sync` listeners) // `concat()` will normalize the value to an array without // double wrapping an array value in an array concat(listeners['update:pressed']).forEach(function (fn) { if (isFunction(fn)) { fn(!props.pressed); } }); } } }; if (toggle) { on.focusin = handleFocus; on.focusout = handleFocus; } var componentData = { staticClass: 'btn', class: computeClass(props), props: computeLinkProps(props), attrs: computeAttrs(props, data), on: on }; return h(link ? BLink : props.tag, mergeData(data, componentData), children); } }); var ButtonPlugin = /*#__PURE__*/ pluginFactory({ components: { BButton: BButton, BBtn: BButton, BButtonClose: BButtonClose, BBtnClose: BButtonClose } }); var NAME$5 = 'BButtonGroup'; var props$5 = { vertical: { type: Boolean, default: false }, size: { type: String, default: function _default() { return getComponentConfig('BButton', 'size'); } }, tag: { type: String, default: 'div' }, ariaRole: { type: String, default: 'group' } }; // @vue/component var BButtonGroup = /*#__PURE__*/ Vue.extend({ name: NAME$5, functional: true, props: props$5, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.tag, mergeData(data, { class: _defineProperty({ 'btn-group': !props.vertical, 'btn-group-vertical': props.vertical }, "btn-group-".concat(props.size), props.size), attrs: { role: props.ariaRole } }), children); } }); var ButtonGroupPlugin = /*#__PURE__*/ pluginFactory({ components: { BButtonGroup: BButtonGroup, BBtnGroup: BButtonGroup } }); var ITEM_SELECTOR = ['.btn:not(.disabled):not([disabled]):not(.dropdown-item)', '.form-control:not(.disabled):not([disabled])', 'select:not(.disabled):not([disabled])', 'input[type="checkbox"]:not(.disabled)', 'input[type="radio"]:not(.disabled)'].join(','); // @vue/component var BButtonToolbar = /*#__PURE__*/ Vue.extend({ name: 'BButtonToolbar', mixins: [normalizeSlotMixin], props: { justify: { type: Boolean, default: false }, keyNav: { type: Boolean, default: false } }, mounted: function mounted() { if (this.keyNav) { // Pre-set the tabindexes if the markup does not include tabindex="-1" on the toolbar items this.getItems(); } }, methods: { onFocusin: function onFocusin(evt) { if (evt.target === this.$el) { evt.preventDefault(); evt.stopPropagation(); this.focusFirst(evt); } }, stop: function stop(evt) { evt.preventDefault(); evt.stopPropagation(); }, onKeydown: function onKeydown(evt) { if (!this.keyNav) { /* istanbul ignore next: should never happen */ return; } var key = evt.keyCode; var shift = evt.shiftKey; if (key === KEY_CODES.UP || key === KEY_CODES.LEFT) { this.stop(evt); shift ? this.focusFirst(evt) : this.focusPrev(evt); } else if (key === KEY_CODES.DOWN || key === KEY_CODES.RIGHT) { this.stop(evt); shift ? this.focusLast(evt) : this.focusNext(evt); } }, setItemFocus: function setItemFocus(item) { item && item.focus && item.focus(); }, focusFirst: function focusFirst() { var items = this.getItems(); this.setItemFocus(items[0]); }, focusPrev: function focusPrev(evt) { var items = this.getItems(); var index = items.indexOf(evt.target); if (index > -1) { items = items.slice(0, index).reverse(); this.setItemFocus(items[0]); } }, focusNext: function focusNext(evt) { var items = this.getItems(); var index = items.indexOf(evt.target); if (index > -1) { items = items.slice(index + 1); this.setItemFocus(items[0]); } }, focusLast: function focusLast() { var items = this.getItems().reverse(); this.setItemFocus(items[0]); }, getItems: function getItems() { var items = selectAll(ITEM_SELECTOR, this.$el); items.forEach(function (item) { // Ensure tabfocus is -1 on any new elements item.tabIndex = -1; }); return items.filter(function (el) { return isVisible(el); }); } }, render: function render(h) { return h('div', { staticClass: 'btn-toolbar', class: { 'justify-content-between': this.justify }, attrs: { role: 'toolbar', tabindex: this.keyNav ? '0' : null }, on: this.keyNav ? { focusin: this.onFocusin, keydown: this.onKeydown } : {} }, [this.normalizeSlot('default')]); } }); var ButtonToolbarPlugin = /*#__PURE__*/ pluginFactory({ components: { BButtonToolbar: BButtonToolbar, BBtnToolbar: BButtonToolbar } }); // Handles when arrays are "sparse" (array.every(...) doesn't handle sparse) var compareArrays = function compareArrays(a, b) { if (a.length !== b.length) { return false; } var equal = true; for (var i = 0; equal && i < a.length; i++) { equal = looseEqual(a[i], b[i]); } return equal; }; /** * Check if two values are loosely equal - that is, * if they are plain objects, do they have the same shape? * Returns boolean true or false */ var looseEqual = function looseEqual(a, b) { if (a === b) { return true; } var aValidType = isDate(a); var bValidType = isDate(b); if (aValidType || bValidType) { return aValidType && bValidType ? a.getTime() === b.getTime() : false; } aValidType = isArray(a); bValidType = isArray(b); if (aValidType || bValidType) { return aValidType && bValidType ? compareArrays(a, b) : false; } aValidType = isObject(a); bValidType = isObject(b); if (aValidType || bValidType) { /* istanbul ignore if: this if will probably never be called */ if (!aValidType || !bValidType) { return false; } var aKeysCount = keys(a).length; var bKeysCount = keys(b).length; if (aKeysCount !== bKeysCount) { return false; } for (var key in a) { // eslint-disable-next-line no-prototype-builtins var aHasKey = a.hasOwnProperty(key); // eslint-disable-next-line no-prototype-builtins var bHasKey = b.hasOwnProperty(key); if (aHasKey && !bHasKey || !aHasKey && bHasKey || !looseEqual(a[key], b[key])) { return false; } } } return String(a) === String(b); }; var RX_DATE = /^\d+-\d+-\d+$/; // --- Date utility methods --- // Create or clone a date (`new Date(...)` shortcut) var createDate = function createDate() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _construct(Date, args); }; // Parse a date sting, or Date object, into a Date object (with no time information) var parseYMD = function parseYMD(date) { if (isString(date) && RX_DATE.test(date.trim())) { var _date$split$map = date.split('-').map(toInteger), _date$split$map2 = _slicedToArray(_date$split$map, 3), year = _date$split$map2[0], month = _date$split$map2[1], day = _date$split$map2[2]; return createDate(year, month - 1, day); } else if (isDate(date)) { return createDate(date.getFullYear(), date.getMonth(), date.getDate()); } return null; }; // Format a date object as `YYYY-MM-DD` format var formatYMD = function formatYMD(date) { date = parseYMD(date); if (!date) { return null; } var year = date.getFullYear(); var month = "0".concat(date.getMonth() + 1).slice(-2); var day = "0".concat(date.getDate()).slice(-2); return "".concat(year, "-").concat(month, "-").concat(day); }; // Given a locale (or locales), resolve the browser available locale var resolveLocale = function resolveLocale(locales) /* istanbul ignore next */ { var calendar = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'gregory'; locales = concat(locales).filter(identity); var fmt = new Intl.DateTimeFormat(locales, { calendar: calendar }); return fmt.resolvedOptions().locale; }; // Create a `Intl.DateTimeFormat` formatter function var createDateFormatter = function createDateFormatter(locale, options) /* istanbul ignore next */ { var dtf = new Intl.DateTimeFormat(locale, options); return dtf.format; }; // Determine if two dates are the same date (ignoring time portion) var datesEqual = function datesEqual(date1, date2) { // Returns true of the date portion of two date objects are equal // We don't compare the time portion return formatYMD(date1) === formatYMD(date2); }; // --- Date "math" utility methods (for BCalendar component mainly) --- var firstDateOfMonth = function firstDateOfMonth(date) { date = createDate(date); date.setDate(1); return date; }; var lastDateOfMonth = function lastDateOfMonth(date) { date = createDate(date); date.setMonth(date.getMonth() + 1); date.setDate(0); return date; }; var oneMonthAgo = function oneMonthAgo(date) { date = createDate(date); var month = date.getMonth(); date.setMonth(month - 1); if (date.getMonth() === month) { date.setDate(0); } return date; }; var oneMonthAhead = function oneMonthAhead(date) { date = createDate(date); var month = date.getMonth(); date.setMonth(month + 1); if (date.getMonth() === (month + 2) % 12) { date.setDate(0); } return date; }; var oneYearAgo = function oneYearAgo(date) { date = createDate(date); var month = date.getMonth(); date.setMonth(month - 12); if (date.getMonth() !== month) { date.setDate(0); } return date; }; var oneYearAhead = function oneYearAhead(date) { date = createDate(date); var month = date.getMonth(); date.setMonth(month + 12); if (date.getMonth() !== month) { date.setDate(0); } return date; }; /* * SSR Safe Client Side ID attribute generation * id's can only be generated client side, after mount. * this._uid is not synched between server and client. */ // @vue/component var idMixin = { props: { id: { type: String, default: null } }, data: function data() { return { localId_: null }; }, computed: { safeId: function safeId() { // Computed property that returns a dynamic function for creating the ID. // Reacts to changes in both .id and .localId_ And regens a new function var id = this.id || this.localId_; // We return a function that accepts an optional suffix string // So this computed prop looks and works like a method!!! // But benefits from Vue's Computed prop caching var fn = function fn(suffix) { if (!id) { return null; } suffix = String(suffix || '').replace(/\s+/g, '_'); return suffix ? id + '_' + suffix : id; }; return fn; } }, mounted: function mounted() { var _this = this; // mounted only occurs client side this.$nextTick(function () { // Update dom with auto ID after dom loaded to prevent // SSR hydration errors. _this.localId_ = "__BVID__".concat(_this._uid); }); } }; var commonIconProps = { variant: { type: String, default: null }, fontScale: { type: [Number, String], default: 1 }, scale: { type: [Number, String], default: 1 }, rotate: { type: [Number, String], default: 0 }, flipH: { type: Boolean, default: false }, flipV: { type: Boolean, default: false }, shiftH: { type: [Number, String], default: 0 }, shiftV: { type: [Number, String], default: 0 } }; // Base attributes needed on all icons var baseAttrs = { width: '1em', height: '1em', viewBox: '0 0 20 20', focusable: 'false', role: 'img', alt: 'icon' }; // Shared private base component to reduce bundle/runtime size // @vue/component var BVIconBase = /*#__PURE__*/ Vue.extend({ name: 'BVIconBase', functional: true, props: _objectSpread2({ content: { type: String }, stacked: { type: Boolean, default: false } }, commonIconProps), render: function render(h, _ref) { var data = _ref.data, props = _ref.props, children = _ref.children; var fontScale = Math.max(toFloat(props.fontScale) || 1, 0) || 1; var scale = Math.max(toFloat(props.scale) || 1, 0) || 1; var rotate = toFloat(props.rotate) || 0; var shiftH = toFloat(props.shiftH) || 0; var shiftV = toFloat(props.shiftV) || 0; var flipH = props.flipH; var flipV = props.flipV; // Compute the transforms // Note that order is important as SVG transforms are applied in order from // left to right and we want flipping/scale to occur before rotation // Note shifting is applied separately // Assumes that the viewbox is `0 0 20 20` (`10 10` is the center) var hasScale = flipH || flipV || scale !== 1; var hasTransforms = hasScale || rotate; var hasShift = shiftH || shiftV; var transforms = [hasTransforms ? 'translate(10 10)' : null, hasScale ? "scale(".concat((flipH ? -1 : 1) * scale, " ").concat((flipV ? -1 : 1) * scale, ")") : null, rotate ? "rotate(".concat(rotate, ")") : null, hasTransforms ? 'translate(-10 -10)' : null].filter(identity); // Handling stacked icons var isStacked = props.stacked; var hasContent = !isUndefinedOrNull(props.content); // We wrap the content in a `` for handling the transforms (except shift) var $inner = h('g', { attrs: { transform: transforms.join(' ') || null }, domProps: hasContent ? { innerHTML: props.content || '' } : {} }, children); // If needed, we wrap in an additional `` in order to handle the shifting if (hasShift) { $inner = h('g', { attrs: { transform: "translate(".concat(20 * shiftH / 16, " ").concat(-20 * shiftV / 16, ")") } }, [$inner]); } return h('svg', mergeData({ staticClass: 'b-icon bi', class: _defineProperty({}, "text-".concat(props.variant), !!props.variant), attrs: baseAttrs, style: isStacked ? {} : { fontSize: fontScale === 1 ? null : "".concat(fontScale * 100, "%") } }, // Merge in user supplied data data, // If icon is stacked, null out some attrs isStacked ? { attrs: { width: null, height: null, role: null, alt: null } } : {}, // These cannot be overridden by users { attrs: { xmlns: isStacked ? null : 'http://www.w3.org/2000/svg', fill: 'currentColor' } }), [$inner]); } }); /** * Icon component generator function * * @param {string} icon name (minus the leading `BIcon`) * @param {string} raw `innerHTML` for SVG * @return {VueComponent} */ var makeIcon = function makeIcon(name, content) { // For performance reason we pre-compute some values, so that // they are not computed on each render of the icon component var iconName = "BIcon".concat(pascalCase(name)); var iconNameClass = "bi-".concat(kebabCase(name)); var svgContent = trim(content || ''); // Return the icon component definition return ( /*#__PURE__*/ Vue.extend({ name: iconName, functional: true, props: _objectSpread2({}, commonIconProps, { stacked: { type: Boolean, default: false } }), render: function render(h, _ref) { var data = _ref.data, props = _ref.props; return h(BVIconBase, mergeData(data, { staticClass: iconNameClass, props: _objectSpread2({}, props, { content: svgContent }) })); } }) ); }; // --- BEGIN AUTO-GENERATED FILE --- var BIconBlank = /*#__PURE__*/ makeIcon('Blank', ''); // --- Bootstrap Icons --- var BIconAlarm = /*#__PURE__*/ makeIcon('Alarm', ''); var BIconAlarmFill = /*#__PURE__*/ makeIcon('AlarmFill', ''); var BIconAlertCircle = /*#__PURE__*/ makeIcon('AlertCircle', ''); var BIconAlertCircleFill = /*#__PURE__*/ makeIcon('AlertCircleFill', ''); var BIconAlertOctagon = /*#__PURE__*/ makeIcon('AlertOctagon', ''); var BIconAlertOctagonFill = /*#__PURE__*/ makeIcon('AlertOctagonFill', ''); var BIconAlertSquare = /*#__PURE__*/ makeIcon('AlertSquare', ''); var BIconAlertSquareFill = /*#__PURE__*/ makeIcon('AlertSquareFill', ''); var BIconAlertTriangle = /*#__PURE__*/ makeIcon('AlertTriangle', ''); var BIconAlertTriangleFill = /*#__PURE__*/ makeIcon('AlertTriangleFill', ''); var BIconArchive = /*#__PURE__*/ makeIcon('Archive', ''); var BIconArchiveFill = /*#__PURE__*/ makeIcon('ArchiveFill', ''); var BIconArrowBarBottom = /*#__PURE__*/ makeIcon('ArrowBarBottom', ''); var BIconArrowBarLeft = /*#__PURE__*/ makeIcon('ArrowBarLeft', ''); var BIconArrowBarRight = /*#__PURE__*/ makeIcon('ArrowBarRight', ''); var BIconArrowBarUp = /*#__PURE__*/ makeIcon('ArrowBarUp', ''); var BIconArrowClockwise = /*#__PURE__*/ makeIcon('ArrowClockwise', ''); var BIconArrowCounterclockwise = /*#__PURE__*/ makeIcon('ArrowCounterclockwise', ''); var BIconArrowDown = /*#__PURE__*/ makeIcon('ArrowDown', ''); var BIconArrowDownLeft = /*#__PURE__*/ makeIcon('ArrowDownLeft', ''); var BIconArrowDownRight = /*#__PURE__*/ makeIcon('ArrowDownRight', ''); var BIconArrowDownShort = /*#__PURE__*/ makeIcon('ArrowDownShort', ''); var BIconArrowLeft = /*#__PURE__*/ makeIcon('ArrowLeft', ''); var BIconArrowLeftRight = /*#__PURE__*/ makeIcon('ArrowLeftRight', ''); var BIconArrowLeftShort = /*#__PURE__*/ makeIcon('ArrowLeftShort', ''); var BIconArrowRepeat = /*#__PURE__*/ makeIcon('ArrowRepeat', ''); var BIconArrowRight = /*#__PURE__*/ makeIcon('ArrowRight', ''); var BIconArrowRightShort = /*#__PURE__*/ makeIcon('ArrowRightShort', ''); var BIconArrowUp = /*#__PURE__*/ makeIcon('ArrowUp', ''); var BIconArrowUpDown = /*#__PURE__*/ makeIcon('ArrowUpDown', ''); var BIconArrowUpLeft = /*#__PURE__*/ makeIcon('ArrowUpLeft', ''); var BIconArrowUpRight = /*#__PURE__*/ makeIcon('ArrowUpRight', ''); var BIconArrowUpShort = /*#__PURE__*/ makeIcon('ArrowUpShort', ''); var BIconArrowsAngleContract = /*#__PURE__*/ makeIcon('ArrowsAngleContract', ''); var BIconArrowsAngleExpand = /*#__PURE__*/ makeIcon('ArrowsAngleExpand', ''); var BIconArrowsCollapse = /*#__PURE__*/ makeIcon('ArrowsCollapse', ''); var BIconArrowsExpand = /*#__PURE__*/ makeIcon('ArrowsExpand', ''); var BIconArrowsFullscreen = /*#__PURE__*/ makeIcon('ArrowsFullscreen', ''); var BIconAt = /*#__PURE__*/ makeIcon('At', ''); var BIconAward = /*#__PURE__*/ makeIcon('Award', ''); var BIconBackspace = /*#__PURE__*/ makeIcon('Backspace', ''); var BIconBackspaceFill = /*#__PURE__*/ makeIcon('BackspaceFill', ''); var BIconBackspaceReverse = /*#__PURE__*/ makeIcon('BackspaceReverse', ''); var BIconBackspaceReverseFill = /*#__PURE__*/ makeIcon('BackspaceReverseFill', ''); var BIconBarChart = /*#__PURE__*/ makeIcon('BarChart', ''); var BIconBarChartFill = /*#__PURE__*/ makeIcon('BarChartFill', ''); var BIconBattery = /*#__PURE__*/ makeIcon('Battery', ''); var BIconBatteryCharging = /*#__PURE__*/ makeIcon('BatteryCharging', ''); var BIconBatteryFull = /*#__PURE__*/ makeIcon('BatteryFull', ''); var BIconBell = /*#__PURE__*/ makeIcon('Bell', ''); var BIconBellFill = /*#__PURE__*/ makeIcon('BellFill', ''); var BIconBlockquoteLeft = /*#__PURE__*/ makeIcon('BlockquoteLeft', ''); var BIconBlockquoteRight = /*#__PURE__*/ makeIcon('BlockquoteRight', ''); var BIconBook = /*#__PURE__*/ makeIcon('Book', ''); var BIconBookHalfFill = /*#__PURE__*/ makeIcon('BookHalfFill', ''); var BIconBookmark = /*#__PURE__*/ makeIcon('Bookmark', ''); var BIconBookmarkFill = /*#__PURE__*/ makeIcon('BookmarkFill', ''); var BIconBootstrap = /*#__PURE__*/ makeIcon('Bootstrap', ''); var BIconBootstrapFill = /*#__PURE__*/ makeIcon('BootstrapFill', ''); var BIconBootstrapReboot = /*#__PURE__*/ makeIcon('BootstrapReboot', ''); var BIconBoxArrowBottomLeft = /*#__PURE__*/ makeIcon('BoxArrowBottomLeft', ''); var BIconBoxArrowBottomRight = /*#__PURE__*/ makeIcon('BoxArrowBottomRight', ''); var BIconBoxArrowDown = /*#__PURE__*/ makeIcon('BoxArrowDown', ''); var BIconBoxArrowLeft = /*#__PURE__*/ makeIcon('BoxArrowLeft', ''); var BIconBoxArrowRight = /*#__PURE__*/ makeIcon('BoxArrowRight', ''); var BIconBoxArrowUp = /*#__PURE__*/ makeIcon('BoxArrowUp', ''); var BIconBoxArrowUpLeft = /*#__PURE__*/ makeIcon('BoxArrowUpLeft', ''); var BIconBoxArrowUpRight = /*#__PURE__*/ makeIcon('BoxArrowUpRight', ''); var BIconBraces = /*#__PURE__*/ makeIcon('Braces', ''); var BIconBrightnessFillHigh = /*#__PURE__*/ makeIcon('BrightnessFillHigh', ''); var BIconBrightnessFillLow = /*#__PURE__*/ makeIcon('BrightnessFillLow', ''); var BIconBrightnessHigh = /*#__PURE__*/ makeIcon('BrightnessHigh', ''); var BIconBrightnessLow = /*#__PURE__*/ makeIcon('BrightnessLow', ''); var BIconBrush = /*#__PURE__*/ makeIcon('Brush', ''); var BIconBucket = /*#__PURE__*/ makeIcon('Bucket', ''); var BIconBucketFill = /*#__PURE__*/ makeIcon('BucketFill', ''); var BIconBuilding = /*#__PURE__*/ makeIcon('Building', ''); var BIconBullseye = /*#__PURE__*/ makeIcon('Bullseye', ''); var BIconCalendar = /*#__PURE__*/ makeIcon('Calendar', ''); var BIconCalendarFill = /*#__PURE__*/ makeIcon('CalendarFill', ''); var BIconCamera = /*#__PURE__*/ makeIcon('Camera', ''); var BIconCameraVideo = /*#__PURE__*/ makeIcon('CameraVideo', ''); var BIconCameraVideoFill = /*#__PURE__*/ makeIcon('CameraVideoFill', ''); var BIconCapslock = /*#__PURE__*/ makeIcon('Capslock', ''); var BIconCapslockFill = /*#__PURE__*/ makeIcon('CapslockFill', ''); var BIconChat = /*#__PURE__*/ makeIcon('Chat', ''); var BIconChatFill = /*#__PURE__*/ makeIcon('ChatFill', ''); var BIconCheck = /*#__PURE__*/ makeIcon('Check', ''); var BIconCheckBox = /*#__PURE__*/ makeIcon('CheckBox', ''); var BIconCheckCircle = /*#__PURE__*/ makeIcon('CheckCircle', ''); var BIconChevronCompactDown = /*#__PURE__*/ makeIcon('ChevronCompactDown', ''); var BIconChevronCompactLeft = /*#__PURE__*/ makeIcon('ChevronCompactLeft', ''); var BIconChevronCompactRight = /*#__PURE__*/ makeIcon('ChevronCompactRight', ''); var BIconChevronCompactUp = /*#__PURE__*/ makeIcon('ChevronCompactUp', ''); var BIconChevronDown = /*#__PURE__*/ makeIcon('ChevronDown', ''); var BIconChevronLeft = /*#__PURE__*/ makeIcon('ChevronLeft', ''); var BIconChevronRight = /*#__PURE__*/ makeIcon('ChevronRight', ''); var BIconChevronUp = /*#__PURE__*/ makeIcon('ChevronUp', ''); var BIconCircle = /*#__PURE__*/ makeIcon('Circle', ''); var BIconCircleFill = /*#__PURE__*/ makeIcon('CircleFill', ''); var BIconCircleHalf = /*#__PURE__*/ makeIcon('CircleHalf', ''); var BIconCircleSlash = /*#__PURE__*/ makeIcon('CircleSlash', ''); var BIconClock = /*#__PURE__*/ makeIcon('Clock', ''); var BIconClockFill = /*#__PURE__*/ makeIcon('ClockFill', ''); var BIconCloud = /*#__PURE__*/ makeIcon('Cloud', ''); var BIconCloudDownload = /*#__PURE__*/ makeIcon('CloudDownload', ''); var BIconCloudFill = /*#__PURE__*/ makeIcon('CloudFill', ''); var BIconCloudUpload = /*#__PURE__*/ makeIcon('CloudUpload', ''); var BIconCode = /*#__PURE__*/ makeIcon('Code', ''); var BIconCodeSlash = /*#__PURE__*/ makeIcon('CodeSlash', ''); var BIconColumns = /*#__PURE__*/ makeIcon('Columns', ''); var BIconColumnsGutters = /*#__PURE__*/ makeIcon('ColumnsGutters', ''); var BIconCommand = /*#__PURE__*/ makeIcon('Command', ''); var BIconCompass = /*#__PURE__*/ makeIcon('Compass', ''); var BIconCone = /*#__PURE__*/ makeIcon('Cone', ''); var BIconConeStriped = /*#__PURE__*/ makeIcon('ConeStriped', ''); var BIconController = /*#__PURE__*/ makeIcon('Controller', ''); var BIconCreditCard = /*#__PURE__*/ makeIcon('CreditCard', ''); var BIconCursor = /*#__PURE__*/ makeIcon('Cursor', ''); var BIconCursorFill = /*#__PURE__*/ makeIcon('CursorFill', ''); var BIconDash = /*#__PURE__*/ makeIcon('Dash', ''); var BIconDiamond = /*#__PURE__*/ makeIcon('Diamond', ''); var BIconDiamondHalf = /*#__PURE__*/ makeIcon('DiamondHalf', ''); var BIconDisplay = /*#__PURE__*/ makeIcon('Display', ''); var BIconDisplayFill = /*#__PURE__*/ makeIcon('DisplayFill', ''); var BIconDocument = /*#__PURE__*/ makeIcon('Document', ''); var BIconDocumentCode = /*#__PURE__*/ makeIcon('DocumentCode', ''); var BIconDocumentDiff = /*#__PURE__*/ makeIcon('DocumentDiff', ''); var BIconDocumentRichtext = /*#__PURE__*/ makeIcon('DocumentRichtext', ''); var BIconDocumentSpreadsheet = /*#__PURE__*/ makeIcon('DocumentSpreadsheet', ''); var BIconDocumentText = /*#__PURE__*/ makeIcon('DocumentText', ''); var BIconDocuments = /*#__PURE__*/ makeIcon('Documents', ''); var BIconDocumentsAlt = /*#__PURE__*/ makeIcon('DocumentsAlt', ''); var BIconDot = /*#__PURE__*/ makeIcon('Dot', ''); var BIconDownload = /*#__PURE__*/ makeIcon('Download', ''); var BIconEggFried = /*#__PURE__*/ makeIcon('EggFried', ''); var BIconEject = /*#__PURE__*/ makeIcon('Eject', ''); var BIconEjectFill = /*#__PURE__*/ makeIcon('EjectFill', ''); var BIconEnvelope = /*#__PURE__*/ makeIcon('Envelope', ''); var BIconEnvelopeFill = /*#__PURE__*/ makeIcon('EnvelopeFill', ''); var BIconEnvelopeOpen = /*#__PURE__*/ makeIcon('EnvelopeOpen', ''); var BIconEnvelopeOpenFill = /*#__PURE__*/ makeIcon('EnvelopeOpenFill', ''); var BIconEye = /*#__PURE__*/ makeIcon('Eye', ''); var BIconEyeFill = /*#__PURE__*/ makeIcon('EyeFill', ''); var BIconEyeSlash = /*#__PURE__*/ makeIcon('EyeSlash', ''); var BIconEyeSlashFill = /*#__PURE__*/ makeIcon('EyeSlashFill', ''); var BIconFilter = /*#__PURE__*/ makeIcon('Filter', ''); var BIconFlag = /*#__PURE__*/ makeIcon('Flag', ''); var BIconFlagFill = /*#__PURE__*/ makeIcon('FlagFill', ''); var BIconFolder = /*#__PURE__*/ makeIcon('Folder', ''); var BIconFolderFill = /*#__PURE__*/ makeIcon('FolderFill', ''); var BIconFolderSymlink = /*#__PURE__*/ makeIcon('FolderSymlink', ''); var BIconFolderSymlinkFill = /*#__PURE__*/ makeIcon('FolderSymlinkFill', ''); var BIconFonts = /*#__PURE__*/ makeIcon('Fonts', ''); var BIconForward = /*#__PURE__*/ makeIcon('Forward', ''); var BIconForwardFill = /*#__PURE__*/ makeIcon('ForwardFill', ''); var BIconGear = /*#__PURE__*/ makeIcon('Gear', ''); var BIconGearFill = /*#__PURE__*/ makeIcon('GearFill', ''); var BIconGearWide = /*#__PURE__*/ makeIcon('GearWide', ''); var BIconGearWideConnected = /*#__PURE__*/ makeIcon('GearWideConnected', ''); var BIconGeo = /*#__PURE__*/ makeIcon('Geo', ''); var BIconGraphDown = /*#__PURE__*/ makeIcon('GraphDown', ''); var BIconGraphUp = /*#__PURE__*/ makeIcon('GraphUp', ''); var BIconGrid = /*#__PURE__*/ makeIcon('Grid', ''); var BIconGridFill = /*#__PURE__*/ makeIcon('GridFill', ''); var BIconHammer = /*#__PURE__*/ makeIcon('Hammer', ''); var BIconHash = /*#__PURE__*/ makeIcon('Hash', ''); var BIconHeart = /*#__PURE__*/ makeIcon('Heart', ''); var BIconHeartFill = /*#__PURE__*/ makeIcon('HeartFill', ''); var BIconHouse = /*#__PURE__*/ makeIcon('House', ''); var BIconHouseFill = /*#__PURE__*/ makeIcon('HouseFill', ''); var BIconImage = /*#__PURE__*/ makeIcon('Image', ''); var BIconImageAlt = /*#__PURE__*/ makeIcon('ImageAlt', ''); var BIconImageFill = /*#__PURE__*/ makeIcon('ImageFill', ''); var BIconImages = /*#__PURE__*/ makeIcon('Images', ''); var BIconInbox = /*#__PURE__*/ makeIcon('Inbox', ''); var BIconInboxFill = /*#__PURE__*/ makeIcon('InboxFill', ''); var BIconInboxes = /*#__PURE__*/ makeIcon('Inboxes', ''); var BIconInboxesFill = /*#__PURE__*/ makeIcon('InboxesFill', ''); var BIconInfo = /*#__PURE__*/ makeIcon('Info', ''); var BIconInfoFill = /*#__PURE__*/ makeIcon('InfoFill', ''); var BIconInfoSquare = /*#__PURE__*/ makeIcon('InfoSquare', ''); var BIconInfoSquareFill = /*#__PURE__*/ makeIcon('InfoSquareFill', ''); var BIconJustify = /*#__PURE__*/ makeIcon('Justify', ''); var BIconJustifyLeft = /*#__PURE__*/ makeIcon('JustifyLeft', ''); var BIconJustifyRight = /*#__PURE__*/ makeIcon('JustifyRight', ''); var BIconKanban = /*#__PURE__*/ makeIcon('Kanban', ''); var BIconKanbanFill = /*#__PURE__*/ makeIcon('KanbanFill', ''); var BIconLaptop = /*#__PURE__*/ makeIcon('Laptop', ''); var BIconLayoutSidebar = /*#__PURE__*/ makeIcon('LayoutSidebar', ''); var BIconLayoutSidebarReverse = /*#__PURE__*/ makeIcon('LayoutSidebarReverse', ''); var BIconLayoutSplit = /*#__PURE__*/ makeIcon('LayoutSplit', ''); var BIconList = /*#__PURE__*/ makeIcon('List', ''); var BIconListCheck = /*#__PURE__*/ makeIcon('ListCheck', ''); var BIconListOl = /*#__PURE__*/ makeIcon('ListOl', ''); var BIconListTask = /*#__PURE__*/ makeIcon('ListTask', ''); var BIconListUl = /*#__PURE__*/ makeIcon('ListUl', ''); var BIconLock = /*#__PURE__*/ makeIcon('Lock', ''); var BIconLockFill = /*#__PURE__*/ makeIcon('LockFill', ''); var BIconMap = /*#__PURE__*/ makeIcon('Map', ''); var BIconMic = /*#__PURE__*/ makeIcon('Mic', ''); var BIconMoon = /*#__PURE__*/ makeIcon('Moon', ''); var BIconMusicPlayer = /*#__PURE__*/ makeIcon('MusicPlayer', ''); var BIconMusicPlayerFill = /*#__PURE__*/ makeIcon('MusicPlayerFill', ''); var BIconOption = /*#__PURE__*/ makeIcon('Option', ''); var BIconOutlet = /*#__PURE__*/ makeIcon('Outlet', ''); var BIconPause = /*#__PURE__*/ makeIcon('Pause', ''); var BIconPauseFill = /*#__PURE__*/ makeIcon('PauseFill', ''); var BIconPen = /*#__PURE__*/ makeIcon('Pen', ''); var BIconPencil = /*#__PURE__*/ makeIcon('Pencil', ''); var BIconPeople = /*#__PURE__*/ makeIcon('People', ''); var BIconPeopleFill = /*#__PURE__*/ makeIcon('PeopleFill', ''); var BIconPerson = /*#__PURE__*/ makeIcon('Person', ''); var BIconPersonFill = /*#__PURE__*/ makeIcon('PersonFill', ''); var BIconPhone = /*#__PURE__*/ makeIcon('Phone', ''); var BIconPhoneLandscape = /*#__PURE__*/ makeIcon('PhoneLandscape', ''); var BIconPieChart = /*#__PURE__*/ makeIcon('PieChart', ''); var BIconPieChartFill = /*#__PURE__*/ makeIcon('PieChartFill', ''); var BIconPlay = /*#__PURE__*/ makeIcon('Play', ''); var BIconPlayFill = /*#__PURE__*/ makeIcon('PlayFill', ''); var BIconPlug = /*#__PURE__*/ makeIcon('Plug', ''); var BIconPlus = /*#__PURE__*/ makeIcon('Plus', ''); var BIconPower = /*#__PURE__*/ makeIcon('Power', ''); var BIconQuestion = /*#__PURE__*/ makeIcon('Question', ''); var BIconQuestionFill = /*#__PURE__*/ makeIcon('QuestionFill', ''); var BIconQuestionSquare = /*#__PURE__*/ makeIcon('QuestionSquare', ''); var BIconQuestionSquareFill = /*#__PURE__*/ makeIcon('QuestionSquareFill', ''); var BIconReply = /*#__PURE__*/ makeIcon('Reply', ''); var BIconReplyAll = /*#__PURE__*/ makeIcon('ReplyAll', ''); var BIconReplyAllFill = /*#__PURE__*/ makeIcon('ReplyAllFill', ''); var BIconReplyFill = /*#__PURE__*/ makeIcon('ReplyFill', ''); var BIconScrewdriver = /*#__PURE__*/ makeIcon('Screwdriver', ''); var BIconSearch = /*#__PURE__*/ makeIcon('Search', ''); var BIconShield = /*#__PURE__*/ makeIcon('Shield', ''); var BIconShieldFill = /*#__PURE__*/ makeIcon('ShieldFill', ''); var BIconShieldLock = /*#__PURE__*/ makeIcon('ShieldLock', ''); var BIconShieldLockFill = /*#__PURE__*/ makeIcon('ShieldLockFill', ''); var BIconShieldShaded = /*#__PURE__*/ makeIcon('ShieldShaded', ''); var BIconShift = /*#__PURE__*/ makeIcon('Shift', ''); var BIconShiftFill = /*#__PURE__*/ makeIcon('ShiftFill', ''); var BIconSkipBackward = /*#__PURE__*/ makeIcon('SkipBackward', ''); var BIconSkipBackwardFill = /*#__PURE__*/ makeIcon('SkipBackwardFill', ''); var BIconSkipEnd = /*#__PURE__*/ makeIcon('SkipEnd', ''); var BIconSkipEndFill = /*#__PURE__*/ makeIcon('SkipEndFill', ''); var BIconSkipForward = /*#__PURE__*/ makeIcon('SkipForward', ''); var BIconSkipForwardFill = /*#__PURE__*/ makeIcon('SkipForwardFill', ''); var BIconSkipStart = /*#__PURE__*/ makeIcon('SkipStart', ''); var BIconSkipStartFill = /*#__PURE__*/ makeIcon('SkipStartFill', ''); var BIconSpeaker = /*#__PURE__*/ makeIcon('Speaker', ''); var BIconSquare = /*#__PURE__*/ makeIcon('Square', ''); var BIconSquareFill = /*#__PURE__*/ makeIcon('SquareFill', ''); var BIconSquareHalf = /*#__PURE__*/ makeIcon('SquareHalf', ''); var BIconStar = /*#__PURE__*/ makeIcon('Star', ''); var BIconStarFill = /*#__PURE__*/ makeIcon('StarFill', ''); var BIconStarHalf = /*#__PURE__*/ makeIcon('StarHalf', ''); var BIconStop = /*#__PURE__*/ makeIcon('Stop', ''); var BIconStopFill = /*#__PURE__*/ makeIcon('StopFill', ''); var BIconStopwatch = /*#__PURE__*/ makeIcon('Stopwatch', ''); var BIconStopwatchFill = /*#__PURE__*/ makeIcon('StopwatchFill', ''); var BIconSun = /*#__PURE__*/ makeIcon('Sun', ''); var BIconTable = /*#__PURE__*/ makeIcon('Table', ''); var BIconTablet = /*#__PURE__*/ makeIcon('Tablet', ''); var BIconTabletLandscape = /*#__PURE__*/ makeIcon('TabletLandscape', ''); var BIconTag = /*#__PURE__*/ makeIcon('Tag', ''); var BIconTagFill = /*#__PURE__*/ makeIcon('TagFill', ''); var BIconTerminal = /*#__PURE__*/ makeIcon('Terminal', ''); var BIconTerminalFill = /*#__PURE__*/ makeIcon('TerminalFill', ''); var BIconTextCenter = /*#__PURE__*/ makeIcon('TextCenter', ''); var BIconTextIndentLeft = /*#__PURE__*/ makeIcon('TextIndentLeft', ''); var BIconTextIndentRight = /*#__PURE__*/ makeIcon('TextIndentRight', ''); var BIconTextLeft = /*#__PURE__*/ makeIcon('TextLeft', ''); var BIconTextRight = /*#__PURE__*/ makeIcon('TextRight', ''); var BIconThreeDots = /*#__PURE__*/ makeIcon('ThreeDots', ''); var BIconThreeDotsVertical = /*#__PURE__*/ makeIcon('ThreeDotsVertical', ''); var BIconToggleOff = /*#__PURE__*/ makeIcon('ToggleOff', ''); var BIconToggleOn = /*#__PURE__*/ makeIcon('ToggleOn', ''); var BIconToggles = /*#__PURE__*/ makeIcon('Toggles', ''); var BIconTools = /*#__PURE__*/ makeIcon('Tools', ''); var BIconTrash = /*#__PURE__*/ makeIcon('Trash', ''); var BIconTrashFill = /*#__PURE__*/ makeIcon('TrashFill', ''); var BIconTriangle = /*#__PURE__*/ makeIcon('Triangle', ''); var BIconTriangleFill = /*#__PURE__*/ makeIcon('TriangleFill', ''); var BIconTriangleHalf = /*#__PURE__*/ makeIcon('TriangleHalf', ''); var BIconTrophy = /*#__PURE__*/ makeIcon('Trophy', ''); var BIconTv = /*#__PURE__*/ makeIcon('Tv', ''); var BIconTvFill = /*#__PURE__*/ makeIcon('TvFill', ''); var BIconType = /*#__PURE__*/ makeIcon('Type', ''); var BIconTypeBold = /*#__PURE__*/ makeIcon('TypeBold', ''); var BIconTypeH1 = /*#__PURE__*/ makeIcon('TypeH1', ''); var BIconTypeH2 = /*#__PURE__*/ makeIcon('TypeH2', ''); var BIconTypeH3 = /*#__PURE__*/ makeIcon('TypeH3', ''); var BIconTypeItalic = /*#__PURE__*/ makeIcon('TypeItalic', ''); var BIconTypeStrikethrough = /*#__PURE__*/ makeIcon('TypeStrikethrough', ''); var BIconTypeUnderline = /*#__PURE__*/ makeIcon('TypeUnderline', ''); var BIconUnlock = /*#__PURE__*/ makeIcon('Unlock', ''); var BIconUnlockFill = /*#__PURE__*/ makeIcon('UnlockFill', ''); var BIconUpload = /*#__PURE__*/ makeIcon('Upload', ''); var BIconVolumeDown = /*#__PURE__*/ makeIcon('VolumeDown', ''); var BIconVolumeDownFill = /*#__PURE__*/ makeIcon('VolumeDownFill', ''); var BIconVolumeMute = /*#__PURE__*/ makeIcon('VolumeMute', ''); var BIconVolumeMuteFill = /*#__PURE__*/ makeIcon('VolumeMuteFill', ''); var BIconVolumeUp = /*#__PURE__*/ makeIcon('VolumeUp', ''); var BIconVolumeUpFill = /*#__PURE__*/ makeIcon('VolumeUpFill', ''); var BIconWallet = /*#__PURE__*/ makeIcon('Wallet', ''); var BIconWatch = /*#__PURE__*/ makeIcon('Watch', ''); var BIconWifi = /*#__PURE__*/ makeIcon('Wifi', ''); var BIconWindow = /*#__PURE__*/ makeIcon('Window', ''); var BIconWrench = /*#__PURE__*/ makeIcon('Wrench', ''); var BIconX = /*#__PURE__*/ makeIcon('X', ''); var BIconXCircle = /*#__PURE__*/ makeIcon('XCircle', ''); var BIconXCircleFill = /*#__PURE__*/ makeIcon('XCircleFill', ''); var BIconXOctagon = /*#__PURE__*/ makeIcon('XOctagon', ''); var BIconXOctagonFill = /*#__PURE__*/ makeIcon('XOctagonFill', ''); var BIconXSquare = /*#__PURE__*/ makeIcon('XSquare', ''); var BIconXSquareFill = /*#__PURE__*/ makeIcon('XSquareFill', ''); // --- END AUTO-GENERATED FILE --- var BIconstack = /*#__PURE__*/ Vue.extend({ name: 'BIconstack', functional: true, props: _objectSpread2({}, commonIconProps), render: function render(h, _ref) { var data = _ref.data, props = _ref.props, children = _ref.children; return h(BVIconBase, mergeData(data, { staticClass: 'b-iconstack', props: _objectSpread2({}, props, { stacked: false }) }), children); } }); var NAME$6 = 'BCalendar'; // Key Codes var UP = KEY_CODES.UP, DOWN = KEY_CODES.DOWN, LEFT = KEY_CODES.LEFT, RIGHT = KEY_CODES.RIGHT, PAGEUP = KEY_CODES.PAGEUP, PAGEDOWN = KEY_CODES.PAGEDOWN, HOME = KEY_CODES.HOME, END = KEY_CODES.END, ENTER = KEY_CODES.ENTER, SPACE = KEY_CODES.SPACE; // Languages that are RTL var RTL_LANGS = ['ar', 'az', 'ckb', 'fa', 'he', 'ks', 'lrc', 'mzn', 'ps', 'sd', 'te', 'ug', 'ur', 'yi'].map(function (locale) { return locale.toLowerCase(); }); // --- Helper utilities --- var isLocaleRTL = function isLocaleRTL(locale) { // Determines if the locale is RTL (only single locale supported) var parts = toString$1(locale).toLowerCase().replace(/-u-.+/, '').split('-'); var locale1 = parts.slice(0, 2).join('-'); var locale2 = parts[0]; return arrayIncludes(RTL_LANGS, locale1) || arrayIncludes(RTL_LANGS, locale2); }; // --- BCalendar component --- // @vue/component var BCalendar = Vue.extend({ name: NAME$6, mixins: [idMixin, normalizeSlotMixin], model: { // Even though this is the default that Vue assumes, we need // to add it for the docs to reflect that this is the model // And also for some validation libraries to work prop: 'value', event: 'input' }, props: { value: { type: [String, Date] // default: null }, valueAsDate: { // Always return the `v-model` value as a date object type: Boolean, default: false }, disabled: { type: Boolean, default: false }, readonly: { type: Boolean, default: false }, min: { type: [String, Date] // default: null }, max: { type: [String, Date] // default: null }, dateDisabledFn: { type: Function // default: null }, startWeekday: { // `0` (Sunday), `1` (Monday), ... `6` (Saturday) // Day of week to start calendar on type: [Number, String], default: 0 }, locale: { // Locale(s) to use // Default is to use page/browser default setting type: [String, Array] // default: null }, direction: { // 'ltr', 'rtl', or `null` (for auto detect) type: String // default: null }, selectedVariant: { // Variant color to use for the selected date type: String, default: 'primary' }, todayVariant: { // Variant color to use for today's date (defaults to `variant`) type: String // default: null }, noHighlightToday: { // Disable highlighting today's date type: Boolean, default: false }, dateInfoFn: { // Function to set a class of (classes) on the date cell // if passed a string or an array // TODO: // If the function returns an object, look for class prop for classes, // and other props for handling events/details/descriptions type: Function // default: null }, width: { // Has no effect if prop `block` is set type: String, default: '270px' }, block: { // Makes calendar the full width of its parent container type: Boolean, default: false }, hideHeader: { // When true makes the selected date header `sr-only` type: Boolean, default: false }, hidden: { // When `true`, renders a comment node, but keeps the component instance active // Mainly for , so that we can get the component's value and locale // But we might just use separate date formatters, using the resolved locale // (adjusted for the gregorian calendar) type: Boolean, default: false }, ariaControls: { type: String // default: null }, roleDescription: { type: String // default: null }, // Labels for buttons and keyboard shortcuts labelPrevYear: { type: String, default: function _default() { return getComponentConfig(NAME$6, 'labelPrevYear'); } }, labelPrevMonth: { type: String, default: function _default() { return getComponentConfig(NAME$6, 'labelPrevMonth'); } }, labelCurrentMonth: { type: String, default: function _default() { return getComponentConfig(NAME$6, 'labelCurrentMonth'); } }, labelNextMonth: { type: String, default: function _default() { return getComponentConfig(NAME$6, 'labelNextMonth'); } }, labelNextYear: { type: String, default: function _default() { return getComponentConfig(NAME$6, 'labelNextYear'); } }, labelToday: { type: String, default: function _default() { return getComponentConfig(NAME$6, 'labelToday'); } }, labelSelected: { type: String, default: function _default() { return getComponentConfig(NAME$6, 'labelSelected'); } }, labelNoDateSelected: { type: String, default: function _default() { return getComponentConfig(NAME$6, 'labelNoDateSelected'); } }, labelCalendar: { type: String, default: function _default() { return getComponentConfig(NAME$6, 'labelCalendar'); } }, labelNav: { type: String, default: function _default() { return getComponentConfig(NAME$6, 'labelNav'); } }, labelHelp: { type: String, default: function _default() { return getComponentConfig(NAME$6, 'labelHelp'); } } }, data: function data() { var selected = formatYMD(this.value) || ''; return { // Selected date selectedYMD: selected, // Date in calendar grid that has `tabindex` of `0` activeYMD: selected || formatYMD(this.getToday()), // Will be true if the calendar grid has/contains focus gridHasFocus: false, // Flag to enable the `aria-live` region(s) after mount // to prevent screen reader "outbursts" when mounting isLive: false }; }, computed: { // TODO: Use computed props to convert `YYYY-MM-DD` to `Date` object selectedDate: function selectedDate() { // Selected as a `Date` object return parseYMD(this.selectedYMD); }, activeDate: function activeDate() { // Active as a `Date` object return parseYMD(this.activeYMD); }, computedMin: function computedMin() { return parseYMD(this.min); }, computedMax: function computedMax() { return parseYMD(this.max); }, computedWeekStarts: function computedWeekStarts() { // `startWeekday` is a prop (constrained to `0` through `6`) return Math.max(toInteger(this.startWeekday) || 0, 0) % 7; }, computedLocale: function computedLocale() { // Returns the resolved locale used by the calendar return resolveLocale(concat(this.locale).filter(identity), 'gregory'); }, calendarLocale: function calendarLocale() { // This locale enforces the gregorian calendar (for use in formatter functions) // Needed because IE 11 resolves `ar-IR` as islamic-civil calendar // and IE 11 (and some other browsers) do not support the `calendar` option // And we currently only support the gregorian calendar var fmt = new Intl.DateTimeFormat(this.computedLocale, { calendar: 'gregory' }); var calendar = fmt.resolvedOptions().calendar; var locale = fmt.resolvedOptions().locale; /* istanbul ignore if: mainly for IE 11 and a few other browsers, hard to test in JSDOM */ if (calendar !== 'gregory') { // Ensure the locale requests the gregorian calendar // Mainly for IE 11, and currently we can't handle non-gregorian calendars // TODO: Should we always return this value? locale = locale.replace(/-u-.+$/i, '').concat('-u-ca-gregory'); } return locale; }, calendarYear: function calendarYear() { return this.activeDate.getFullYear(); }, calendarMonth: function calendarMonth() { return this.activeDate.getMonth(); }, calendarFirstDay: function calendarFirstDay() { return createDate(this.calendarYear, this.calendarMonth, 1); }, calendarDaysInMonth: function calendarDaysInMonth() { // We create a new date as to not mutate the original var date = createDate(this.calendarFirstDay); date.setMonth(date.getMonth() + 1, 0); return date.getDate(); }, computedVariant: function computedVariant() { return "btn-".concat(this.selectedVariant || 'primary'); }, computedTodayVariant: function computedTodayVariant() { return "btn-outline-".concat(this.todayVariant || this.selectedVariant || 'primary'); }, isRTL: function isRTL() { // `true` if the language requested is RTL var dir = toString$1(this.direction).toLowerCase(); if (dir === 'rtl') { /* istanbul ignore next */ return true; } else if (dir === 'ltr') { /* istanbul ignore next */ return false; } return isLocaleRTL(this.computedLocale); }, context: function context() { var selectedYMD = this.selectedYMD; var selectedDate = parseYMD(selectedYMD); var activeYMD = this.activeYMD; var activeDate = parseYMD(activeYMD); return { // The current value of the `v-model` selectedYMD: selectedYMD, selectedDate: selectedDate, selectedFormatted: selectedDate ? this.formatDateString(selectedDate) : this.labelNoDateSelected, // Which date cell is considered active due to navigation activeYMD: activeYMD, activeDate: activeDate, activeFormatted: activeDate ? this.formatDateString(activeDate) : '', // `true` if the date is disabled (when using keyboard navigation) disabled: this.dateDisabled(activeDate), // Locales used in formatting dates locale: this.computedLocale, calendarLocale: this.calendarLocale, rtl: this.isRTL }; }, // Computed props that return a function reference dateOutOfRange: function dateOutOfRange() { // Check wether a date is within the min/max range // returns a new function ref if the pops change // We do this as we need to trigger the calendar computed prop // to update when these props update var min = this.computedMin; var max = this.computedMax; return function (date) { // Handle both `YYYY-MM-DD` and `Date` objects date = parseYMD(date); return min && date < min || max && date > max; }; }, dateDisabled: function dateDisabled() { // Returns a function for validating if a date is within range // We grab this variables first to ensure a new function ref // is generated when the props value changes // We do this as we need to trigger the calendar computed prop // to update when these props update var rangeFn = this.dateOutOfRange; var disabledFn = isFunction(this.dateDisabledFn) ? this.dateDisabledFn : function () { return false; }; // Return the function ref return function (date) { // Handle both `YYYY-MM-DD` and `Date` objects date = parseYMD(date); var ymd = formatYMD(date); return !!(rangeFn(date) || disabledFn(ymd, date)); }; }, // Computed props that return date formatter functions formatDateString: function formatDateString() { // Returns a date formatter function return createDateFormatter(this.calendarLocale, { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long', calendar: 'gregory' }); }, formatYearMonth: function formatYearMonth() { // Returns a date formatter function return createDateFormatter(this.calendarLocale, { year: 'numeric', month: 'long', calendar: 'gregory' }); }, formatWeekdayName: function formatWeekdayName() { return createDateFormatter(this.calendarLocale, { weekday: 'long', calendar: 'gregory' }); }, formatWeekdayNameShort: function formatWeekdayNameShort() { // Used as the header cells return createDateFormatter(this.calendarLocale, { weekday: 'short', calendar: 'gregory' }); }, formatDay: function formatDay() { return createDateFormatter(this.calendarLocale, { day: 'numeric', calendar: 'gregory' }); }, // Disabled states for the nav buttons prevYearDisabled: function prevYearDisabled() { var min = this.computedMin; return this.disabled || min && lastDateOfMonth(oneYearAgo(this.activeDate)) < min; }, prevMonthDisabled: function prevMonthDisabled() { var min = this.computedMin; return this.disabled || min && lastDateOfMonth(oneMonthAgo(this.activeDate)) < min; }, thisMonthDisabled: function thisMonthDisabled() { // TODO: We could/should check if today is out of range return this.disabled; }, nextMonthDisabled: function nextMonthDisabled() { var max = this.computedMax; return this.disabled || max && firstDateOfMonth(oneMonthAhead(this.activeDate)) > max; }, nextYearDisabled: function nextYearDisabled() { var max = this.computedMax; return this.disabled || max && firstDateOfMonth(oneYearAhead(this.activeDate)) > max; }, // Calendar generation calendar: function calendar() { var matrix = []; var firstDay = this.calendarFirstDay; var calendarYear = firstDay.getFullYear(); var calendarMonth = firstDay.getMonth(); var daysInMonth = this.calendarDaysInMonth; var startIndex = firstDay.getDay(); // `0`..`6` var weekOffset = (this.computedWeekStarts > startIndex ? 7 : 0) - this.computedWeekStarts; // TODO: Change `dateInfoFn` to handle events and notes as well as classes var dateInfoFn = isFunction(this.dateInfoFn) ? this.dateInfoFn : function () { return {}; }; // Build the calendar matrix var currentDay = 0 - weekOffset - startIndex; for (var week = 0; week < 6 && currentDay < daysInMonth; week++) { // For each week matrix[week] = []; // The following could be a map function for (var j = 0; j < 7; j++) { // For each day in week currentDay++; var date = createDate(calendarYear, calendarMonth, currentDay); var month = date.getMonth(); var dayYMD = formatYMD(date); var dayDisabled = this.dateDisabled(date); // TODO: This could be a normalizer method var dateInfo = dateInfoFn(dayYMD, parseYMD(dayYMD)); dateInfo = isString(dateInfo) || isArray(dateInfo) ? { class: dateInfo } : isPlainObject(dateInfo) ? _objectSpread2({ class: '' }, dateInfo) : { class: '' }; matrix[week].push({ ymd: dayYMD, // Cell content day: this.formatDay(date), label: this.formatDateString(date), // Flags for styling isThisMonth: month === calendarMonth, isDisabled: dayDisabled, // TODO: Handle other dateInfo properties such as notes/events info: dateInfo }); } } return matrix; }, calendarHeadings: function calendarHeadings() { var _this = this; return this.calendar[0].map(function (d) { return { text: _this.formatWeekdayNameShort(parseYMD(d.ymd)), label: _this.formatWeekdayName(parseYMD(d.ymd)) }; }); } }, watch: { value: function value(newVal, oldVal) { var selected = formatYMD(newVal) || ''; var old = formatYMD(oldVal) || ''; if (!datesEqual(selected, old)) { this.activeYMD = selected || this.activeYMD; this.selectedYMD = selected; } }, selectedYMD: function selectedYMD(newYMD, oldYMD) { // TODO: // Should we compare to `formatYMD(this.value)` and emit // only if they are different? if (newYMD !== oldYMD) { this.$emit('input', this.valueAsDate ? parseYMD(newYMD) || null : newYMD || ''); } }, context: function context(newVal, oldVal) { if (!looseEqual(newVal, oldVal)) { this.$emit('context', newVal); } }, hidden: function hidden(newVal) { // Reset the active focused day when hidden this.activeYMD = this.selectedYMD || formatYMD(this.value) || formatYMD(this.getToday()); // Enable/disable the live regions this.setLive(!newVal); } }, created: function created() { var _this2 = this; this.$nextTick(function () { _this2.$emit('context', _this2.context); }); }, mounted: function mounted() { this.setLive(true); }, activated: function activated() /* istanbul ignore next */ { this.setLive(true); }, deactivated: function deactivated() /* istanbul ignore next */ { this.setLive(false); }, beforeDestroy: function beforeDestroy() { this.setLive(false); }, methods: { // Public method(s) focus: function focus() { if (!this.disabled) { try { this.$refs.grid.focus(); } catch (_unused) {} } }, blur: function blur() { try { this.$refs.grid.blur(); } catch (_unused2) {} }, // Private methods setLive: function setLive(on) { var _this3 = this; if (on) { this.$nextTick(function () { requestAF(function () { _this3.isLive = true; }); }); } else { this.isLive = false; } }, getToday: function getToday() { return parseYMD(createDate()); }, constrainDate: function constrainDate(date) { // Constrains a date between min and max // returns a new `Date` object instance date = parseYMD(date); var min = this.computedMin || date; var max = this.computedMax || date; return createDate(date < min ? min : date > max ? max : date); }, emitSelected: function emitSelected(date) { var _this4 = this; // Performed in a `$nextTick()` to (probably) ensure // the input event has emitted first this.$nextTick(function () { _this4.$emit('selected', formatYMD(date) || '', parseYMD(date) || null); }); }, // Event handlers setGridFocusFlag: function setGridFocusFlag(evt) { // Sets the gridHasFocus flag to make date "button" look focused this.gridHasFocus = !this.disabled && evt.type === 'focus'; }, onKeydownWrapper: function onKeydownWrapper(evt) { // Calendar keyboard navigation // Handles PAGEUP/PAGEDOWN/END/HOME/LEFT/UP/RIGHT/DOWN // Focuses grid after updating var keyCode = evt.keyCode; var altKey = evt.altKey; if (!arrayIncludes([PAGEUP, PAGEDOWN, END, HOME, LEFT, UP, RIGHT, DOWN], keyCode)) { /* istanbul ignore next */ return; } evt.preventDefault(); evt.stopPropagation(); var activeDate = createDate(this.activeDate); var checkDate = createDate(this.activeDate); var day = activeDate.getDate(); var isRTL = this.isRTL; if (keyCode === PAGEUP) { // PAGEUP - Previous month/year activeDate = (altKey ? oneYearAgo : oneMonthAgo)(activeDate); // We check the first day of month to be in rage checkDate = createDate(activeDate); checkDate.setDate(1); } else if (keyCode === PAGEDOWN) { // PAGEDOWN - Next month/year activeDate = (altKey ? oneYearAhead : oneMonthAhead)(activeDate); // We check the last day of month to be in rage checkDate = createDate(activeDate); checkDate.setMonth(checkDate.getMonth() + 1); checkDate.setDate(0); } else if (keyCode === LEFT) { // LEFT - Previous day (or next day for RTL) activeDate.setDate(day + (isRTL ? 1 : -1)); checkDate = activeDate; } else if (keyCode === RIGHT) { // RIGHT - Next day (or previous day for RTL) activeDate.setDate(day + (isRTL ? -1 : 1)); checkDate = activeDate; } else if (keyCode === UP) { // UP - Previous week activeDate.setDate(day - 7); checkDate = activeDate; } else if (keyCode === DOWN) { // DOWN - Next week activeDate.setDate(day + 7); checkDate = activeDate; } else if (keyCode === HOME) { // HOME - Today activeDate = this.getToday(); checkDate = activeDate; } else if (keyCode === END) { // END - Selected date, or today if no selected date activeDate = parseYMD(this.selectedDate) || this.getToday(); checkDate = activeDate; } if (!this.dateOutOfRange(checkDate) && !datesEqual(activeDate, this.activeDate)) { // We only jump to date if within min/max // We don't check for individual disabled dates though (via user function) this.activeYMD = formatYMD(activeDate); } // Ensure grid is focused this.focus(); }, onKeydownGrid: function onKeydownGrid(evt) { // Pressing enter/space on grid to select active date var keyCode = evt.keyCode; var activeDate = this.activeDate; if (keyCode === ENTER || keyCode === SPACE) { evt.preventDefault(); evt.stopPropagation(); if (!this.disabled && !this.readonly && !this.dateDisabled(activeDate)) { this.selectedYMD = formatYMD(activeDate); this.emitSelected(activeDate); } // Ensure grid is focused this.focus(); } }, onClickDay: function onClickDay(day) { // Clicking on a date "button" to select it // TODO: Change to lookup the `data-data` attribute var selectedDate = this.selectedDate; var activeDate = this.activeDate; var clickedDate = parseYMD(day.ymd); if (!this.disabled && !day.isDisabled && !this.dateDisabled(clickedDate)) { if (!this.readonly) { // If readonly mode, we don't set the selected date, just the active date // If the clicked date is equal to the already selected date, we don't update the model this.selectedYMD = formatYMD(datesEqual(clickedDate, selectedDate) ? selectedDate : clickedDate); this.emitSelected(clickedDate); } this.activeYMD = formatYMD(datesEqual(clickedDate, activeDate) ? activeDate : createDate(clickedDate)); // Ensure grid is focused this.focus(); } }, gotoPrevYear: function gotoPrevYear() { this.activeYMD = formatYMD(this.constrainDate(oneYearAgo(this.activeDate))); }, gotoPrevMonth: function gotoPrevMonth() { this.activeYMD = formatYMD(this.constrainDate(oneMonthAgo(this.activeDate))); }, gotoCurrentMonth: function gotoCurrentMonth() { // TODO: Maybe this goto date should be configurable? this.activeYMD = formatYMD(this.getToday()); }, gotoNextMonth: function gotoNextMonth() { this.activeYMD = formatYMD(this.constrainDate(oneMonthAhead(this.activeDate))); }, gotoNextYear: function gotoNextYear() { this.activeYMD = formatYMD(this.constrainDate(oneYearAhead(this.activeDate))); } }, render: function render(h) { var _this5 = this; // If hidden prop is set, render just a placeholder node if (this.hidden) { return h(); } var isRTL = this.isRTL; var todayYMD = formatYMD(this.getToday()); var selectedYMD = this.selectedYMD; var activeYMD = this.activeYMD; var highlightToday = !this.noHighlightToday; var safeId = this.safeId; // Flag for making the `aria-live` regions live var isLive = this.isLive; // Pre-compute some IDs var idWidget = safeId(); var idValue = safeId('_calendar-value_'); var idNav = safeId('_calendar-nav_'); var idGrid = safeId('_calendar-grid_'); var idGridCaption = safeId('_calendar-grid-caption_'); var idGridHelp = safeId('_calendar-grid-help_'); var idActive = activeYMD ? safeId("_cell-".concat(activeYMD, "_")) : null; // Header showing current selected date var $header = h('output', { staticClass: 'd-block text-center rounded border small p-1 mb-1', class: { 'text-muted': this.disabled, readonly: this.readonly || this.disabled }, attrs: { id: idValue, for: idGrid, role: 'status', // Mainly for testing purposes, as we do not know // the exact format `Intl` will format the date string 'data-selected': toString$1(selectedYMD), // We wait until after mount to enable `aria-live` // to prevent initial announcement on page render 'aria-live': isLive ? 'polite' : 'off', 'aria-atomic': isLive ? 'true' : null } }, this.selectedDate ? [// We use `bdi` elements here in case the label doesn't match the locale // Although IE 11 does not deal with at all (equivalent to a span) h('bdi', { staticClass: 'sr-only' }, " (".concat(toString$1(this.labelSelected), ") ")), h('bdi', {}, this.formatDateString(this.selectedDate))] : this.labelNoDateSelected || "\xA0" // ' ' ); $header = h('header', { class: this.hideHeader ? 'sr-only' : 'mb-1', attrs: { title: this.selectedDate ? this.labelSelectedDate || null : null } }, [$header]); // Content for the date navigation buttons var $prevYearIcon = h(BIconstack, { props: { shiftV: 0.5, flipH: isRTL } }, [h(BIconChevronLeft, { props: { shiftH: -2 } }), h(BIconChevronLeft, { props: { shiftH: 2 } })]); var $prevMonthIcon = h(BIconChevronLeft, { props: { shiftV: 0.5, flipH: isRTL } }); var $thisMonthIcon = h(BIconCircleFill, { props: { shiftV: 0.5 } }); var $nextMonthIcon = h(BIconChevronLeft, { props: { shiftV: 0.5, flipH: !isRTL } }); var $nextYearIcon = h(BIconstack, { props: { shiftV: 0.5, flipH: !isRTL } }, [h(BIconChevronLeft, { props: { shiftH: -2 } }), h(BIconChevronLeft, { props: { shiftH: 2 } })]); // Utility to create the date navigation buttons var makeNavBtn = function makeNavBtn(content, label, handler, btnDisabled, shortcut) { return h('button', { staticClass: 'btn btn-sm btn-outline-secondary border-0 flex-fill p-1 mx-1', class: { disabled: btnDisabled }, attrs: { title: label || null, type: 'button', 'aria-label': label || null, 'aria-disabled': btnDisabled ? 'true' : null, 'aria-keyshortcuts': shortcut || null }, on: btnDisabled ? {} : { click: handler } }, [h('div', { attrs: { 'aria-hidden': 'true' } }, [content])]); }; // Generate the date navigation buttons var $nav = h('div', { staticClass: 'b-calendar-nav d-flex mx-n1 mb-1', attrs: { id: idNav, role: 'group', 'aria-hidden': this.disabled ? 'true' : null, 'aria-label': this.labelNav || null, 'aria-controls': idGrid } }, [makeNavBtn($prevYearIcon, this.labelPrevYear, this.gotoPrevYear, this.prevYearDisabled, 'Alt+PageDown'), makeNavBtn($prevMonthIcon, this.labelPrevMonth, this.gotoPrevMonth, this.prevMonthDisabled, 'PageDown'), makeNavBtn($thisMonthIcon, this.labelCurrentMonth, this.gotoCurrentMonth, this.thisMonthDisabled, 'Home'), makeNavBtn($nextMonthIcon, this.labelNextMonth, this.gotoNextMonth, this.nextMonthDisabled, 'PageUp'), makeNavBtn($nextYearIcon, this.labelNextYear, this.gotoNextYear, this.nextYearDisabled, 'Alt+PageUp')]); // Caption for calendar grid var $gridCaption = h('header', { key: 'grid-caption', staticClass: 'text-center font-weight-bold p-1 m-0', class: { 'text-muted': this.disabled }, attrs: { id: idGridCaption, 'aria-live': isLive ? 'polite' : null, 'aria-atomic': isLive ? 'true' : null } }, this.formatYearMonth(this.calendarFirstDay)); // Calendar weekday headings var $gridWeekDays = h('div', { staticClass: 'row no-gutters border-bottom', attrs: { 'aria-hidden': 'true' } }, this.calendarHeadings.map(function (d, idx) { return h('small', { key: idx, staticClass: 'col', class: { 'text-muted': _this5.disabled }, attrs: { title: d.label === d.text ? null : d.label, 'aria-label': d.label } }, d.text); })); // Calendar day grid var $gridBody = this.calendar.map(function (week) { var $cells = week.map(function (day, dIndex) { var _class; var isSelected = day.ymd === selectedYMD; var isActive = day.ymd === activeYMD; var isToday = day.ymd === todayYMD; var idCell = safeId("_cell-".concat(day.ymd, "_")); // "fake" button var $btn = h('span', { staticClass: 'btn border-0 rounded-circle text-nowrap', // Should we add some classes to signify if today/selected/etc? class: (_class = { // Give the fake button a focus ring focus: isActive && _this5.gridHasFocus, // Styling disabled: day.isDisabled || _this5.disabled, active: isSelected }, _defineProperty(_class, _this5.computedVariant, isSelected), _defineProperty(_class, _this5.computedTodayVariant, isToday && highlightToday && !isSelected && day.isThisMonth), _defineProperty(_class, 'btn-outline-light', !(isToday && highlightToday) && !isSelected && !isActive), _defineProperty(_class, 'btn-light', !(isToday && highlightToday) && !isSelected && isActive), _defineProperty(_class, 'text-muted', !day.isThisMonth && !isSelected), _defineProperty(_class, 'text-dark', !(isToday && highlightToday) && !isSelected && !isActive && day.isThisMonth), _defineProperty(_class, 'font-weight-bold', (isSelected || day.isThisMonth) && !day.isDisabled), _class), on: { click: function click() { return _this5.onClickDay(day); } } }, day.day); return h('div', // Cell with button { key: dIndex, staticClass: 'col p-0', class: day.isDisabled ? 'bg-light' : day.info.class || '', attrs: { id: idCell, role: 'button', 'data-date': day.ymd, // Primarily for testing purposes // Only days in the month are presented as buttons to screen readers 'aria-hidden': day.isThisMonth ? null : 'true', 'aria-disabled': day.isDisabled || _this5.disabled ? 'true' : null, 'aria-label': [day.label, isSelected ? "(".concat(_this5.labelSelected, ")") : null, isToday ? "(".concat(_this5.labelToday, ")") : null].filter(identity).join(' '), // NVDA doesn't convey `aria-selected`, but does `aria-current`, // ChromeVox doesn't convey `aria-current`, but does `aria-selected`, // so we set both attributes for robustness 'aria-selected': isSelected ? 'true' : null, 'aria-current': isSelected ? 'date' : null } }, [$btn]); }); // Return the week "row" // We use the first day of the weeks YMD value as a // key for efficient DOM patching / element re-use return h('div', { key: week[0].ymd, staticClass: 'row no-gutters' }, $cells); }); $gridBody = h('div', { // A key is only required on the body if we add in transition support // key: this.activeYMD.slice(0, -3), staticClass: 'b-calendar-grid-body', style: this.disabled ? { pointerEvents: 'none' } : {} }, $gridBody); var $gridHelp = h('footer', { staticClass: 'border-top small text-muted text-center bg-light', attrs: { id: idGridHelp } }, [h('div', { staticClass: 'small' }, this.labelHelp)]); var $grid = h('div', { ref: 'grid', staticClass: 'form-control h-auto text-center p-0 mb-0', attrs: { id: idGrid, role: 'application', tabindex: this.disabled ? null : '0', 'data-month': activeYMD.slice(0, -3), // `YYYY-MM`, mainly for testing // tabindex: this.disabled ? null : '0', 'aria-roledescription': this.labelCalendar || null, 'aria-labelledby': idGridCaption, 'aria-describedby': idGridHelp, // `aria-readonly` is not considered valid on `role="application"` // https://www.w3.org/TR/wai-aria-1.1/#aria-readonly // 'aria-readonly': this.readonly && !this.disabled ? 'true' : null, 'aria-disabled': this.disabled ? 'true' : null, 'aria-activedescendant': idActive }, on: { keydown: this.onKeydownGrid, focus: this.setGridFocusFlag, blur: this.setGridFocusFlag } }, [$gridCaption, $gridWeekDays, $gridBody, $gridHelp]); // Optional bottom slot var $slot = this.normalizeSlot('default'); $slot = $slot ? h('footer', { staticClass: 'mt-2' }, $slot) : h(); var $widget = h('div', { class: this.block ? 'd-block' : 'd-inline-block', style: this.block ? {} : { width: this.width }, attrs: { id: idWidget, dir: isRTL ? 'rtl' : 'ltr', lang: this.computedLocale || null, role: 'group', 'aria-disabled': this.disabled ? 'true' : null, // If datepicker controls an input, this will specify the ID of the input 'aria-controls': this.ariaControls || null, // This should be a prop (so it can be changed to Date picker, etc, localized 'aria-roledescription': this.roleDescription || null, 'aria-describedby': [// Should the attr (if present) go last? // Or should this attr be a prop? this.$attrs['aria-describedby'], idValue, idGridHelp].filter(identity).join(' ') }, on: { keydown: this.onKeydownWrapper } }, [$header, $nav, $grid, $slot]); // Wrap in an outer div that can be styled return h('div', { staticClass: 'b-calendar', // We use a style here rather than class `d-inline-block` so that users can // override the display value (`d-*` classes use the `!important` flag) style: this.block ? {} : { display: 'inline-block' } }, [$widget]); } }); var CalendarPlugin = /*#__PURE__*/ pluginFactory({ components: { BCalendar: BCalendar } }); /** * @param {string} prefix * @param {string} value */ var prefixPropName = function prefixPropName(prefix, value) { return prefix + upperFirst(value); }; /** * @param {string} prefix * @param {string} value */ var unprefixPropName = function unprefixPropName(prefix, value) { return lowerFirst(value.replace(prefix, '')); }; /** * Copies props from one array/object to a new array/object. Prop values * are also cloned as new references to prevent possible mutation of original * prop object values. Optionally accepts a function to transform the prop name. * * @param {[]|{}} props * @param {Function} transformFn */ var copyProps = function copyProps(props) { var transformFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : identity; if (isArray(props)) { return props.map(transformFn); } // Props as an object. var copied = {}; for (var prop in props) { /* istanbul ignore else */ // eslint-disable-next-line no-prototype-builtins if (props.hasOwnProperty(prop)) { // If the prop value is an object, do a shallow clone to prevent // potential mutations to the original object. copied[transformFn(prop)] = isObject(props[prop]) ? clone(props[prop]) : props[prop]; } } return copied; }; // @vue/component var cardMixin = { props: { tag: { type: String, default: 'div' }, bgVariant: { type: String, default: null }, borderVariant: { type: String, default: null }, textVariant: { type: String, default: null } } }; var props$6 = { title: { type: String, default: '' }, titleTag: { type: String, default: 'h4' } }; // @vue/component var BCardTitle = /*#__PURE__*/ Vue.extend({ name: 'BCardTitle', functional: true, props: props$6, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.titleTag, mergeData(data, { staticClass: 'card-title' }), children || props.title); } }); var NAME$7 = 'BCardSubTitle'; var props$7 = { subTitle: { type: String, default: '' }, subTitleTag: { type: String, default: 'h6' }, subTitleTextVariant: { type: String, default: function _default() { return getComponentConfig(NAME$7, 'subTitleTextVariant'); } } }; // @vue/component var BCardSubTitle = /*#__PURE__*/ Vue.extend({ name: NAME$7, functional: true, props: props$7, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.subTitleTag, mergeData(data, { staticClass: 'card-subtitle', class: [props.subTitleTextVariant ? "text-".concat(props.subTitleTextVariant) : null] }), children || props.subTitle); } }); var props$8 = _objectSpread2({}, copyProps(cardMixin.props, prefixPropName.bind(null, 'body')), { bodyClass: { type: [String, Object, Array], default: null } }, props$6, {}, props$7, { overlay: { type: Boolean, default: false } }); // @vue/component var BCardBody = /*#__PURE__*/ Vue.extend({ name: 'BCardBody', functional: true, props: props$8, render: function render(h, _ref) { var _ref2; var props = _ref.props, data = _ref.data, children = _ref.children; var cardTitle = h(); var cardSubTitle = h(); var cardContent = children || [h()]; if (props.title) { cardTitle = h(BCardTitle, { props: pluckProps(props$6, props) }); } if (props.subTitle) { cardSubTitle = h(BCardSubTitle, { props: pluckProps(props$7, props), class: ['mb-2'] }); } return h(props.bodyTag, mergeData(data, { staticClass: 'card-body', class: [(_ref2 = { 'card-img-overlay': props.overlay }, _defineProperty(_ref2, "bg-".concat(props.bodyBgVariant), props.bodyBgVariant), _defineProperty(_ref2, "border-".concat(props.bodyBorderVariant), props.bodyBorderVariant), _defineProperty(_ref2, "text-".concat(props.bodyTextVariant), props.bodyTextVariant), _ref2), props.bodyClass || {}] }), [cardTitle, cardSubTitle].concat(_toConsumableArray(cardContent))); } }); var props$9 = _objectSpread2({}, copyProps(cardMixin.props, prefixPropName.bind(null, 'header')), { header: { type: String, default: null }, headerHtml: { type: String, default: null }, headerClass: { type: [String, Object, Array], default: null } }); // @vue/component var BCardHeader = /*#__PURE__*/ Vue.extend({ name: 'BCardHeader', functional: true, props: props$9, render: function render(h, _ref) { var _ref2; var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.headerTag, mergeData(data, { staticClass: 'card-header', class: [props.headerClass, (_ref2 = {}, _defineProperty(_ref2, "bg-".concat(props.headerBgVariant), props.headerBgVariant), _defineProperty(_ref2, "border-".concat(props.headerBorderVariant), props.headerBorderVariant), _defineProperty(_ref2, "text-".concat(props.headerTextVariant), props.headerTextVariant), _ref2)] }), children || [h('div', { domProps: htmlOrText(props.headerHtml, props.header) })]); } }); var props$a = _objectSpread2({}, copyProps(cardMixin.props, prefixPropName.bind(null, 'footer')), { footer: { type: String, default: null }, footerHtml: { type: String, default: null }, footerClass: { type: [String, Object, Array], default: null } }); // @vue/component var BCardFooter = /*#__PURE__*/ Vue.extend({ name: 'BCardFooter', functional: true, props: props$a, render: function render(h, _ref) { var _ref2; var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.footerTag, mergeData(data, { staticClass: 'card-footer', class: [props.footerClass, (_ref2 = {}, _defineProperty(_ref2, "bg-".concat(props.footerBgVariant), props.footerBgVariant), _defineProperty(_ref2, "border-".concat(props.footerBorderVariant), props.footerBorderVariant), _defineProperty(_ref2, "text-".concat(props.footerTextVariant), props.footerTextVariant), _ref2)] }), children || [h('div', { domProps: htmlOrText(props.footerHtml, props.footer) })]); } }); var props$b = { src: { type: String, default: null, required: true }, alt: { type: String, default: null }, top: { type: Boolean, default: false }, bottom: { type: Boolean, default: false }, start: { type: Boolean, default: false }, left: { // alias of 'start' type: Boolean, default: false }, end: { type: Boolean, default: false }, right: { // alias of 'end' type: Boolean, default: false }, height: { type: [Number, String], default: null }, width: { type: [Number, String], default: null } }; // @vue/component var BCardImg = /*#__PURE__*/ Vue.extend({ name: 'BCardImg', functional: true, props: props$b, render: function render(h, _ref) { var props = _ref.props, data = _ref.data; var baseClass = 'card-img'; if (props.top) { baseClass += '-top'; } else if (props.right || props.end) { baseClass += '-right'; } else if (props.bottom) { baseClass += '-bottom'; } else if (props.left || props.start) { baseClass += '-left'; } return h('img', mergeData(data, { class: [baseClass], attrs: { src: props.src, alt: props.alt, height: props.height, width: props.width } })); } }); var cardImgProps = copyProps(props$b, prefixPropName.bind(null, 'img')); cardImgProps.imgSrc.required = false; var props$c = _objectSpread2({}, props$8, {}, props$9, {}, props$a, {}, cardImgProps, {}, copyProps(cardMixin.props), { align: { type: String, default: null }, noBody: { type: Boolean, default: false } }); // @vue/component var BCard = /*#__PURE__*/ Vue.extend({ name: 'BCard', functional: true, props: props$c, render: function render(h, _ref) { var _class; var props = _ref.props, data = _ref.data, slots = _ref.slots, scopedSlots = _ref.scopedSlots; var $slots = slots(); // Vue < 2.6.x may return undefined for scopedSlots var $scopedSlots = scopedSlots || {}; // Create placeholder elements for each section var imgFirst = h(); var header = h(); var content = h(); var footer = h(); var imgLast = h(); if (props.imgSrc) { var img = h(BCardImg, { props: pluckProps(cardImgProps, props, unprefixPropName.bind(null, 'img')) }); if (props.imgBottom) { imgLast = img; } else { imgFirst = img; } } if (props.header || hasNormalizedSlot('header', $scopedSlots, $slots)) { header = h(BCardHeader, { props: pluckProps(props$9, props) }, normalizeSlot('header', {}, $scopedSlots, $slots)); } content = normalizeSlot('default', {}, $scopedSlots, $slots) || []; if (!props.noBody) { // Wrap content in card-body content = [h(BCardBody, { props: pluckProps(props$8, props) }, _toConsumableArray(content))]; } if (props.footer || hasNormalizedSlot('footer', $scopedSlots, $slots)) { footer = h(BCardFooter, { props: pluckProps(props$a, props) }, normalizeSlot('footer', {}, $scopedSlots, $slots)); } return h(props.tag, mergeData(data, { staticClass: 'card', class: (_class = { 'flex-row': props.imgLeft || props.imgStart, 'flex-row-reverse': (props.imgRight || props.imgEnd) && !(props.imgLeft || props.imgStart) }, _defineProperty(_class, "text-".concat(props.align), props.align), _defineProperty(_class, "bg-".concat(props.bgVariant), props.bgVariant), _defineProperty(_class, "border-".concat(props.borderVariant), props.borderVariant), _defineProperty(_class, "text-".concat(props.textVariant), props.textVariant), _class) }), [imgFirst, header].concat(_toConsumableArray(content), [footer, imgLast])); } }); var OBSERVER_PROP_NAME = '__bv__visibility_observer'; var onlyDgitsRE = /^\d+$/; var VisibilityObserver = /*#__PURE__*/ function () { function VisibilityObserver(el, options, vnode) { _classCallCheck(this, VisibilityObserver); this.el = el; this.callback = options.callback; this.margin = options.margin || 0; this.once = options.once || false; this.observer = null; this.visible = undefined; this.doneOnce = false; // Create the observer instance (if possible) this.createObserver(vnode); } _createClass(VisibilityObserver, [{ key: "createObserver", value: function createObserver(vnode) { var _this = this; // Remove any previous observer if (this.observer) { /* istanbul ignore next */ this.stop(); } // Should only be called once and `callback` prop should be a function if (this.doneOnce || !isFunction(this.callback)) { /* istanbul ignore next */ return; } // Create the observer instance try { // Future: Possibly add in other modifiers for left/right/top/bottom // offsets, root element reference, and thresholds this.observer = new IntersectionObserver(this.handler.bind(this), { // `null` = 'viewport' root: null, // Pixels away from view port to consider "visible" rootMargin: this.margin, // Intersection ratio of el and root (as a value from 0 to 1) threshold: 0 }); } catch (_unused) { // No IntersectionObserver support, so just stop trying to observe this.doneOnce = true; this.observer = undefined; this.callback(null); return; } // Start observing in a `$nextTick()` (to allow DOM to complete rendering) /* istanbul ignore next: IntersectionObserver not supported in JSDOM */ vnode.context.$nextTick(function () { requestAF(function () { // Placed in an `if` just in case we were destroyed before // this `requestAnimationFrame` runs if (_this.observer) { _this.observer.observe(_this.el); } }); }); } }, { key: "handler", value: function handler(entries) /* istanbul ignore next: IntersectionObserver not supported in JSDOM */ { var entry = entries ? entries[0] : {}; var isIntersecting = Boolean(entry.isIntersecting || entry.intersectionRatio > 0.0); if (isIntersecting !== this.visible) { this.visible = isIntersecting; this.callback(isIntersecting); if (this.once && this.visible) { this.doneOnce = true; this.stop(); } } } }, { key: "stop", value: function stop() { var observer = this.observer; /* istanbul ignore next */ if (observer && observer.disconnect) { observer.disconnect(); } this.observer = null; } }]); return VisibilityObserver; }(); var destroy = function destroy(el) { var observer = el[OBSERVER_PROP_NAME]; if (observer && observer.stop) { observer.stop(); } delete el[OBSERVER_PROP_NAME]; }; var bind = function bind(el, _ref, vnode) { var value = _ref.value, modifiers = _ref.modifiers; // `value` is the callback function var options = { margin: '0px', once: false, callback: value }; // Parse modifiers keys(modifiers).forEach(function (mod) { /* istanbul ignore else: Until is switched to use this directive */ if (onlyDgitsRE.test(mod)) { options.margin = "".concat(mod, "px"); } else if (mod.toLowerCase() === 'once') { options.once = true; } }); // Destroy any previous observer destroy(el); // Create new observer el[OBSERVER_PROP_NAME] = new VisibilityObserver(el, options, vnode); // Store the current modifiers on the object (cloned) el[OBSERVER_PROP_NAME]._prevModifiers = clone(modifiers); }; // When the directive options may have been updated (or element) var componentUpdated = function componentUpdated(el, _ref2, vnode) { var value = _ref2.value, oldValue = _ref2.oldValue, modifiers = _ref2.modifiers; // Compare value/oldValue and modifiers to see if anything has changed // and if so, destroy old observer and create new observer /* istanbul ignore next */ modifiers = clone(modifiers); /* istanbul ignore next */ if (el && (value !== oldValue || !el[OBSERVER_PROP_NAME] || !looseEqual(modifiers, el[OBSERVER_PROP_NAME]._prevModifiers))) { // Re-bind on element bind(el, { value: value, modifiers: modifiers }, vnode); } }; // When directive un-binds from element var unbind = function unbind(el) { // Remove the observer destroy(el); }; // Export the directive var VBVisible = { bind: bind, componentUpdated: componentUpdated, unbind: unbind }; var NAME$8 = 'BImg'; // Blank image with fill template var BLANK_TEMPLATE = '' + '' + ''; var props$d = { src: { type: String, default: null }, srcset: { type: [String, Array], default: null }, sizes: { type: [String, Array], default: null }, alt: { type: String, default: null }, width: { type: [Number, String], default: null }, height: { type: [Number, String], default: null }, block: { type: Boolean, default: false }, fluid: { type: Boolean, default: false }, fluidGrow: { // Gives fluid images class `w-100` to make them grow to fit container type: Boolean, default: false }, rounded: { // rounded can be: // false: no rounding of corners // true: slightly rounded corners // 'top': top corners rounded // 'right': right corners rounded // 'bottom': bottom corners rounded // 'left': left corners rounded // 'circle': circle/oval // '0': force rounding off type: [Boolean, String], default: false }, thumbnail: { type: Boolean, default: false }, left: { type: Boolean, default: false }, right: { type: Boolean, default: false }, center: { type: Boolean, default: false }, blank: { type: Boolean, default: false }, blankColor: { type: String, default: function _default() { return getComponentConfig(NAME$8, 'blankColor'); } } }; // --- Helper methods --- var makeBlankImgSrc = function makeBlankImgSrc(width, height, color) { var src = encodeURIComponent(BLANK_TEMPLATE.replace('%{w}', toString$1(width)).replace('%{h}', toString$1(height)).replace('%{f}', color)); return "data:image/svg+xml;charset=UTF-8,".concat(src); }; // @vue/component var BImg = /*#__PURE__*/ Vue.extend({ name: NAME$8, functional: true, props: props$d, render: function render(h, _ref) { var _class; var props = _ref.props, data = _ref.data; var src = props.src; var width = toInteger(props.width) || null; var height = toInteger(props.height) || null; var align = null; var block = props.block; var srcset = concat(props.srcset).filter(identity).join(','); var sizes = concat(props.sizes).filter(identity).join(','); if (props.blank) { if (!height && width) { height = width; } else if (!width && height) { width = height; } if (!width && !height) { width = 1; height = 1; } // Make a blank SVG image src = makeBlankImgSrc(width, height, props.blankColor || 'transparent'); // Disable srcset and sizes srcset = null; sizes = null; } if (props.left) { align = 'float-left'; } else if (props.right) { align = 'float-right'; } else if (props.center) { align = 'mx-auto'; block = true; } return h('img', mergeData(data, { attrs: { src: src, alt: props.alt, width: width ? toString$1(width) : null, height: height ? toString$1(height) : null, srcset: srcset || null, sizes: sizes || null }, class: (_class = { 'img-thumbnail': props.thumbnail, 'img-fluid': props.fluid || props.fluidGrow, 'w-100': props.fluidGrow, rounded: props.rounded === '' || props.rounded === true }, _defineProperty(_class, "rounded-".concat(props.rounded), isString(props.rounded) && props.rounded !== ''), _defineProperty(_class, align, align), _defineProperty(_class, 'd-block', block), _class) })); } }); var NAME$9 = 'BImgLazy'; var props$e = { src: { type: String, default: null, required: true }, srcset: { type: [String, Array], default: null }, sizes: { type: [String, Array], default: null }, alt: { type: String, default: null }, width: { type: [Number, String], default: null }, height: { type: [Number, String], default: null }, blankSrc: { // If null, a blank image is generated type: String, default: null }, blankColor: { type: String, default: function _default() { return getComponentConfig(NAME$9, 'blankColor'); } }, blankWidth: { type: [Number, String], default: null }, blankHeight: { type: [Number, String], default: null }, show: { type: Boolean, default: false }, fluid: { type: Boolean, default: false }, fluidGrow: { type: Boolean, default: false }, block: { type: Boolean, default: false }, thumbnail: { type: Boolean, default: false }, rounded: { type: [Boolean, String], default: false }, left: { type: Boolean, default: false }, right: { type: Boolean, default: false }, center: { type: Boolean, default: false }, offset: { // Distance away from viewport (in pixels) before being // considered "visible" type: [Number, String], default: 360 } }; // @vue/component var BImgLazy = /*#__PURE__*/ Vue.extend({ name: NAME$9, directives: { bVisible: VBVisible }, props: props$e, data: function data() { return { isShown: this.show }; }, computed: { computedSrc: function computedSrc() { return !this.blankSrc || this.isShown ? this.src : this.blankSrc; }, computedBlank: function computedBlank() { return !(this.isShown || this.blankSrc); }, computedWidth: function computedWidth() { return this.isShown ? this.width : this.blankWidth || this.width; }, computedHeight: function computedHeight() { return this.isShown ? this.height : this.blankHeight || this.height; }, computedSrcset: function computedSrcset() { var srcset = concat(this.srcset).filter(identity).join(','); return !this.blankSrc || this.isShown ? srcset : null; }, computedSizes: function computedSizes() { var sizes = concat(this.sizes).filter(identity).join(','); return !this.blankSrc || this.isShown ? sizes : null; } }, watch: { show: function show(newVal, oldVal) { if (newVal !== oldVal) { // If IntersectionObserver support is not available, image is always shown var visible = hasIntersectionObserverSupport ? newVal : true; this.isShown = visible; if (visible !== newVal) { // Ensure the show prop is synced (when no IntersectionObserver) this.$nextTick(this.updateShowProp); } } }, isShown: function isShown(newVal, oldVal) { if (newVal !== oldVal) { // Update synched show prop this.updateShowProp(); } } }, mounted: function mounted() { // If IntersectionObserver is not available, image is always shown this.isShown = hasIntersectionObserverSupport ? this.show : true; }, methods: { updateShowProp: function updateShowProp() { this.$emit('update:show', this.isShown); }, doShow: function doShow(visible) { // If IntersectionObserver is not supported, the callback // will be called with `null` rather than `true` or `false` if ((visible || visible === null) && !this.isShown) { this.isShown = true; } } }, render: function render(h) { var directives = []; if (!this.isShown) { var _modifiers; // We only add the visible directive if we are not shown directives.push({ // Visible directive will silently do nothing if // IntersectionObserver is not supported name: 'b-visible', // Value expects a callback (passed one arg of `visible` = `true` or `false`) value: this.doShow, modifiers: (_modifiers = {}, _defineProperty(_modifiers, "".concat(toInteger(this.offset) || 0), true), _defineProperty(_modifiers, "once", true), _modifiers) }); } return h(BImg, { directives: directives, props: { // Computed value props src: this.computedSrc, blank: this.computedBlank, width: this.computedWidth, height: this.computedHeight, srcset: this.computedSrcset || null, sizes: this.computedSizes || null, // Passthrough props alt: this.alt, blankColor: this.blankColor, fluid: this.fluid, fluidGrow: this.fluidGrow, block: this.block, thumbnail: this.thumbnail, rounded: this.rounded, left: this.left, right: this.right, center: this.center } }); } }); // The `omit()` util creates a new object, so we can just pass the original props var lazyProps = omit(props$e, ['left', 'right', 'center', 'block', 'rounded', 'thumbnail', 'fluid', 'fluidGrow']); var props$f = _objectSpread2({}, lazyProps, { top: { type: Boolean, default: false }, bottom: { type: Boolean, default: false }, start: { type: Boolean, default: false }, left: { // alias of 'start' type: Boolean, default: false }, end: { type: Boolean, default: false }, right: { // alias of 'end' type: Boolean, default: false } }); // @vue/component var BCardImgLazy = /*#__PURE__*/ Vue.extend({ name: 'BCardImgLazy', functional: true, props: props$f, render: function render(h, _ref) { var props = _ref.props, data = _ref.data; var baseClass = 'card-img'; if (props.top) { baseClass += '-top'; } else if (props.right || props.end) { baseClass += '-right'; } else if (props.bottom) { baseClass += '-bottom'; } else if (props.left || props.start) { baseClass += '-left'; } // False out the left/center/right props before passing to b-img-lazy var lazyProps = _objectSpread2({}, props, { left: false, right: false, center: false }); return h(BImgLazy, mergeData(data, { class: [baseClass], props: lazyProps })); } }); var props$g = { textTag: { type: String, default: 'p' } }; // @vue/component var BCardText = /*#__PURE__*/ Vue.extend({ name: 'BCardText', functional: true, props: props$g, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.textTag, mergeData(data, { staticClass: 'card-text' }), children); } }); var props$h = { tag: { type: String, default: 'div' }, deck: { type: Boolean, default: false }, columns: { type: Boolean, default: false } }; // @vue/component var BCardGroup = /*#__PURE__*/ Vue.extend({ name: 'BCardGroup', functional: true, props: props$h, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.tag, mergeData(data, { class: props.deck ? 'card-deck' : props.columns ? 'card-columns' : 'card-group' }), children); } }); var CardPlugin = /*#__PURE__*/ pluginFactory({ components: { BCard: BCard, BCardHeader: BCardHeader, BCardBody: BCardBody, BCardTitle: BCardTitle, BCardSubTitle: BCardSubTitle, BCardFooter: BCardFooter, BCardImg: BCardImg, BCardImgLazy: BCardImgLazy, BCardText: BCardText, BCardGroup: BCardGroup } }); var noop = function noop() {}; /** * Observe a DOM element changes, falls back to eventListener mode * @param {Element} el The DOM element to observe * @param {Function} callback callback to be called on change * @param {object} [options={childList: true, subtree: true}] observe options * @see http://stackoverflow.com/questions/3219758 */ var observeDom = function observeDom(el, callback, options) /* istanbul ignore next: difficult to test in JSDOM */ { // Handle cases where we might be passed a Vue instance el = el ? el.$el || el : null; // Early exit when we have no element /* istanbul ignore next: difficult to test in JSDOM */ if (!isElement(el)) { return null; } // Exit and throw a warning when `MutationObserver` isn't available if (warnNoMutationObserverSupport('observeDom')) { return null; } // Define a new observer var obs = new MutationObs(function (mutations) { var changed = false; // A mutation can contain several change records, so we loop // through them to see what has changed // We break out of the loop early if any "significant" change // has been detected for (var i = 0; i < mutations.length && !changed; i++) { // The mutation record var mutation = mutations[i]; // Mutation type var type = mutation.type; // DOM node (could be any DOM node type - HTMLElement, Text, comment, etc.) var target = mutation.target; // Detect whether a change happened based on type and target if (type === 'characterData' && target.nodeType === Node.TEXT_NODE) { // We ignore nodes that are not TEXT (i.e. comments, etc) // as they don't change layout changed = true; } else if (type === 'attributes') { changed = true; } else if (type === 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0)) { // This includes HTMLElement and text nodes being // added/removed/re-arranged changed = true; } } // We only call the callback if a change that could affect // layout/size truely happened if (changed) { callback(); } }); // Have the observer observe foo for changes in children, etc obs.observe(el, _objectSpread2({ childList: true, subtree: true }, options)); // We return a reference to the observer so that `obs.disconnect()` // can be called if necessary // To reduce overhead when the root element is hidden return obs; }; var EVENT_OPTIONS_PASSIVE = { passive: true }; var EVENT_OPTIONS_NO_CAPTURE = { passive: true, capture: false }; // --- Utils --- // Normalize event options based on support of passive option // Exported only for testing purposes var parseEventOptions = function parseEventOptions(options) { /* istanbul ignore else: can't test in JSDOM, as it supports passive */ if (hasPassiveEventSupport) { return isObject(options) ? options : { capture: !!options || false }; } else { // Need to translate to actual Boolean value return !!(isObject(options) ? options.capture : options); } }; // Attach an event listener to an element var eventOn = function eventOn(el, evtName, handler, options) { if (el && el.addEventListener) { el.addEventListener(evtName, handler, parseEventOptions(options)); } }; // Remove an event listener from an element var eventOff = function eventOff(el, evtName, handler, options) { if (el && el.removeEventListener) { el.removeEventListener(evtName, handler, parseEventOptions(options)); } }; // Utility method to add/remove a event listener based on first argument (boolean) // It passes all other arguments to the `eventOn()` or `eventOff` method var eventOnOff = function eventOnOff(on) { var method = on ? eventOn : eventOff; for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } method.apply(void 0, args); }; var NAME$a = 'BCarousel'; // Slide directional classes var DIRECTION = { next: { dirClass: 'carousel-item-left', overlayClass: 'carousel-item-next' }, prev: { dirClass: 'carousel-item-right', overlayClass: 'carousel-item-prev' } }; // Fallback Transition duration (with a little buffer) in ms var TRANS_DURATION = 600 + 50; // Time for mouse compat events to fire after touch var TOUCH_EVENT_COMPAT_WAIT = 500; // Number of pixels to consider touch move a swipe var SWIPE_THRESHOLD = 40; // PointerEvent pointer types var PointerType = { TOUCH: 'touch', PEN: 'pen' }; // Transition Event names var TransitionEndEvents = { WebkitTransition: 'webkitTransitionEnd', MozTransition: 'transitionend', OTransition: 'otransitionend oTransitionEnd', transition: 'transitionend' }; // Return the browser specific transitionEnd event name var getTransitionEndEvent = function getTransitionEndEvent(el) { for (var name in TransitionEndEvents) { if (!isUndefined(el.style[name])) { return TransitionEndEvents[name]; } } // Fallback /* istanbul ignore next */ return null; }; // @vue/component var BCarousel = /*#__PURE__*/ Vue.extend({ name: NAME$a, mixins: [idMixin, normalizeSlotMixin], provide: function provide() { return { bvCarousel: this }; }, model: { prop: 'value', event: 'input' }, props: { labelPrev: { type: String, default: function _default() { return getComponentConfig(NAME$a, 'labelPrev'); } }, labelNext: { type: String, default: function _default() { return getComponentConfig(NAME$a, 'labelNext'); } }, labelGotoSlide: { type: String, default: function _default() { return getComponentConfig(NAME$a, 'labelGotoSlide'); } }, labelIndicators: { type: String, default: function _default() { return getComponentConfig(NAME$a, 'labelIndicators'); } }, interval: { type: Number, default: 5000 }, indicators: { type: Boolean, default: false }, controls: { type: Boolean, default: false }, noAnimation: { // Disable slide/fade animation type: Boolean, default: false }, fade: { // Enable cross-fade animation instead of slide animation type: Boolean, default: false }, noWrap: { // Disable wrapping/looping when start/end is reached type: Boolean, default: false }, noTouch: { // Sniffed by carousel-slide type: Boolean, default: false }, noHoverPause: { // Disable pause on hover type: Boolean, default: false }, imgWidth: { // Sniffed by carousel-slide type: [Number, String] // default: undefined }, imgHeight: { // Sniffed by carousel-slide type: [Number, String] // default: undefined }, background: { type: String // default: undefined }, value: { type: Number, default: 0 } }, data: function data() { return { index: this.value || 0, isSliding: false, transitionEndEvent: null, slides: [], direction: null, isPaused: !(toInteger(this.interval) > 0), // Touch event handling values touchStartX: 0, touchDeltaX: 0 }; }, computed: { numSlides: function numSlides() { return this.slides.length; } }, watch: { value: function value(newVal, oldVal) { if (newVal !== oldVal) { this.setSlide(toInteger(newVal) || 0); } }, interval: function interval(newVal, oldVal) { if (newVal === oldVal) { /* istanbul ignore next */ return; } if (!newVal) { // Pausing slide show this.pause(false); } else { // Restarting or Changing interval this.pause(true); this.start(false); } }, isPaused: function isPaused(newVal, oldVal) { if (newVal !== oldVal) { this.$emit(newVal ? 'paused' : 'unpaused'); } }, index: function index(to, from) { if (to === from || this.isSliding) { /* istanbul ignore next */ return; } this.doSlide(to, from); } }, created: function created() { // Create private non-reactive props this._intervalId = null; this._animationTimeout = null; this._touchTimeout = null; // Set initial paused state this.isPaused = !(toInteger(this.interval) > 0); }, mounted: function mounted() { // Cache current browser transitionend event name this.transitionEndEvent = getTransitionEndEvent(this.$el) || null; // Get all slides this.updateSlides(); // Observe child changes so we can update slide list observeDom(this.$refs.inner, this.updateSlides.bind(this), { subtree: false, childList: true, attributes: true, attributeFilter: ['id'] }); }, beforeDestroy: function beforeDestroy() { clearTimeout(this._animationTimeout); clearTimeout(this._touchTimeout); clearInterval(this._intervalId); this._intervalId = null; this._animationTimeout = null; this._touchTimeout = null; }, methods: { // Set slide setSlide: function setSlide(slide) { var _this = this; var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; // Don't animate when page is not visible /* istanbul ignore if: difficult to test */ if (isBrowser && document.visibilityState && document.hidden) { return; } var noWrap = this.noWrap; var numSlides = this.numSlides; // Make sure we have an integer (you never know!) slide = Math.floor(slide); // Don't do anything if nothing to slide to if (numSlides === 0) { return; } // Don't change slide while transitioning, wait until transition is done if (this.isSliding) { // Schedule slide after sliding complete this.$once('sliding-end', function () { return _this.setSlide(slide, direction); }); return; } this.direction = direction; // Set new slide index // Wrap around if necessary (if no-wrap not enabled) this.index = slide >= numSlides ? noWrap ? numSlides - 1 : 0 : slide < 0 ? noWrap ? 0 : numSlides - 1 : slide; // Ensure the v-model is synched up if no-wrap is enabled // and user tried to slide pass either ends if (noWrap && this.index !== slide && this.index !== this.value) { this.$emit('input', this.index); } }, // Previous slide prev: function prev() { this.setSlide(this.index - 1, 'prev'); }, // Next slide next: function next() { this.setSlide(this.index + 1, 'next'); }, // Pause auto rotation pause: function pause(evt) { if (!evt) { this.isPaused = true; } if (this._intervalId) { clearInterval(this._intervalId); this._intervalId = null; } }, // Start auto rotate slides start: function start(evt) { if (!evt) { this.isPaused = false; } /* istanbul ignore next: most likely will never happen, but just in case */ if (this._intervalId) { clearInterval(this._intervalId); this._intervalId = null; } // Don't start if no interval, or less than 2 slides if (this.interval && this.numSlides > 1) { this._intervalId = setInterval(this.next, Math.max(1000, this.interval)); } }, // Restart auto rotate slides when focus/hover leaves the carousel restart: function restart() /* istanbul ignore next: difficult to test */ { if (!this.$el.contains(document.activeElement)) { this.start(); } }, doSlide: function doSlide(to, from) { var _this2 = this; var isCycling = Boolean(this.interval); // Determine sliding direction var direction = this.calcDirection(this.direction, from, to); var overlayClass = direction.overlayClass; var dirClass = direction.dirClass; // Determine current and next slides var currentSlide = this.slides[from]; var nextSlide = this.slides[to]; // Don't do anything if there aren't any slides to slide to if (!currentSlide || !nextSlide) { /* istanbul ignore next */ return; } // Start animating this.isSliding = true; if (isCycling) { this.pause(false); } this.$emit('sliding-start', to); // Update v-model this.$emit('input', this.index); if (this.noAnimation) { addClass(nextSlide, 'active'); removeClass(currentSlide, 'active'); this.isSliding = false; // Notify ourselves that we're done sliding (slid) this.$nextTick(function () { return _this2.$emit('sliding-end', to); }); } else { addClass(nextSlide, overlayClass); // Trigger a reflow of next slide reflow(nextSlide); addClass(currentSlide, dirClass); addClass(nextSlide, dirClass); // Transition End handler var called = false; /* istanbul ignore next: difficult to test */ var onceTransEnd = function onceTransEnd() { if (called) { return; } called = true; /* istanbul ignore if: transition events cant be tested in JSDOM */ if (_this2.transitionEndEvent) { var events = _this2.transitionEndEvent.split(/\s+/); events.forEach(function (evt) { return eventOff(currentSlide, evt, onceTransEnd, EVENT_OPTIONS_NO_CAPTURE); }); } _this2._animationTimeout = null; removeClass(nextSlide, dirClass); removeClass(nextSlide, overlayClass); addClass(nextSlide, 'active'); removeClass(currentSlide, 'active'); removeClass(currentSlide, dirClass); removeClass(currentSlide, overlayClass); setAttr(currentSlide, 'aria-current', 'false'); setAttr(nextSlide, 'aria-current', 'true'); setAttr(currentSlide, 'aria-hidden', 'true'); setAttr(nextSlide, 'aria-hidden', 'false'); _this2.isSliding = false; _this2.direction = null; // Notify ourselves that we're done sliding (slid) _this2.$nextTick(function () { return _this2.$emit('sliding-end', to); }); }; // Set up transitionend handler /* istanbul ignore if: transition events cant be tested in JSDOM */ if (this.transitionEndEvent) { var events = this.transitionEndEvent.split(/\s+/); events.forEach(function (event) { return eventOn(currentSlide, event, onceTransEnd, EVENT_OPTIONS_NO_CAPTURE); }); } // Fallback to setTimeout() this._animationTimeout = setTimeout(onceTransEnd, TRANS_DURATION); } if (isCycling) { this.start(false); } }, // Update slide list updateSlides: function updateSlides() { this.pause(true); // Get all slides as DOM elements this.slides = selectAll('.carousel-item', this.$refs.inner); var numSlides = this.slides.length; // Keep slide number in range var index = Math.max(0, Math.min(Math.floor(this.index), numSlides - 1)); this.slides.forEach(function (slide, idx) { var n = idx + 1; if (idx === index) { addClass(slide, 'active'); setAttr(slide, 'aria-current', 'true'); } else { removeClass(slide, 'active'); setAttr(slide, 'aria-current', 'false'); } setAttr(slide, 'aria-posinset', String(n)); setAttr(slide, 'aria-setsize', String(numSlides)); }); // Set slide as active this.setSlide(index); this.start(this.isPaused); }, calcDirection: function calcDirection() { var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; var curIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var nextIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; if (!direction) { return nextIndex > curIndex ? DIRECTION.next : DIRECTION.prev; } return DIRECTION[direction]; }, handleClick: function handleClick(evt, fn) { var keyCode = evt.keyCode; if (evt.type === 'click' || keyCode === KEY_CODES.SPACE || keyCode === KEY_CODES.ENTER) { evt.preventDefault(); evt.stopPropagation(); fn(); } }, handleSwipe: function handleSwipe() /* istanbul ignore next: JSDOM doesn't support touch events */ { var absDeltaX = Math.abs(this.touchDeltaX); if (absDeltaX <= SWIPE_THRESHOLD) { return; } var direction = absDeltaX / this.touchDeltaX; // Reset touch delta X // https://github.com/twbs/bootstrap/pull/28558 this.touchDeltaX = 0; if (direction > 0) { // Swipe left this.prev(); } else if (direction < 0) { // Swipe right this.next(); } }, touchStart: function touchStart(evt) /* istanbul ignore next: JSDOM doesn't support touch events */ { if (hasPointerEventSupport && PointerType[evt.pointerType.toUpperCase()]) { this.touchStartX = evt.clientX; } else if (!hasPointerEventSupport) { this.touchStartX = evt.touches[0].clientX; } }, touchMove: function touchMove(evt) /* istanbul ignore next: JSDOM doesn't support touch events */ { // Ensure swiping with one touch and not pinching if (evt.touches && evt.touches.length > 1) { this.touchDeltaX = 0; } else { this.touchDeltaX = evt.touches[0].clientX - this.touchStartX; } }, touchEnd: function touchEnd(evt) /* istanbul ignore next: JSDOM doesn't support touch events */ { if (hasPointerEventSupport && PointerType[evt.pointerType.toUpperCase()]) { this.touchDeltaX = evt.clientX - this.touchStartX; } this.handleSwipe(); // If it's a touch-enabled device, mouseenter/leave are fired as // part of the mouse compatibility events on first tap - the carousel // would stop cycling until user tapped out of it; // here, we listen for touchend, explicitly pause the carousel // (as if it's the second time we tap on it, mouseenter compat event // is NOT fired) and after a timeout (to allow for mouse compatibility // events to fire) we explicitly restart cycling this.pause(false); if (this._touchTimeout) { clearTimeout(this._touchTimeout); } this._touchTimeout = setTimeout(this.start, TOUCH_EVENT_COMPAT_WAIT + Math.max(1000, this.interval)); } }, render: function render(h) { var _this3 = this; // Wrapper for slides var inner = h('div', { ref: 'inner', class: ['carousel-inner'], attrs: { id: this.safeId('__BV_inner_'), role: 'list' } }, [this.normalizeSlot('default')]); // Prev and next controls var controls = h(); if (this.controls) { var prevHandler = function prevHandler(evt) { /* istanbul ignore next */ if (!_this3.isSliding) { _this3.handleClick(evt, _this3.prev); } else { evt.preventDefault(); } }; var nextHandler = function nextHandler(evt) { /* istanbul ignore next */ if (!_this3.isSliding) { _this3.handleClick(evt, _this3.next); } else { evt.preventDefault(); } }; controls = [h('a', { class: ['carousel-control-prev'], attrs: { href: '#', role: 'button', 'aria-controls': this.safeId('__BV_inner_'), 'aria-disabled': this.isSliding ? 'true' : null }, on: { click: prevHandler, keydown: prevHandler } }, [h('span', { class: ['carousel-control-prev-icon'], attrs: { 'aria-hidden': 'true' } }), h('span', { class: ['sr-only'] }, [this.labelPrev])]), h('a', { class: ['carousel-control-next'], attrs: { href: '#', role: 'button', 'aria-controls': this.safeId('__BV_inner_'), 'aria-disabled': this.isSliding ? 'true' : null }, on: { click: nextHandler, keydown: nextHandler } }, [h('span', { class: ['carousel-control-next-icon'], attrs: { 'aria-hidden': 'true' } }), h('span', { class: ['sr-only'] }, [this.labelNext])])]; } // Indicators var indicators = h('ol', { class: ['carousel-indicators'], directives: [{ name: 'show', rawName: 'v-show', value: this.indicators, expression: 'indicators' }], attrs: { id: this.safeId('__BV_indicators_'), 'aria-hidden': this.indicators ? 'false' : 'true', 'aria-label': this.labelIndicators, 'aria-owns': this.safeId('__BV_inner_') } }, this.slides.map(function (slide, n) { return h('li', { key: "slide_".concat(n), class: { active: n === _this3.index }, attrs: { role: 'button', id: _this3.safeId("__BV_indicator_".concat(n + 1, "_")), tabindex: _this3.indicators ? '0' : '-1', 'aria-current': n === _this3.index ? 'true' : 'false', 'aria-label': "".concat(_this3.labelGotoSlide, " ").concat(n + 1), 'aria-describedby': _this3.slides[n].id || null, 'aria-controls': _this3.safeId('__BV_inner_') }, on: { click: function click(evt) { _this3.handleClick(evt, function () { _this3.setSlide(n); }); }, keydown: function keydown(evt) { _this3.handleClick(evt, function () { _this3.setSlide(n); }); } } }); })); var on = { mouseenter: this.noHoverPause ? noop : this.pause, mouseleave: this.noHoverPause ? noop : this.restart, focusin: this.pause, focusout: this.restart, keydown: function keydown(evt) { if (/input|textarea/i.test(evt.target.tagName)) { /* istanbul ignore next */ return; } var keyCode = evt.keyCode; if (keyCode === KEY_CODES.LEFT || keyCode === KEY_CODES.RIGHT) { evt.preventDefault(); evt.stopPropagation(); _this3[keyCode === KEY_CODES.LEFT ? 'prev' : 'next'](); } } }; // Touch support event handlers for environment if (!this.noTouch && hasTouchSupport) { // Attach appropriate listeners (prepend event name with '&' for passive mode) /* istanbul ignore next: JSDOM doesn't support touch events */ if (hasPointerEventSupport) { on['&pointerdown'] = this.touchStart; on['&pointerup'] = this.touchEnd; } else { on['&touchstart'] = this.touchStart; on['&touchmove'] = this.touchMove; on['&touchend'] = this.touchEnd; } } // Return the carousel return h('div', { staticClass: 'carousel', class: { slide: !this.noAnimation, 'carousel-fade': !this.noAnimation && this.fade, 'pointer-event': !this.noTouch && hasTouchSupport && hasPointerEventSupport }, style: { background: this.background }, attrs: { role: 'region', id: this.safeId(), 'aria-busy': this.isSliding ? 'true' : 'false' }, on: on }, [inner, controls, indicators]); } }); var props$i = { imgSrc: { type: String // default: undefined }, imgAlt: { type: String // default: undefined }, imgWidth: { type: [Number, String] // default: undefined }, imgHeight: { type: [Number, String] // default: undefined }, imgBlank: { type: Boolean, default: false }, imgBlankColor: { type: String, default: 'transparent' }, contentVisibleUp: { type: String }, contentTag: { type: String, default: 'div' }, caption: { type: String }, captionHtml: { type: String }, captionTag: { type: String, default: 'h3' }, text: { type: String }, textHtml: { type: String }, textTag: { type: String, default: 'p' }, background: { type: String } }; // @vue/component var BCarouselSlide = /*#__PURE__*/ Vue.extend({ name: 'BCarouselSlide', mixins: [idMixin, normalizeSlotMixin], inject: { bvCarousel: { default: function _default() { return { // Explicitly disable touch if not a child of carousel noTouch: true }; } } }, props: props$i, computed: { contentClasses: function contentClasses() { return [this.contentVisibleUp ? 'd-none' : '', this.contentVisibleUp ? "d-".concat(this.contentVisibleUp, "-block") : '']; }, computedWidth: function computedWidth() { // Use local width, or try parent width return this.imgWidth || this.bvCarousel.imgWidth || null; }, computedHeight: function computedHeight() { // Use local height, or try parent height return this.imgHeight || this.bvCarousel.imgHeight || null; } }, render: function render(h) { var noDrag = !this.bvCarousel.noTouch && hasTouchSupport; var img = this.normalizeSlot('img'); if (!img && (this.imgSrc || this.imgBlank)) { img = h(BImg, { props: { fluidGrow: true, block: true, src: this.imgSrc, blank: this.imgBlank, blankColor: this.imgBlankColor, width: this.computedWidth, height: this.computedHeight, alt: this.imgAlt }, // Touch support event handler on: noDrag ? { dragstart: function dragstart(e) { /* istanbul ignore next: difficult to test in JSDOM */ e.preventDefault(); } } : {} }); } if (!img) { img = h(); } var content = h(); var contentChildren = [this.caption || this.captionHtml ? h(this.captionTag, { domProps: htmlOrText(this.captionHtml, this.caption) }) : false, this.text || this.textHtml ? h(this.textTag, { domProps: htmlOrText(this.textHtml, this.text) }) : false, this.normalizeSlot('default') || false]; if (contentChildren.some(Boolean)) { content = h(this.contentTag, { staticClass: 'carousel-caption', class: this.contentClasses }, contentChildren.map(function (i) { return i || h(); })); } return h('div', { staticClass: 'carousel-item', style: { background: this.background || this.bvCarousel.background || null }, attrs: { id: this.safeId(), role: 'listitem' } }, [img, content]); } }); var CarouselPlugin = /*#__PURE*/ pluginFactory({ components: { BCarousel: BCarousel, BCarouselSlide: BCarouselSlide } }); // Generic collapse transion helper component var onEnter = function onEnter(el) { el.style.height = 0; // Animaton frame delay neeeded for `appear` to work requestAF(function () { reflow(el); el.style.height = "".concat(el.scrollHeight, "px"); }); }; var onAfterEnter = function onAfterEnter(el) { el.style.height = null; }; var onLeave = function onLeave(el) { el.style.height = 'auto'; el.style.display = 'block'; el.style.height = "".concat(getBCR(el).height, "px"); reflow(el); el.style.height = 0; }; var onAfterLeave = function onAfterLeave(el) { el.style.height = null; }; // Default transition props // `appear` will use the enter classes var TRANSITION_PROPS = { css: true, enterClass: '', enterActiveClass: 'collapsing', enterToClass: 'collapse show', leaveClass: 'collapse show', leaveActiveClass: 'collapsing', leaveToClass: 'collapse' }; // Default transition handlers // `appear` will use the enter handlers var TRANSITION_HANDLERS = { enter: onEnter, afterEnter: onAfterEnter, leave: onLeave, afterLeave: onAfterLeave }; // @vue/component var BVCollapse = /*#__PURE__*/ Vue.extend({ name: 'BVCollapse', functional: true, props: { appear: { // If `true` (and `visible` is `true` on mount), animate initially visible type: Boolean, default: false } }, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h('transition', // We merge in the `appear` prop last mergeData(data, { props: TRANSITION_PROPS, on: TRANSITION_HANDLERS }, { props: props }), // Note: `` supports a single root element only children); } }); /** * Issue #569: collapse::toggle::state triggered too many times * @link https://github.com/bootstrap-vue/bootstrap-vue/issues/569 */ // @vue/component var listenOnRootMixin = { methods: { /** * Safely register event listeners on the root Vue node. * While Vue automatically removes listeners for individual components, * when a component registers a listener on root and is destroyed, * this orphans a callback because the node is gone, * but the root does not clear the callback. * * When registering a $root listener, it also registers a listener on * the component's `beforeDestroy` hook to automatically remove the * event listener from the $root instance. * * @param {string} event * @param {function} callback * @chainable */ listenOnRoot: function listenOnRoot(event, callback) { var _this = this; this.$root.$on(event, callback); this.$on('hook:beforeDestroy', function () { _this.$root.$off(event, callback); }); // Return this for easy chaining return this; }, /** * Safely register a $once event listener on the root Vue node. * While Vue automatically removes listeners for individual components, * when a component registers a listener on root and is destroyed, * this orphans a callback because the node is gone, * but the root does not clear the callback. * * When registering a $root listener, it also registers a listener on * the component's `beforeDestroy` hook to automatically remove the * event listener from the $root instance. * * @param {string} event * @param {function} callback * @chainable */ listenOnRootOnce: function listenOnRootOnce(event, callback) { var _this2 = this; this.$root.$once(event, callback); this.$on('hook:beforeDestroy', function () { _this2.$root.$off(event, callback); }); // Return this for easy chaining return this; }, /** * Convenience method for calling vm.$emit on vm.$root. * @param {string} event * @param {*} args * @chainable */ emitOnRoot: function emitOnRoot(event) { var _this$$root; for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } (_this$$root = this.$root).$emit.apply(_this$$root, [event].concat(args)); // Return this for easy chaining return this; } } }; var EVENT_STATE = 'bv::collapse::state'; var EVENT_ACCORDION = 'bv::collapse::accordion'; // Private event we emit on `$root` to ensure the toggle state is // always synced. It gets emitted even if the state has not changed! // This event is NOT to be documented as people should not be using it var EVENT_STATE_SYNC = 'bv::collapse::sync::state'; // Events we listen to on `$root` var EVENT_TOGGLE = 'bv::toggle::collapse'; var EVENT_STATE_REQUEST = 'bv::request::collapse::state'; // @vue/component var BCollapse = /*#__PURE__*/ Vue.extend({ name: 'BCollapse', mixins: [idMixin, listenOnRootMixin, normalizeSlotMixin], model: { prop: 'visible', event: 'input' }, props: { isNav: { type: Boolean, default: false }, accordion: { type: String, default: null }, visible: { type: Boolean, default: false }, tag: { type: String, default: 'div' }, appear: { // If `true` (and `visible` is `true` on mount), animate initially visible type: Boolean, default: false } }, data: function data() { return { show: this.visible, transitioning: false }; }, computed: { classObject: function classObject() { return { 'navbar-collapse': this.isNav, collapse: !this.transitioning, show: this.show && !this.transitioning }; } }, watch: { visible: function visible(newVal) { if (newVal !== this.show) { this.show = newVal; } }, show: function show(newVal, oldVal) { if (newVal !== oldVal) { this.emitState(); } } }, created: function created() { this.show = this.visible; }, mounted: function mounted() { var _this = this; this.show = this.visible; // Listen for toggle events to open/close us this.listenOnRoot(EVENT_TOGGLE, this.handleToggleEvt); // Listen to other collapses for accordion events this.listenOnRoot(EVENT_ACCORDION, this.handleAccordionEvt); if (this.isNav) { // Set up handlers this.setWindowEvents(true); this.handleResize(); } this.$nextTick(function () { _this.emitState(); }); // Listen for "Sync state" requests from `v-b-toggle` this.listenOnRoot(EVENT_STATE_REQUEST, function (id) { if (id === _this.safeId()) { _this.$nextTick(_this.emitSync); } }); }, updated: function updated() { // Emit a private event every time this component updates to ensure // the toggle button is in sync with the collapse's state // It is emitted regardless if the visible state changes this.emitSync(); }, deactivated: function deactivated() /* istanbul ignore next */ { if (this.isNav) { this.setWindowEvents(false); } }, activated: function activated() /* istanbul ignore next */ { if (this.isNav) { this.setWindowEvents(true); } this.emitSync(); }, beforeDestroy: function beforeDestroy() { // Trigger state emit if needed this.show = false; if (this.isNav && isBrowser) { this.setWindowEvents(false); } }, methods: { setWindowEvents: function setWindowEvents(on) { eventOnOff(on, window, 'resize', this.handleResize, EVENT_OPTIONS_NO_CAPTURE); eventOnOff(on, window, 'orientationchange', this.handleResize, EVENT_OPTIONS_NO_CAPTURE); }, toggle: function toggle() { this.show = !this.show; }, onEnter: function onEnter() { this.transitioning = true; // This should be moved out so we can add cancellable events this.$emit('show'); }, onAfterEnter: function onAfterEnter() { this.transitioning = false; this.$emit('shown'); }, onLeave: function onLeave() { this.transitioning = true; // This should be moved out so we can add cancellable events this.$emit('hide'); }, onAfterLeave: function onAfterLeave() { this.transitioning = false; this.$emit('hidden'); }, emitState: function emitState() { this.$emit('input', this.show); // Let `v-b-toggle` know the state of this collapse this.$root.$emit(EVENT_STATE, this.safeId(), this.show); if (this.accordion && this.show) { // Tell the other collapses in this accordion to close this.$root.$emit(EVENT_ACCORDION, this.safeId(), this.accordion); } }, emitSync: function emitSync() { // Emit a private event every time this component updates to ensure // the toggle button is in sync with the collapse's state // It is emitted regardless if the visible state changes this.$root.$emit(EVENT_STATE_SYNC, this.safeId(), this.show); }, checkDisplayBlock: function checkDisplayBlock() { // Check to see if the collapse has `display: block !important` set // We can't set `display: none` directly on `this.$el`, as it would // trigger a new transition to start (or cancel a current one) var restore = hasClass(this.$el, 'show'); removeClass(this.$el, 'show'); var isBlock = getCS(this.$el).display === 'block'; if (restore) { addClass(this.$el, 'show'); } return isBlock; }, clickHandler: function clickHandler(evt) { // If we are in a nav/navbar, close the collapse when non-disabled link clicked var el = evt.target; if (!this.isNav || !el || getCS(this.$el).display !== 'block') { /* istanbul ignore next: can't test getComputedStyle in JSDOM */ return; } if (matches(el, '.nav-link,.dropdown-item') || closest('.nav-link,.dropdown-item', el)) { if (!this.checkDisplayBlock()) { // Only close the collapse if it is not forced to be `display: block !important` this.show = false; } } }, handleToggleEvt: function handleToggleEvt(target) { if (target !== this.safeId()) { return; } this.toggle(); }, handleAccordionEvt: function handleAccordionEvt(openedId, accordion) { if (!this.accordion || accordion !== this.accordion) { return; } if (openedId === this.safeId()) { // Open this collapse if not shown if (!this.show) { this.toggle(); } } else { // Close this collapse if shown if (this.show) { this.toggle(); } } }, handleResize: function handleResize() { // Handler for orientation/resize to set collapsed state in nav/navbar this.show = getCS(this.$el).display === 'block'; } }, render: function render(h) { var _this2 = this; var scope = { visible: this.show, close: function close() { return _this2.show = false; } }; var content = h(this.tag, { class: this.classObject, directives: [{ name: 'show', value: this.show }], attrs: { id: this.safeId() }, on: { click: this.clickHandler } }, [this.normalizeSlot('default', scope)]); return h(BVCollapse, { props: { appear: this.appear }, on: { enter: this.onEnter, afterEnter: this.onAfterEnter, leave: this.onLeave, afterLeave: this.onAfterLeave } }, [content]); } }); var allListenTypes = { hover: true, click: true, focus: true }; var BVBoundListeners = '__BV_boundEventListeners__'; var getTargets = function getTargets(binding) { var targets = keys(binding.modifiers || {}).filter(function (t) { return !allListenTypes[t]; }); if (binding.value) { targets.push(binding.value); } return targets; }; var bindTargets = function bindTargets(vnode, binding, listenTypes, fn) { var targets = getTargets(binding); var listener = function listener() { fn({ targets: targets, vnode: vnode }); }; keys(allListenTypes).forEach(function (type) { if (listenTypes[type] || binding.modifiers[type]) { eventOn(vnode.elm, type, listener); var boundListeners = vnode.elm[BVBoundListeners] || {}; boundListeners[type] = boundListeners[type] || []; boundListeners[type].push(listener); vnode.elm[BVBoundListeners] = boundListeners; } }); // Return the list of targets return targets; }; var unbindTargets = function unbindTargets(vnode, binding, listenTypes) { keys(allListenTypes).forEach(function (type) { if (listenTypes[type] || binding.modifiers[type]) { var boundListeners = vnode.elm[BVBoundListeners] && vnode.elm[BVBoundListeners][type]; if (boundListeners) { boundListeners.forEach(function (listener) { return eventOff(vnode.elm, type, listener); }); delete vnode.elm[BVBoundListeners][type]; } } }); }; var listenTypes = { click: true }; // Property key for handler storage var BV_TOGGLE = '__BV_toggle__'; var BV_TOGGLE_STATE = '__BV_toggle_STATE__'; var BV_TOGGLE_CONTROLS = '__BV_toggle_CONTROLS__'; var BV_TOGGLE_TARGETS = '__BV_toggle_TARGETS__'; // Emitted control event for collapse (emitted to collapse) var EVENT_TOGGLE$1 = 'bv::toggle::collapse'; // Listen to event for toggle state update (emitted by collapse) var EVENT_STATE$1 = 'bv::collapse::state'; // Private event emitted on $root to ensure the toggle state is always synced. // Gets emitted even if the state of b-collapse has not changed. // This event is NOT to be documented as people should not be using it. var EVENT_STATE_SYNC$1 = 'bv::collapse::sync::state'; // Private event we send to collapse to request state update sync event var EVENT_STATE_REQUEST$1 = 'bv::request::collapse::state'; // Reset and remove a property from the provided element var resetProp = function resetProp(el, prop) { el[prop] = null; delete el[prop]; }; // Handle targets update var handleTargets = function handleTargets(_ref) { var targets = _ref.targets, vnode = _ref.vnode; targets.forEach(function (target) { vnode.context.$root.$emit(EVENT_TOGGLE$1, target); }); }; // Handle directive updates /* istanbul ignore next: not easy to test */ var handleUpdate = function handleUpdate(el, binding, vnode) { if (!isBrowser) { return; } if (!looseEqual(getTargets(binding), el[BV_TOGGLE_TARGETS])) { // Targets have changed, so update accordingly unbindTargets(vnode, binding, listenTypes); var targets = bindTargets(vnode, binding, listenTypes, handleTargets); // Update targets array to element el[BV_TOGGLE_TARGETS] = targets; // Add aria attributes to element el[BV_TOGGLE_CONTROLS] = targets.join(' '); // ensure aria-controls is up to date setAttr(el, 'aria-controls', el[BV_TOGGLE_CONTROLS]); // Request a state update from targets so that we can ensure // expanded state is correct targets.forEach(function (target) { vnode.context.$root.$emit(EVENT_STATE_REQUEST$1, target); }); } // Ensure the collapse class and aria-* attributes persist // after element is updated (either by parent re-rendering // or changes to this element or its contents if (el[BV_TOGGLE_STATE] === true) { addClass(el, 'collapsed'); setAttr(el, 'aria-expanded', 'true'); } else if (el[BV_TOGGLE_STATE] === false) { removeClass(el, 'collapsed'); setAttr(el, 'aria-expanded', 'false'); } setAttr(el, 'aria-controls', el[BV_TOGGLE_CONTROLS]); }; /* * Export our directive */ var VBToggle = { bind: function bind(el, binding, vnode) { var targets = bindTargets(vnode, binding, listenTypes, handleTargets); if (isBrowser && vnode.context && targets.length > 0) { // Add targets array to element el[BV_TOGGLE_TARGETS] = targets; // Add aria attributes to element el[BV_TOGGLE_CONTROLS] = targets.join(' '); // State is initially collapsed until we receive a state event el[BV_TOGGLE_STATE] = false; setAttr(el, 'aria-controls', el[BV_TOGGLE_CONTROLS]); setAttr(el, 'aria-expanded', 'false'); // If element is not a button, we add `role="button"` for accessibility if (el.tagName !== 'BUTTON' && !hasAttr(el, 'role')) { setAttr(el, 'role', 'button'); } // Toggle state handler var toggleDirectiveHandler = function toggleDirectiveHandler(id, state) { var targets = el[BV_TOGGLE_TARGETS] || []; if (targets.indexOf(id) !== -1) { // Set aria-expanded state setAttr(el, 'aria-expanded', state ? 'true' : 'false'); // Set/Clear 'collapsed' class state el[BV_TOGGLE_STATE] = state; if (state) { removeClass(el, 'collapsed'); } else { addClass(el, 'collapsed'); } } }; // Store the toggle handler on the element el[BV_TOGGLE] = toggleDirectiveHandler; // Listen for toggle state changes (public) vnode.context.$root.$on(EVENT_STATE$1, el[BV_TOGGLE]); // Listen for toggle state sync (private) vnode.context.$root.$on(EVENT_STATE_SYNC$1, el[BV_TOGGLE]); } }, componentUpdated: handleUpdate, updated: handleUpdate, unbind: function unbind(el, binding, vnode) /* istanbul ignore next */ { unbindTargets(vnode, binding, listenTypes); // Remove our $root listener if (el[BV_TOGGLE]) { vnode.context.$root.$off(EVENT_STATE$1, el[BV_TOGGLE]); vnode.context.$root.$off(EVENT_STATE_SYNC$1, el[BV_TOGGLE]); } // Reset custom props resetProp(el, BV_TOGGLE); resetProp(el, BV_TOGGLE_STATE); resetProp(el, BV_TOGGLE_CONTROLS); resetProp(el, BV_TOGGLE_TARGETS); // Reset classes/attrs removeClass(el, 'collapsed'); removeAttr(el, 'aria-expanded'); removeAttr(el, 'aria-controls'); removeAttr(el, 'role'); } }; var CollapsePlugin = /*#__PURE__*/ pluginFactory({ components: { BCollapse: BCollapse }, directives: { VBToggle: VBToggle } }); var BvEvent = /*#__PURE__*/ function () { function BvEvent(type) { var eventInit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; _classCallCheck(this, BvEvent); // Start by emulating native Event constructor if (!type) { /* istanbul ignore next */ throw new TypeError("Failed to construct '".concat(this.constructor.name, "'. 1 argument required, ").concat(arguments.length, " given.")); } // Merge defaults first, the eventInit, and the type last // so it can't be overwritten assign(this, BvEvent.Defaults, this.constructor.Defaults, eventInit, { type: type }); // Freeze some props as readonly, but leave them enumerable defineProperties(this, { type: readonlyDescriptor(), cancelable: readonlyDescriptor(), nativeEvent: readonlyDescriptor(), target: readonlyDescriptor(), relatedTarget: readonlyDescriptor(), vueTarget: readonlyDescriptor(), componentId: readonlyDescriptor() }); // Create a private variable using closure scoping var defaultPrevented = false; // Recreate preventDefault method. One way setter this.preventDefault = function preventDefault() { if (this.cancelable) { defaultPrevented = true; } }; // Create `defaultPrevented` publicly accessible prop that // can only be altered by the preventDefault method defineProperty(this, 'defaultPrevented', { enumerable: true, get: function get() { return defaultPrevented; } }); } _createClass(BvEvent, null, [{ key: "Defaults", get: function get() { return { type: '', cancelable: true, nativeEvent: null, target: null, relatedTarget: null, vueTarget: null, componentId: null }; } }]); return BvEvent; }(); // Named Exports var clickOutMixin = { data: function data() { return { listenForClickOut: false }; }, watch: { listenForClickOut: function listenForClickOut(newValue, oldValue) { if (newValue !== oldValue) { eventOff(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); if (newValue) { eventOn(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); } } } }, beforeCreate: function beforeCreate() { // Declare non-reactive properties this.clickOutElement = null; this.clickOutEventName = null; }, mounted: function mounted() { if (!this.clickOutElement) { this.clickOutElement = document; } if (!this.clickOutEventName) { this.clickOutEventName = 'click'; } if (this.listenForClickOut) { eventOn(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); } }, beforeDestroy: function beforeDestroy() /* istanbul ignore next */ { eventOff(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); }, methods: { isClickOut: function isClickOut(evt) { return !contains(this.$el, evt.target); }, _clickOutHandler: function _clickOutHandler(evt) { if (this.clickOutHandler && this.isClickOut(evt)) { this.clickOutHandler(evt); } } } }; var focusInMixin = { data: function data() { return { listenForFocusIn: false }; }, watch: { listenForFocusIn: function listenForFocusIn(newValue, oldValue) { if (newValue !== oldValue) { eventOff(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); if (newValue) { eventOn(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); } } } }, beforeCreate: function beforeCreate() { // Declare non-reactive properties this.focusInElement = null; }, mounted: function mounted() { if (!this.focusInElement) { this.focusInElement = document; } if (this.listenForFocusIn) { eventOn(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); } }, beforeDestroy: function beforeDestroy() /* istanbul ignore next */ { eventOff(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); }, methods: { _focusInHandler: function _focusInHandler(evt) { if (this.focusInHandler) { this.focusInHandler(evt); } } } }; var filterVisibles = function filterVisibles(els) { return (els || []).filter(isVisible); }; // Root dropdown event names var ROOT_DROPDOWN_PREFIX = 'bv::dropdown::'; var ROOT_DROPDOWN_SHOWN = "".concat(ROOT_DROPDOWN_PREFIX, "shown"); var ROOT_DROPDOWN_HIDDEN = "".concat(ROOT_DROPDOWN_PREFIX, "hidden"); // Dropdown item CSS selectors var Selector = { FORM_CHILD: '.dropdown form', ITEM_SELECTOR: ['.dropdown-item', '.b-dropdown-form'].map(function (selector) { return "".concat(selector, ":not(.disabled):not([disabled])"); }).join(', ') }; // Popper attachment positions var AttachmentMap = { // Dropup left align TOP: 'top-start', // Dropup right align TOPEND: 'top-end', // Dropdown left align BOTTOM: 'bottom-start', // Dropdown right align BOTTOMEND: 'bottom-end', // Dropright left align RIGHT: 'right-start', // Dropright right align RIGHTEND: 'right-end', // Dropleft left align LEFT: 'left-start', // Dropleft right align LEFTEND: 'left-end' }; // @vue/component var dropdownMixin = { mixins: [idMixin, clickOutMixin, focusInMixin], provide: function provide() { return { bvDropdown: this }; }, inject: { bvNavbar: { default: null } }, props: { disabled: { type: Boolean, default: false }, dropup: { // place on top if possible type: Boolean, default: false }, dropright: { // place right if possible type: Boolean, default: false }, dropleft: { // place left if possible type: Boolean, default: false }, right: { // Right align menu (default is left align) type: Boolean, default: false }, offset: { // Number of pixels to offset menu, or a CSS unit value (i.e. 1px, 1rem, etc) type: [Number, String], default: 0 }, noFlip: { // Disable auto-flipping of menu from bottom<=>top type: Boolean, default: false }, popperOpts: { // type: Object, default: function _default() {} }, boundary: { // String: `scrollParent`, `window` or `viewport` // HTMLElement: HTML Element reference type: [String, HTMLElement], default: 'scrollParent' } }, data: function data() { return { visible: false, visibleChangePrevented: false }; }, computed: { inNavbar: function inNavbar() { return !isNull(this.bvNavbar); }, toggler: function toggler() { var toggle = this.$refs.toggle; return toggle ? toggle.$el || toggle : null; }, directionClass: function directionClass() { if (this.dropup) { return 'dropup'; } else if (this.dropright) { return 'dropright'; } else if (this.dropleft) { return 'dropleft'; } return ''; } }, watch: { visible: function visible(newValue, oldValue) { if (this.visibleChangePrevented) { this.visibleChangePrevented = false; return; } if (newValue !== oldValue) { var evtName = newValue ? 'show' : 'hide'; var bvEvt = new BvEvent(evtName, { cancelable: true, vueTarget: this, target: this.$refs.menu, relatedTarget: null, componentId: this.safeId ? this.safeId() : this.id || null }); this.emitEvent(bvEvt); if (bvEvt.defaultPrevented) { // Reset value and exit if canceled this.visibleChangePrevented = true; this.visible = oldValue; // Just in case a child element triggered `this.hide(true)` this.$off('hidden', this.focusToggler); return; } if (evtName === 'show') { this.showMenu(); } else { this.hideMenu(); } } }, disabled: function disabled(newValue, oldValue) { if (newValue !== oldValue && newValue && this.visible) { // Hide dropdown if disabled changes to true this.visible = false; } } }, created: function created() { // Create non-reactive property this.$_popper = null; }, deactivated: function deactivated() /* istanbul ignore next: not easy to test */ { // In case we are inside a `` this.visible = false; this.whileOpenListen(false); this.destroyPopper(); }, beforeDestroy: function beforeDestroy() { this.visible = false; this.whileOpenListen(false); this.destroyPopper(); }, methods: { // Event emitter emitEvent: function emitEvent(bvEvt) { var type = bvEvt.type; this.$emit(type, bvEvt); this.$root.$emit("".concat(ROOT_DROPDOWN_PREFIX).concat(type), bvEvt); }, showMenu: function showMenu() { var _this = this; if (this.disabled) { /* istanbul ignore next */ return; } // Only instantiate Popper.js when dropdown is not in `` if (!this.inNavbar) { if (typeof Popper === 'undefined') { /* istanbul ignore next */ warn('Popper.js not found. Falling back to CSS positioning', 'BDropdown'); } else { // For dropup with alignment we use the parent element as popper container var el = this.dropup && this.right || this.split ? this.$el : this.$refs.toggle; // Make sure we have a reference to an element, not a component! el = el.$el || el; // Instantiate Popper.js this.createPopper(el); } } // Ensure other menus are closed this.$root.$emit(ROOT_DROPDOWN_SHOWN, this); // Enable listeners this.whileOpenListen(true); // Wrap in `$nextTick()` to ensure menu is fully rendered/shown this.$nextTick(function () { // Focus on the menu container on show _this.focusMenu(); // Emit the shown event _this.$emit('shown'); }); }, hideMenu: function hideMenu() { this.whileOpenListen(false); this.$root.$emit(ROOT_DROPDOWN_HIDDEN, this); this.$emit('hidden'); this.destroyPopper(); }, createPopper: function createPopper(element) { this.destroyPopper(); this.$_popper = new Popper(element, this.$refs.menu, this.getPopperConfig()); }, destroyPopper: function destroyPopper() { // Ensure popper event listeners are removed cleanly if (this.$_popper) { this.$_popper.destroy(); } this.$_popper = null; }, updatePopper: function updatePopper() /* istanbul ignore next: not easy to test */ { // Instructs popper to re-computes the dropdown position // usefull if the content changes size try { this.$_popper.scheduleUpdate(); } catch (_unused) {} }, getPopperConfig: function getPopperConfig() { var placement = AttachmentMap.BOTTOM; if (this.dropup) { placement = this.right ? AttachmentMap.TOPEND : AttachmentMap.TOP; } else if (this.dropright) { placement = AttachmentMap.RIGHT; } else if (this.dropleft) { placement = AttachmentMap.LEFT; } else if (this.right) { placement = AttachmentMap.BOTTOMEND; } var popperConfig = { placement: placement, modifiers: { offset: { offset: this.offset || 0 }, flip: { enabled: !this.noFlip } } }; if (this.boundary) { popperConfig.modifiers.preventOverflow = { boundariesElement: this.boundary }; } return _objectSpread2({}, popperConfig, {}, this.popperOpts || {}); }, // Turn listeners on/off while open whileOpenListen: function whileOpenListen(isOpen) { // Hide the dropdown when clicked outside this.listenForClickOut = isOpen; // Hide the dropdown when it loses focus this.listenForFocusIn = isOpen; // Hide the dropdown when another dropdown is opened var method = isOpen ? '$on' : '$off'; this.$root[method](ROOT_DROPDOWN_SHOWN, this.rootCloseListener); }, rootCloseListener: function rootCloseListener(vm) { if (vm !== this) { this.visible = false; } }, show: function show() { var _this2 = this; // Public method to show dropdown if (this.disabled) { return; } // Wrap in a `requestAF()` to allow any previous // click handling to occur first requestAF(function () { _this2.visible = true; }); }, hide: function hide() { var refocus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; // Public method to hide dropdown if (this.disabled) { /* istanbul ignore next */ return; } this.visible = false; if (refocus) { // Child element is closing the dropdown on click this.$once('hidden', this.focusToggler); } }, // Called only by a button that toggles the menu toggle: function toggle(evt) { evt = evt || {}; // Early exit when not a click event or ENTER, SPACE or DOWN were pressed var _evt = evt, type = _evt.type, keyCode = _evt.keyCode; if (type !== 'click' && !(type === 'keydown' && [KEY_CODES.ENTER, KEY_CODES.SPACE, KEY_CODES.DOWN].indexOf(keyCode) !== -1)) { /* istanbul ignore next */ return; } /* istanbul ignore next */ if (this.disabled) { this.visible = false; return; } this.$emit('toggle', evt); evt.preventDefault(); evt.stopPropagation(); // Toggle visibility if (this.visible) { this.hide(true); } else { this.show(); } }, // Mousedown handler for the toggle onMousedown: function onMousedown(evt) /* istanbul ignore next */ { // We prevent the 'mousedown' event for the toggle to stop the // 'focusin' event from being fired // The event would otherwise be picked up by the global 'focusin' // listener and there is no cross-browser solution to detect it // relates to the toggle click // The 'click' event will still be fired and we handle closing // other dropdowns there too // See https://github.com/bootstrap-vue/bootstrap-vue/issues/4328 evt.preventDefault(); }, // Called from dropdown menu context onKeydown: function onKeydown(evt) { var keyCode = evt.keyCode; if (keyCode === KEY_CODES.ESC) { // Close on ESC this.onEsc(evt); } else if (keyCode === KEY_CODES.DOWN) { // Down Arrow this.focusNext(evt, false); } else if (keyCode === KEY_CODES.UP) { // Up Arrow this.focusNext(evt, true); } }, // If user presses ESC, close the menu onEsc: function onEsc(evt) { if (this.visible) { this.visible = false; evt.preventDefault(); evt.stopPropagation(); // Return focus to original trigger button this.$once('hidden', this.focusToggler); } }, // Called only in split button mode, for the split button onSplitClick: function onSplitClick(evt) { /* istanbul ignore next */ if (this.disabled) { this.visible = false; return; } this.$emit('click', evt); }, // Shared hide handler between click-out and focus-in events hideHandler: function hideHandler(evt) { var target = evt.target; if (this.visible && !contains(this.$refs.menu, target) && !contains(this.toggler, target)) { this.hide(); } }, // Document click-out listener clickOutHandler: function clickOutHandler(evt) { this.hideHandler(evt); }, // Document focus-in listener focusInHandler: function focusInHandler(evt) { this.hideHandler(evt); }, // Keyboard nav focusNext: function focusNext(evt, up) { var _this3 = this; // Ignore key up/down on form elements var target = evt.target; if (!this.visible || evt && closest(Selector.FORM_CHILD, target)) { /* istanbul ignore next: should never happen */ return; } evt.preventDefault(); evt.stopPropagation(); this.$nextTick(function () { var items = _this3.getItems(); if (items.length < 1) { /* istanbul ignore next: should never happen */ return; } var index = items.indexOf(target); if (up && index > 0) { index--; } else if (!up && index < items.length - 1) { index++; } if (index < 0) { /* istanbul ignore next: should never happen */ index = 0; } _this3.focusItem(index, items); }); }, focusItem: function focusItem(idx, items) { var el = items.find(function (el, i) { return i === idx; }); if (el && el.focus) { el.focus(); } }, getItems: function getItems() { // Get all items return filterVisibles(selectAll(Selector.ITEM_SELECTOR, this.$refs.menu)); }, focusMenu: function focusMenu() { try { this.$refs.menu.focus(); } catch (_unused2) {} }, focusToggler: function focusToggler() { var _this4 = this; this.$nextTick(function () { var toggler = _this4.toggler; if (toggler && toggler.focus) { toggler.focus(); } }); } } }; var NAME$b = 'BDropdown'; var props$j = { text: { // Button label type: String, default: '' }, html: { // Button label type: String }, size: { type: String, default: function _default() { return getComponentConfig(NAME$b, 'size'); } }, variant: { type: String, default: function _default() { return getComponentConfig(NAME$b, 'variant'); } }, block: { type: Boolean, default: false }, menuClass: { type: [String, Array, Object], default: null }, toggleTag: { type: String, default: 'button' }, toggleText: { // This really should be toggleLabel type: String, default: function _default() { return getComponentConfig(NAME$b, 'toggleText'); } }, toggleClass: { type: [String, Array, Object], default: null }, noCaret: { type: Boolean, default: false }, split: { type: Boolean, default: false }, splitHref: { type: String // default: undefined }, splitTo: { type: [String, Object] // default: undefined }, splitVariant: { type: String, default: function _default() { return getComponentConfig(NAME$b, 'splitVariant'); } }, splitClass: { type: [String, Array, Object], default: null }, splitButtonType: { type: String, default: 'button', validator: function validator(value) { return arrayIncludes(['button', 'submit', 'reset'], value); } }, lazy: { // If true, only render menu contents when open type: Boolean, default: false }, role: { type: String, default: 'menu' } }; // @vue/component var BDropdown = /*#__PURE__*/ Vue.extend({ name: NAME$b, mixins: [idMixin, dropdownMixin, normalizeSlotMixin], props: props$j, computed: { dropdownClasses: function dropdownClasses() { return [this.directionClass, { show: this.visible, // The 'btn-group' class is required in `split` mode for button alignment // It needs also to be applied when `block` is disabled to allow multiple // dropdowns to be aligned one line 'btn-group': this.split || !this.block, // When `block` is enabled and we are in `split` mode the 'd-flex' class // needs to be applied to allow the buttons to stretch to full width 'd-flex': this.block && this.split, // Position `static` is needed to allow menu to "breakout" of the `scrollParent` // boundaries when boundary is anything other than `scrollParent` // See: https://github.com/twbs/bootstrap/issues/24251#issuecomment-341413786 'position-static': this.boundary !== 'scrollParent' || !this.boundary }]; }, menuClasses: function menuClasses() { return [this.menuClass, { 'dropdown-menu-right': this.right, show: this.visible }]; }, toggleClasses: function toggleClasses() { return [this.toggleClass, { 'dropdown-toggle-split': this.split, 'dropdown-toggle-no-caret': this.noCaret && !this.split }]; } }, render: function render(h) { var split = h(); var buttonContent = this.normalizeSlot('button-content') || this.html || stripTags(this.text); if (this.split) { var btnProps = { variant: this.splitVariant || this.variant, size: this.size, block: this.block, disabled: this.disabled }; // We add these as needed due to router-link issues with defined property with undefined/null values if (this.splitTo) { btnProps.to = this.splitTo; } else if (this.splitHref) { btnProps.href = this.splitHref; } else if (this.splitButtonType) { btnProps.type = this.splitButtonType; } split = h(BButton, { ref: 'button', props: btnProps, class: this.splitClass, attrs: { id: this.safeId('_BV_button_') }, on: { click: this.onSplitClick } }, [buttonContent]); } var toggle = h(BButton, { ref: 'toggle', staticClass: 'dropdown-toggle', class: this.toggleClasses, props: { tag: this.toggleTag, variant: this.variant, size: this.size, block: this.block && !this.split, disabled: this.disabled }, attrs: { id: this.safeId('_BV_toggle_'), 'aria-haspopup': 'true', 'aria-expanded': this.visible ? 'true' : 'false' }, on: { mousedown: this.onMousedown, click: this.toggle, keydown: this.toggle // Handle ENTER, SPACE and DOWN } }, [this.split ? h('span', { class: ['sr-only'] }, [this.toggleText]) : buttonContent]); var menu = h('ul', { ref: 'menu', staticClass: 'dropdown-menu', class: this.menuClasses, attrs: { role: this.role, tabindex: '-1', 'aria-labelledby': this.safeId(this.split ? '_BV_button_' : '_BV_toggle_') }, on: { keydown: this.onKeydown // Handle UP, DOWN and ESC } }, !this.lazy || this.visible ? this.normalizeSlot('default', { hide: this.hide }) : [h()]); return h('div', { staticClass: 'dropdown b-dropdown', class: this.dropdownClasses, attrs: { id: this.safeId() } }, [split, toggle, menu]); } }); var props$k = propsFactory(); // @vue/component var BDropdownItem = /*#__PURE__*/ Vue.extend({ name: 'BDropdownItem', mixins: [normalizeSlotMixin], inheritAttrs: false, inject: { bvDropdown: { default: null } }, props: _objectSpread2({}, props$k, { variant: { type: String, default: null } }), methods: { closeDropdown: function closeDropdown() { var _this = this; // Close on next animation frame to allow time to process requestAF(function () { if (_this.bvDropdown) { _this.bvDropdown.hide(true); } }); }, onClick: function onClick(evt) { this.$emit('click', evt); this.closeDropdown(); } }, render: function render(h) { return h('li', { attrs: { role: 'presentation' } }, [h(BLink, { props: this.$props, staticClass: 'dropdown-item', class: _defineProperty({}, "text-".concat(this.variant), this.variant && !(this.active || this.disabled)), attrs: _objectSpread2({}, this.$attrs, { role: 'menuitem' }), on: { click: this.onClick }, ref: 'item' }, this.normalizeSlot('default'))]); } }); var props$l = { active: { type: Boolean, default: false }, activeClass: { type: String, default: 'active' }, disabled: { type: Boolean, default: false }, variant: { type: String, default: null } }; // @vue/component var BDropdownItemButton = /*#__PURE__*/ Vue.extend({ name: 'BDropdownItemButton', mixins: [normalizeSlotMixin], inheritAttrs: false, inject: { bvDropdown: { default: null } }, props: props$l, methods: { closeDropdown: function closeDropdown() { if (this.bvDropdown) { this.bvDropdown.hide(true); } }, onClick: function onClick(evt) { this.$emit('click', evt); this.closeDropdown(); } }, render: function render(h) { var _class; return h('li', { attrs: { role: 'presentation' } }, [h('button', { staticClass: 'dropdown-item', class: (_class = {}, _defineProperty(_class, this.activeClass, this.active), _defineProperty(_class, "text-".concat(this.variant), this.variant && !(this.active || this.disabled)), _class), attrs: _objectSpread2({}, this.$attrs, { role: 'menuitem', type: 'button', disabled: this.disabled }), on: { click: this.onClick }, ref: 'button' }, this.normalizeSlot('default'))]); } }); var props$m = { id: { type: String, default: null }, tag: { type: String, default: 'header' }, variant: { type: String, default: null } }; // @vue/component var BDropdownHeader = /*#__PURE__*/ Vue.extend({ name: 'BDropdownHeader', functional: true, props: props$m, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; var $attrs = data.attrs || {}; data.attrs = {}; return h('li', mergeData(data, { attrs: { role: 'presentation' } }), [h(props.tag, { staticClass: 'dropdown-header', class: _defineProperty({}, "text-".concat(props.variant), props.variant), attrs: _objectSpread2({}, $attrs, { id: props.id || null, role: 'heading' }), ref: 'header' }, children)]); } }); var props$n = { tag: { type: String, default: 'hr' } }; // @vue/component var BDropdownDivider = /*#__PURE__*/ Vue.extend({ name: 'BDropdownDivider', functional: true, props: props$n, render: function render(h, _ref) { var props = _ref.props, data = _ref.data; var $attrs = data.attrs || {}; data.attrs = {}; return h('li', mergeData(data, { attrs: { role: 'presentation' } }), [h(props.tag, { staticClass: 'dropdown-divider', attrs: _objectSpread2({}, $attrs, { role: 'separator', 'aria-orientation': 'horizontal' }), ref: 'divider' })]); } }); var props$o = { id: { type: String, default: null }, inline: { type: Boolean, default: false }, novalidate: { type: Boolean, default: false }, validated: { type: Boolean, default: false } }; // @vue/component var BForm = /*#__PURE__*/ Vue.extend({ name: 'BForm', functional: true, props: props$o, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h('form', mergeData(data, { class: { 'form-inline': props.inline, 'was-validated': props.validated }, attrs: { id: props.id, novalidate: props.novalidate } }), children); } }); var BDropdownForm = /*#__PURE__*/ Vue.extend({ name: 'BDropdownForm', functional: true, props: _objectSpread2({}, props$o, { disabled: { type: Boolean, default: false }, formClass: { type: [String, Object, Array], default: null } }), render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; var $attrs = data.attrs || {}; var $listeners = data.on || {}; data.attrs = {}; data.on = {}; return h('li', mergeData(data, { attrs: { role: 'presentation' } }), [h(BForm, { ref: 'form', staticClass: 'b-dropdown-form', class: [props.formClass, { disabled: props.disabled }], props: props, attrs: _objectSpread2({}, $attrs, { disabled: props.disabled, // Tab index of -1 for keyboard navigation tabindex: props.disabled ? null : '-1' }), on: $listeners }, children)]); } }); var BDropdownText = /*#__PURE__*/ Vue.extend({ name: 'BDropdownText', functional: true, props: { tag: { type: String, default: 'p' }, variant: { type: String, default: null } }, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; var $attrs = data.attrs || {}; data.attrs = {}; return h('li', mergeData(data, { attrs: { role: 'presentation' } }), [h(props.tag, { staticClass: 'b-dropdown-text', class: _defineProperty({}, "text-".concat(props.variant), props.variant), props: props, attrs: $attrs, ref: 'text' }, children)]); } }); var props$p = { id: { type: String, default: null }, header: { type: String, default: null }, headerTag: { type: String, default: 'header' }, headerVariant: { type: String, default: null }, headerClasses: { type: [String, Array, Object], default: null }, ariaDescribedby: { type: String, default: null } }; // @vue/component var BDropdownGroup = /*#__PURE__*/ Vue.extend({ name: 'BDropdownGroup', functional: true, props: props$p, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, slots = _ref.slots, scopedSlots = _ref.scopedSlots; var $slots = slots(); var $scopedSlots = scopedSlots || {}; var $attrs = data.attrs || {}; data.attrs = {}; var header; var headerId = null; if (hasNormalizedSlot('header', $scopedSlots, $slots) || props.header) { headerId = props.id ? "_bv_".concat(props.id, "_group_dd_header") : null; header = h(props.headerTag, { staticClass: 'dropdown-header', class: [props.headerClasses, _defineProperty({}, "text-".concat(props.variant), props.variant)], attrs: { id: headerId, role: 'heading' } }, normalizeSlot('header', {}, $scopedSlots, $slots) || props.header); } var adb = [headerId, props.ariaDescribedBy].filter(Boolean).join(' ').trim(); return h('li', mergeData(data, { attrs: { role: 'presentation' } }), [header || h(), h('ul', { staticClass: 'list-unstyled', attrs: _objectSpread2({}, $attrs, { id: props.id || null, role: 'group', 'aria-describedby': adb || null }) }, normalizeSlot('default', {}, $scopedSlots, $slots))]); } }); var DropdownPlugin = /*#__PURE__*/ pluginFactory({ components: { BDropdown: BDropdown, BDd: BDropdown, BDropdownItem: BDropdownItem, BDdItem: BDropdownItem, BDropdownItemButton: BDropdownItemButton, BDropdownItemBtn: BDropdownItemButton, BDdItemButton: BDropdownItemButton, BDdItemBtn: BDropdownItemButton, BDropdownHeader: BDropdownHeader, BDdHeader: BDropdownHeader, BDropdownDivider: BDropdownDivider, BDdDivider: BDropdownDivider, BDropdownForm: BDropdownForm, BDdForm: BDropdownForm, BDropdownText: BDropdownText, BDdText: BDropdownText, BDropdownGroup: BDropdownGroup, BDdGroup: BDropdownGroup } }); var props$q = { type: { type: String, default: 'iframe', validator: function validator(str) { return arrayIncludes(['iframe', 'embed', 'video', 'object', 'img', 'b-img', 'b-img-lazy'], str); } }, tag: { type: String, default: 'div' }, aspect: { type: String, default: '16by9' } }; // @vue/component var BEmbed = /*#__PURE__*/ Vue.extend({ name: 'BEmbed', functional: true, props: props$q, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.tag, { ref: data.ref, staticClass: 'embed-responsive', class: _defineProperty({}, "embed-responsive-".concat(props.aspect), props.aspect) }, [h(props.type, mergeData(data, { ref: '', staticClass: 'embed-responsive-item' }), children)]); } }); var EmbedPlugin = /*#__PURE__*/ pluginFactory({ components: { BEmbed: BEmbed } }); var OPTIONS_OBJECT_DEPRECATED_MSG = 'Setting prop "options" to an object is deprecated. Use the array format instead.'; // @vue/component var formOptionsMixin = { props: { options: { type: [Array, Object], default: function _default() { return []; } }, valueField: { type: String, default: 'value' }, textField: { type: String, default: 'text' }, htmlField: { type: String, default: 'html' }, disabledField: { type: String, default: 'disabled' } }, computed: { formOptions: function formOptions() { var _this = this; var options = this.options; // Normalize the given options array if (isArray(options)) { return options.map(function (option) { return _this.normalizeOption(option); }); } // Deprecate the object options format warn(OPTIONS_OBJECT_DEPRECATED_MSG, this.$options.name); // Normalize a `options` object to an array of options return keys(options).map(function (key) { return _this.normalizeOption(options[key] || {}, key); }); } }, methods: { normalizeOption: function normalizeOption(option) { var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; // When the option is an object, normalize it if (isPlainObject(option)) { var value = get(option, this.valueField); var text = get(option, this.textField); return { value: isUndefined(value) ? key || text : value, text: stripTags(String(isUndefined(text) ? key : text)), html: get(option, this.htmlField), disabled: Boolean(get(option, this.disabledField)) }; } // Otherwise create an `` object if (isArray(options)) { return { label: String(get(option, this.labelField) || text), options: options }; } // Otherwise create an `