import { defineComponent, computed, createElementBlock, openBlock, normalizeClass, renderSlot, unref, inject, toValue, readonly, toRef, watch, mergeModels, useSlots, useModel, createBlock, normalizeProps, guardReactiveProps, withCtx, createCommentVNode, withDirectives, createVNode, Fragment, renderList, mergeProps, createTextVNode, toDisplayString, vShow, resolveDynamicComponent, createElementVNode, onMounted, provide, createSlots } from "vue";
import { _ as _sfc_main$8 } from "./BTableSimple.vue_vue_type_script_setup_true_lang-COdODP3B.mjs";
import { u as useDefaults } from "./useDefaults-DvqfKEoD.mjs";
import { p as pick, d as deepEqual, s as set } from "./object-hfadz3TY.mjs";
import { g as getDataLabelAttr, a as getWithGetter, b as bTableSimpleProps, c as getTableFieldHeadLabel, d as getByFieldKey, f as formatItem, e as bTableLiteProps } from "./tableUtils-CEJcbxqj.mjs";
import { u as useId } from "./useId-9_HUwM96.mjs";
import { s as startCase } from "./stringUtils-BRGdLBKx.mjs";
import { a as CODE_DOWN, C as CODE_UP, d as CODE_HOME, e as CODE_END } from "./constants-CXMQW_qx.mjs";
import { s as stopEvent } from "./event-a_bi5ysw.mjs";
import { x as tableKeyboardNavigationKey } from "./keys-D5Pj1dmf.mjs";
import { u as useDebounceFn } from "./debounce-CAItkwCO.mjs";
import { u as useToNumber } from "./index-DX8Yoi0C.mjs";
const isTableItem = (value) => typeof value === "object" && value !== null;
const isTableField = (value) => typeof value === "object" && value !== null && "key" in value;
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
  __name: "BTbody",
  props: {
    variant: { default: null }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults(_props, "BTbody");
    const computedClasses = computed(() => ({
      [`thead-${props.variant}`]: props.variant !== null
    }));
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("tbody", {
        class: normalizeClass(computedClasses.value)
      }, [
        renderSlot(_ctx.$slots, "default")
      ], 2);
    };
  }
});
const _hoisted_1$3 = ["colspan", "rowspan", "data-label"];
const _hoisted_2$3 = { key: 0 };
const _sfc_main$6 = /* @__PURE__ */ defineComponent({
  __name: "BTd",
  props: {
    colspan: { default: void 0 },
    rowspan: { default: void 0 },
    stackedHeading: { default: void 0 },
    stickyColumn: { type: Boolean, default: false },
    variant: { default: null }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults(_props, "BTd");
    const computedClasses = computed(() => ({
      [`table-${props.variant}`]: props.variant !== null,
      "b-table-sticky-column": props.stickyColumn,
      "table-b-table-default": props.stickyColumn && props.variant === null
    }));
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("td", {
        class: normalizeClass(computedClasses.value),
        colspan: unref(props).colspan,
        rowspan: unref(props).rowspan,
        "data-label": unref(props).stackedHeading
      }, [
        unref(props).stackedHeading ? (openBlock(), createElementBlock("div", _hoisted_2$3, [
          renderSlot(_ctx.$slots, "default")
        ])) : renderSlot(_ctx.$slots, "default", { key: 1 })
      ], 10, _hoisted_1$3);
    };
  }
});
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
  __name: "BTfoot",
  props: {
    variant: { default: null }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults(_props, "BTfoot");
    const computedClasses = computed(() => ({
      [`table-${props.variant}`]: props.variant !== null
    }));
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("tfoot", {
        class: normalizeClass(computedClasses.value)
      }, [
        renderSlot(_ctx.$slots, "default")
      ], 2);
    };
  }
});
const _hoisted_1$2 = ["scope", "colspan", "rowspan", "data-label"];
const _hoisted_2$2 = { key: 0 };
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
  __name: "BTh",
  props: {
    colspan: { default: void 0 },
    rowspan: { default: void 0 },
    stackedHeading: { default: void 0 },
    stickyColumn: { type: Boolean, default: false },
    variant: { default: null },
    scope: { default: void 0 }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults(_props, "BTh");
    const computedClasses = computed(() => ({
      [`table-${props.variant}`]: props.variant !== null,
      "b-table-sticky-column": props.stickyColumn,
      "table-b-table-default": props.stickyColumn && props.variant === null
    }));
    const localScope = computed(
      () => props.scope ? props.scope : props.colspan ? "colgroup" : props.rowspan ? "rowgroup" : "col"
    );
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("th", {
        scope: localScope.value,
        class: normalizeClass(computedClasses.value),
        colspan: unref(props).colspan,
        rowspan: unref(props).rowspan,
        "data-label": unref(props).stackedHeading
      }, [
        unref(props).stackedHeading !== void 0 ? (openBlock(), createElementBlock("div", _hoisted_2$2, [
          renderSlot(_ctx.$slots, "default")
        ])) : renderSlot(_ctx.$slots, "default", { key: 1 })
      ], 10, _hoisted_1$2);
    };
  }
});
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
  __name: "BThead",
  props: {
    variant: { default: null }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults(_props, "BThead");
    const computedClasses = computed(() => ({
      [`table-${props.variant}`]: props.variant !== null
    }));
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("thead", {
        class: normalizeClass(computedClasses.value)
      }, [
        renderSlot(_ctx.$slots, "default")
      ], 2);
    };
  }
});
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
  __name: "BTr",
  props: {
    variant: { default: null }
  },
  setup(__props) {
    const _props = __props;
    const props = useDefaults(_props, "BTr");
    const computedClasses = computed(() => ({
      [`table-${props.variant}`]: props.variant !== null
    }));
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("tr", {
        class: normalizeClass(computedClasses.value)
      }, [
        renderSlot(_ctx.$slots, "default")
      ], 2);
    };
  }
});
const TABLE_TAG_NAMES = ["TD", "TH", "TR"];
const eventFilter = [
  "a",
  "a *",
  // Include content inside links
  "button",
  "button *",
  // Include content inside buttons
  "input:not(.disabled):not([disabled])",
  "select:not(.disabled):not([disabled])",
  "textarea:not(.disabled):not([disabled])",
  '[role="link"]',
  '[role="link"] *',
  '[role="button"]',
  '[role="button"] *',
  "[tabindex]:not(.disabled):not([disabled])"
].join(",");
const filterEvent = (event) => {
  if (!event || !event.target) {
    return false;
  }
  const el = event.target;
  if ("disabled" in el && el.disabled || TABLE_TAG_NAMES.indexOf(el.tagName) !== -1) {
    return false;
  }
  if (el.closest(".dropdown-menu")) return true;
  const label = el.tagName === "LABEL" ? el : el.closest("label");
  if (label) {
    const labelFor = label.getAttribute("for");
    const input = labelFor ? document.getElementById(labelFor) : label.querySelector("input, select, textarea");
    if (input && !input.disabled) {
      return true;
    }
  }
  return el.matches(eventFilter);
};
const useTableFieldsMapper = ({
  fields,
  items,
  stackedProps
}) => {
  const computedFields = computed(() => {
    const fieldsValue = toValue(fields);
    const itemsValue = toValue(items);
    const stacked = {
      stacked: toValue(stackedProps.stacked),
      labelStacked: toValue(stackedProps.labelStacked)
    };
    if (!fieldsValue.length && itemsValue.length) {
      const [firstItem] = itemsValue;
      if (firstItem && (isTableItem(firstItem) || Array.isArray(firstItem))) {
        return {
          items: Object.keys(firstItem).map((k) => {
            const label = startCase(k);
            return {
              key: k,
              label,
              tdAttr: getDataLabelAttr(stacked, label)
            };
          })
        };
      }
      return { items: [{ key: "" }], opts: { noHeader: true } };
    }
    return {
      items: fieldsValue.map((f) => {
        if (isTableField(f)) {
          const label2 = f.label ?? startCase(f.key);
          const dataLabelAttr = getDataLabelAttr(stacked, label2);
          const tdAttr = typeof f.tdAttr === "function" ? (obj) => ({
            ...dataLabelAttr,
            ...f.tdAttr(obj)
          }) : dataLabelAttr || f.tdAttr ? { ...dataLabelAttr, ...f.tdAttr } : void 0;
          return {
            ...f,
            tdAttr
          };
        }
        const label = startCase(f);
        return {
          key: f,
          label,
          tdAttr: getDataLabelAttr(stacked, label)
        };
      })
    };
  });
  const total = computed(() => computedFields.value.items.length);
  const showHeaders = computed(
    () => (
      // We only hide the header if all fields have _noHeader set to true. Which would be our doing
      // This usually happens under a circumstance of displaying an array of primitives
      // Under any other circumstance, I'm not sure how this would apply
      !(total.value > 0 && computedFields.value.opts?.noHeader === true)
    )
  );
  return {
    total,
    showHeaders,
    fields: computed(() => computedFields.value.items)
  };
};
const useItemTracker = ({
  allItems,
  selectedItems,
  primaryKey
}) => {
  const isActivated = computed(() => selectedItems.value.length > 0);
  const pKey = readonly(toRef(primaryKey));
  const get = (item) => {
    if (typeof item === "object" && item !== null && pKey.value) {
      return getWithGetter(item, pKey.value);
    }
    return item;
  };
  const add = (item) => {
    const value = get(item);
    selectedItems.value = [...selectedItems.value, value];
  };
  const set2 = (items) => {
    selectedItems.value = pKey.value ? items.map(get) : items;
  };
  const setAll = () => set2([...toValue(allItems)]);
  const remove = (item) => {
    const value = get(item);
    selectedItems.value = selectedItems.value.filter((i) => i !== value);
  };
  const clear = () => {
    selectedItems.value = [];
  };
  const has = (item) => {
    const value = get(item);
    return selectedItems.value.includes(value);
  };
  watch(pKey, () => {
    clear();
  });
  const objectsMap = computed(() => {
    if (!pKey.value) return /* @__PURE__ */ new Map();
    return new Map(toValue(allItems).map((item) => [get(item), item]));
  });
  const getFromPrimaryKey = (value) => {
    if (!pKey.value) return void 0;
    return objectsMap.value.get(value);
  };
  const resolvedItems = computed(() => {
    if (!pKey.value) return selectedItems.value;
    const arr = [];
    selectedItems.value.forEach((item) => {
      const resolved = getFromPrimaryKey(item);
      if (resolved !== void 0) {
        arr.push(resolved);
      }
    });
    return arr;
  });
  return {
    getFromPrimaryKey,
    resolvedItems,
    isActivated,
    get,
    add,
    remove,
    clear,
    set: set2,
    has,
    setAll
  };
};
const useItemExpansion = ({
  allItems,
  primaryKey,
  expandedItems
}) => {
  const utils = useItemTracker({
    primaryKey,
    allItems,
    selectedItems: expandedItems
  });
  const toggle = (item) => {
    if (utils.has(item)) {
      utils.remove(item);
    } else {
      utils.add(item);
    }
  };
  return {
    ...utils,
    toggle
  };
};
const useTableKeyboardNavigation = ({
  items,
  id
}, events) => {
  const keyboardNavigation = inject(tableKeyboardNavigationKey, null);
  const shouldHeaderBeFocusable = (field) => !!(keyboardNavigation?.headerNavigation.value && field.sortable === true);
  const shouldRowBeFocusable = computed(
    () => !!(keyboardNavigation?.rowNavigation.value && toValue(items).length > 0)
  );
  const headerClicked = (field, event, isFooter = false) => {
    events.onHeadClicked({ key: field.key, field, event, isFooter });
  };
  const handleHeaderKeydown = (field, event, isFooter = false) => {
    const { target, code } = event;
    if (target && target.tagName !== "TH" && document.activeElement === target) return;
    if (code === "Enter" || code === "NumpadEnter" || code === "Space") {
      stopEvent(event);
      headerClicked(field, event, isFooter);
    }
  };
  const handleRowKeydown = (item, itemIndex, event) => {
    const { target, code, shiftKey } = event;
    if (target && target.tagName !== "TR" && document.activeElement === target) return;
    if (code === "Enter" || code === "NumpadEnter" || code === "Space") {
      stopEvent(event);
      events.onRowClicked({ item, index: itemIndex, event });
      return;
    }
    if (code === CODE_DOWN || code === CODE_UP || code === CODE_HOME || code === CODE_END) {
      stopEvent(event);
      handleRowNavigation(code, shiftKey, itemIndex);
    }
  };
  const handleRowNavigation = (code, shiftKey, currentIndex) => {
    const rows = Array.from(
      document.querySelectorAll(`#${toValue(id)} tbody tr[tabindex]`)
    );
    if (rows.length === 0) return;
    let targetIndex = currentIndex;
    if (code === CODE_DOWN) {
      if (shiftKey) {
        targetIndex = rows.length - 1;
      } else {
        targetIndex = Math.min(currentIndex + 1, rows.length - 1);
      }
    } else if (code === CODE_UP) {
      if (shiftKey) {
        targetIndex = 0;
      } else {
        targetIndex = Math.max(currentIndex - 1, 0);
      }
    } else if (code === CODE_END) {
      targetIndex = rows.length - 1;
    } else if (code === CODE_HOME) {
      targetIndex = 0;
    }
    if (targetIndex !== currentIndex && rows[targetIndex]) {
      rows[targetIndex].focus();
    }
  };
  const handleMiddleClick = (item, itemIndex, event) => {
    if (event.button === 1 && !filterEvent(event)) {
      events.onRowMiddleClicked({ item, index: itemIndex, event });
    }
  };
  return {
    shouldHeaderBeFocusable,
    headerClicked,
    handleHeaderKeydown,
    shouldRowBeFocusable,
    handleRowKeydown,
    handleMiddleClick
  };
};
const _hoisted_1$1 = { key: 0 };
const _hoisted_2$1 = {
  key: 0,
  class: "b-table-stacked-label"
};
const _hoisted_3 = { class: "d-inline-flex flex-nowrap align-items-center gap-1" };
const _hoisted_4 = { key: 3 };
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
  __name: "BTableLite",
  props: /* @__PURE__ */ mergeModels({
    align: { default: void 0 },
    caption: { default: void 0 },
    detailsTdClass: { default: void 0 },
    fieldColumnClass: { type: [Function, String, Object, Array], default: void 0 },
    fields: { default: () => [] },
    footClone: { type: Boolean, default: false },
    footRowVariant: { default: void 0 },
    footVariant: { default: void 0 },
    headRowVariant: { default: void 0 },
    headVariant: { default: void 0 },
    items: { default: () => [] },
    labelStacked: { type: Boolean, default: false },
    modelValue: { default: void 0 },
    primaryKey: { type: [String, Function], default: void 0 },
    tbodyClass: { default: void 0 },
    tbodyTrAttrs: { type: [Function, Object], default: void 0 },
    tbodyTrClass: { type: [Function, String, Array, Object], default: void 0 },
    tfootClass: { default: void 0 },
    tfootTrClass: { default: void 0 },
    theadClass: { default: void 0 },
    theadTrClass: { default: void 0 },
    bordered: { type: Boolean, default: void 0 },
    borderless: { type: Boolean, default: void 0 },
    borderVariant: { default: void 0 },
    captionTop: { type: Boolean, default: void 0 },
    dark: { type: Boolean, default: void 0 },
    fixed: { type: Boolean, default: void 0 },
    hover: { type: Boolean, default: void 0 },
    id: { default: void 0 },
    noBorderCollapse: { type: Boolean, default: void 0 },
    outlined: { type: Boolean, default: void 0 },
    responsive: { type: [Boolean, String], default: void 0 },
    small: { type: Boolean, default: void 0 },
    stacked: { type: [Boolean, String], default: void 0 },
    stickyHeader: { type: [Boolean, String, Number], default: void 0 },
    striped: { type: Boolean, default: void 0 },
    stripedColumns: { type: Boolean, default: void 0 },
    variant: { default: void 0 },
    tableAttrs: {},
    tableClass: { default: void 0 }
  }, {
    "expandedItems": {
      default: () => []
    },
    "expandedItemsModifiers": {}
  }),
  emits: /* @__PURE__ */ mergeModels(["head-clicked", "row-clicked", "row-dblclicked", "row-contextmenu", "row-hovered", "row-unhovered", "row-middle-clicked"], ["update:expandedItems"]),
  setup(__props, { expose: __expose, emit: __emit }) {
    const _props = __props;
    const props = useDefaults(_props, "BTableLite");
    const emit = __emit;
    const slots = useSlots();
    const expandedItems = useModel(
      __props,
      "expandedItems"
    );
    const computedId = useId(() => props.id);
    const expandedItemsController = useItemExpansion({
      allItems: () => props.items,
      primaryKey: toRef(() => props.primaryKey),
      expandedItems
    });
    const keyboardController = useTableKeyboardNavigation(
      {
        items: () => props.items,
        id: computedId
      },
      {
        onHeadClicked: (obj) => {
          emit("head-clicked", obj);
        },
        onRowClicked: (obj) => {
          emit("row-clicked", obj);
        },
        onRowMiddleClicked: (obj) => {
          emit("row-middle-clicked", obj);
        }
      }
    );
    const {
      fields: computedFields,
      total: computedFieldsTotal,
      showHeaders: showComputedHeaders
    } = useTableFieldsMapper({
      fields: () => props.fields,
      items: () => props.items,
      stackedProps: {
        labelStacked: () => props.labelStacked,
        stacked: () => props.stacked
      }
    });
    const calculatedFooterSlot = (key) => slots[`foot(${key})`] ? `foot(${key})` : slots["foot()"] ? "foot()" : slots[`head(${key})`] ? `head(${key})` : "head()";
    const computedTableClasses = computed(() => [
      props.tableClass,
      {
        [`align-${props.align}`]: props.align !== void 0
      }
    ]);
    const getFieldColumnClasses = (field) => [
      field.class,
      field.thClass,
      {
        "b-table-sticky-column": field.stickyColumn
      },
      props.fieldColumnClass ? typeof props.fieldColumnClass === "function" ? props.fieldColumnClass(field) : props.fieldColumnClass : null
    ];
    const getFieldRowClasses = (field, tr) => [
      field.class,
      typeof field.tdClass === "function" ? field.tdClass(getByFieldKey(tr, field), field.key, tr) : field.tdClass,
      (isTableItem(tr) ? tr._cellVariants?.[field.key] : false) ? `table-${tr._cellVariants?.[field.key]}` : null,
      {
        "b-table-sticky-column": field.stickyColumn
      }
    ];
    const getRowClasses = (item, type) => props.tbodyTrClass ? typeof props.tbodyTrClass === "function" ? props.tbodyTrClass(item, type) : props.tbodyTrClass : null;
    const itemAttributes = (item, field) => field.tdAttr && typeof field.tdAttr === "function" ? field.tdAttr({ value: getByFieldKey(item, field), key: field.key, item }) : field.tdAttr;
    const callThAttr = (item, field, type) => field.thAttr && typeof field.thAttr === "function" ? field.thAttr({ value: getByFieldKey(item, field), key: field.key, item, type }) : field.thAttr;
    const callTbodyTrAttrs = (item, type) => props.tbodyTrAttrs ? typeof props.tbodyTrAttrs === "function" ? props.tbodyTrAttrs(item, type) : props.tbodyTrAttrs : null;
    const generateTableRowId = (primaryKeyValue) => `${computedId.value}__row_${primaryKeyValue}`;
    const getCellComponent = (field) => {
      if (field?.isRowHeader) {
        return _sfc_main$4;
      }
      return _sfc_main$6;
    };
    const footerProps = computed(() => ({
      variant: props.footVariant ?? props.headVariant,
      class: props.tfootClass ?? props.theadClass
    }));
    const computedSimpleProps = computed(() => ({
      ...pick(props, bTableSimpleProps),
      tableClass: computedTableClasses.value,
      id: computedId.value
    }));
    __expose({
      expansion: {
        ...expandedItemsController,
        expandedItems: readonly(expandedItems)
      }
    });
    return (_ctx, _cache) => {
      return openBlock(), createBlock(_sfc_main$8, normalizeProps(guardReactiveProps(computedSimpleProps.value)), {
        default: withCtx(() => [
          slots["table-colgroup"] ? (openBlock(), createElementBlock("colgroup", _hoisted_1$1, [
            renderSlot(_ctx.$slots, "table-colgroup", { fields: unref(computedFields) })
          ])) : createCommentVNode("", true),
          withDirectives(createVNode(_sfc_main$3, {
            variant: unref(props).headVariant,
            class: normalizeClass(unref(props).theadClass)
          }, {
            default: withCtx(() => [
              renderSlot(_ctx.$slots, "thead-top", {
                columns: unref(computedFieldsTotal),
                fields: unref(computedFields)
              }),
              createVNode(_sfc_main$2, {
                variant: unref(props).headRowVariant,
                class: normalizeClass(unref(props).theadTrClass)
              }, {
                default: withCtx(() => [
                  (openBlock(true), createElementBlock(Fragment, null, renderList(unref(computedFields), (field) => {
                    return openBlock(), createBlock(_sfc_main$4, mergeProps({
                      key: field.key,
                      scope: field.scope,
                      class: getFieldColumnClasses(field),
                      title: field.headerTitle,
                      variant: field.variant,
                      abbr: field.headerAbbr,
                      style: field.thStyle,
                      tabindex: unref(keyboardController).shouldHeaderBeFocusable(field) ? "0" : void 0
                    }, { ref_for: true }, callThAttr(null, field, "top"), {
                      onClick: ($event) => unref(keyboardController).headerClicked(field, $event),
                      onKeydown: ($event) => unref(keyboardController).handleHeaderKeydown(field, $event)
                    }), {
                      default: withCtx(() => [
                        renderSlot(_ctx.$slots, slots[`head(${field.key})`] ? `head(${field.key})` : "head()", {
                          label: field.label,
                          column: field.key,
                          field,
                          isFoot: false
                        }, () => [
                          createTextVNode(toDisplayString(unref(getTableFieldHeadLabel)(field)), 1)
                        ])
                      ]),
                      _: 2
                    }, 1040, ["scope", "class", "title", "variant", "abbr", "style", "tabindex", "onClick", "onKeydown"]);
                  }), 128))
                ]),
                _: 3
              }, 8, ["variant", "class"]),
              slots["thead-sub"] ? (openBlock(), createBlock(_sfc_main$2, { key: 0 }, {
                default: withCtx(() => [
                  (openBlock(true), createElementBlock(Fragment, null, renderList(unref(computedFields), (field) => {
                    return openBlock(), createBlock(_sfc_main$6, {
                      key: field.key,
                      scope: "col",
                      variant: field.variant,
                      class: normalizeClass([field.class, field.thClass])
                    }, {
                      default: withCtx(() => [
                        renderSlot(_ctx.$slots, "thead-sub", {
                          items: unref(props).items,
                          fields: unref(computedFields),
                          field
                        }, () => [
                          createTextVNode(toDisplayString(field.label), 1)
                        ])
                      ]),
                      _: 2
                    }, 1032, ["variant", "class"]);
                  }), 128))
                ]),
                _: 3
              })) : createCommentVNode("", true)
            ]),
            _: 3
          }, 8, ["variant", "class"]), [
            [vShow, unref(showComputedHeaders)]
          ]),
          createVNode(_sfc_main$7, {
            class: normalizeClass(unref(props).tbodyClass)
          }, {
            default: withCtx(() => [
              renderSlot(_ctx.$slots, "custom-body", {
                fields: unref(computedFields),
                items: unref(props).items,
                columns: unref(computedFieldsTotal)
              }, () => [
                !unref(props).stacked && slots["top-row"] ? (openBlock(), createBlock(_sfc_main$2, mergeProps({
                  key: 0,
                  class: getRowClasses(null, "row-top")
                }, callTbodyTrAttrs(null, "row-top")), {
                  default: withCtx(() => [
                    renderSlot(_ctx.$slots, "top-row", {
                      columns: unref(computedFieldsTotal),
                      fields: unref(computedFields)
                    })
                  ]),
                  _: 3
                }, 16, ["class"])) : createCommentVNode("", true),
                (openBlock(true), createElementBlock(Fragment, null, renderList(unref(props).items, (item, itemIndex) => {
                  return openBlock(), createElementBlock(Fragment, {
                    key: unref(props).primaryKey && unref(isTableItem)(item) && unref(getWithGetter)(item, unref(props).primaryKey) ? unref(getWithGetter)(item, unref(props).primaryKey) : itemIndex
                  }, [
                    createVNode(_sfc_main$2, mergeProps({
                      id: unref(props).primaryKey && unref(isTableItem)(item) && unref(getWithGetter)(item, unref(props).primaryKey) ? generateTableRowId(unref(getWithGetter)(item, unref(props).primaryKey)) : void 0,
                      class: getRowClasses(item, "row"),
                      variant: unref(isTableItem)(item) ? item._rowVariant : void 0,
                      tabindex: unref(keyboardController).shouldRowBeFocusable.value ? "0" : void 0
                    }, { ref_for: true }, callTbodyTrAttrs(item, "row"), {
                      onClick: ($event) => !unref(filterEvent)($event) && emit("row-clicked", { item, index: itemIndex, event: $event }),
                      onDblclick: ($event) => !unref(filterEvent)($event) && emit("row-dblclicked", { item, index: itemIndex, event: $event }),
                      onContextmenu: ($event) => !unref(filterEvent)($event) && emit("row-contextmenu", { item, index: itemIndex, event: $event }),
                      onMouseenter: ($event) => !unref(filterEvent)($event) && emit("row-hovered", { item, index: itemIndex, event: $event }),
                      onMouseleave: ($event) => !unref(filterEvent)($event) && emit("row-unhovered", { item, index: itemIndex, event: $event }),
                      onMousedown: ($event) => unref(keyboardController).handleMiddleClick(item, itemIndex, $event),
                      onKeydown: ($event) => unref(keyboardController).handleRowKeydown(item, itemIndex, $event)
                    }), {
                      default: withCtx(() => [
                        (openBlock(true), createElementBlock(Fragment, null, renderList(unref(computedFields), (field) => {
                          return openBlock(), createBlock(resolveDynamicComponent(getCellComponent(field)), mergeProps({
                            key: field.key,
                            variant: (unref(isTableItem)(item) ? item._cellVariants?.[field.key] : false) ? null : field.variant,
                            class: getFieldRowClasses(field, item)
                          }, { ref_for: true }, itemAttributes(item, field)), {
                            default: withCtx(() => [
                              unref(props).stacked && unref(props).labelStacked ? (openBlock(), createElementBlock("label", _hoisted_2$1, toDisplayString(unref(getTableFieldHeadLabel)(field)), 1)) : createCommentVNode("", true),
                              renderSlot(_ctx.$slots, slots[`cell(${field.key})`] ? `cell(${field.key})` : "cell()", {
                                value: unref(formatItem)(item, field),
                                unformatted: unref(getByFieldKey)(item, field),
                                index: itemIndex,
                                item,
                                field,
                                items: unref(props).items,
                                toggleExpansion: () => unref(expandedItemsController).toggle(item),
                                expansionShowing: unref(expandedItemsController).has(item)
                              }, () => [
                                !slots[`cell(${field.key})`] && !slots["cell()"] ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
                                  createTextVNode(toDisplayString(unref(formatItem)(item, field)), 1)
                                ], 64)) : createCommentVNode("", true)
                              ])
                            ]),
                            _: 2
                          }, 1040, ["variant", "class"]);
                        }), 128))
                      ]),
                      _: 2
                    }, 1040, ["id", "class", "variant", "tabindex", "onClick", "onDblclick", "onContextmenu", "onMouseenter", "onMouseleave", "onMousedown", "onKeydown"]),
                    unref(expandedItemsController).has(item) && slots["row-expansion"] ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
                      createVNode(_sfc_main$2, {
                        "aria-hidden": "true",
                        role: "presentation",
                        class: "d-none"
                      }),
                      createVNode(_sfc_main$2, mergeProps({
                        class: getRowClasses(item, "row-expansion"),
                        variant: unref(isTableItem)(item) ? item._rowVariant : void 0
                      }, { ref_for: true }, callTbodyTrAttrs(item, "row-expansion")), {
                        default: withCtx(() => [
                          createVNode(_sfc_main$6, {
                            colspan: unref(computedFieldsTotal),
                            class: normalizeClass(__props.detailsTdClass)
                          }, {
                            default: withCtx(() => [
                              renderSlot(_ctx.$slots, "row-expansion", {
                                item,
                                toggleExpansion: () => unref(expandedItemsController).toggle(item),
                                fields: unref(computedFields),
                                index: itemIndex
                              })
                            ]),
                            _: 2
                          }, 1032, ["colspan", "class"])
                        ]),
                        _: 2
                      }, 1040, ["class", "variant"])
                    ], 64)) : createCommentVNode("", true)
                  ], 64);
                }), 128)),
                !unref(props).stacked && slots["bottom-row"] ? (openBlock(), createBlock(_sfc_main$2, mergeProps({
                  key: 1,
                  class: ["bottom-row", getRowClasses(null, "row-bottom")]
                }, callTbodyTrAttrs(null, "row-bottom")), {
                  default: withCtx(() => [
                    renderSlot(_ctx.$slots, "bottom-row", {
                      columns: unref(computedFieldsTotal),
                      fields: unref(computedFields)
                    })
                  ]),
                  _: 3
                }, 16, ["class"])) : createCommentVNode("", true)
              ])
            ]),
            _: 3
          }, 8, ["class"]),
          unref(props).footClone ? (openBlock(), createBlock(_sfc_main$5, normalizeProps(mergeProps({ key: 1 }, footerProps.value)), {
            default: withCtx(() => [
              createVNode(_sfc_main$2, {
                variant: unref(props).footRowVariant ?? unref(props).headRowVariant,
                class: normalizeClass(unref(props).tfootTrClass ?? unref(props).theadTrClass)
              }, {
                default: withCtx(() => [
                  (openBlock(true), createElementBlock(Fragment, null, renderList(unref(computedFields), (field) => {
                    return openBlock(), createBlock(_sfc_main$4, mergeProps({
                      key: field.key,
                      scope: "col",
                      class: getFieldColumnClasses(field),
                      title: field.headerTitle,
                      abbr: field.headerAbbr,
                      style: field.thStyle,
                      variant: field.variant,
                      tabindex: unref(keyboardController).shouldHeaderBeFocusable(field) ? "0" : void 0
                    }, { ref_for: true }, callThAttr(null, field, "bottom"), {
                      onClick: ($event) => unref(keyboardController).headerClicked(field, $event, true),
                      onKeydown: ($event) => unref(keyboardController).handleHeaderKeydown(field, $event, true)
                    }), {
                      default: withCtx(() => [
                        createElementVNode("div", _hoisted_3, [
                          createElementVNode("div", null, [
                            renderSlot(_ctx.$slots, calculatedFooterSlot(field.key), {
                              label: field.label,
                              column: field.key,
                              field,
                              isFoot: true
                            }, () => [
                              createTextVNode(toDisplayString(unref(getTableFieldHeadLabel)(field)), 1)
                            ])
                          ])
                        ])
                      ]),
                      _: 2
                    }, 1040, ["class", "title", "abbr", "style", "variant", "tabindex", "onClick", "onKeydown"]);
                  }), 128))
                ]),
                _: 3
              }, 8, ["variant", "class"])
            ]),
            _: 3
          }, 16)) : slots["custom-foot"] ? (openBlock(), createBlock(_sfc_main$5, normalizeProps(mergeProps({ key: 2 }, footerProps.value)), {
            default: withCtx(() => [
              renderSlot(_ctx.$slots, "custom-foot", {
                fields: unref(computedFields),
                items: unref(props).items,
                columns: unref(computedFieldsTotal)
              })
            ]),
            _: 3
          }, 16)) : createCommentVNode("", true),
          slots["table-caption"] || unref(props).caption ? (openBlock(), createElementBlock("caption", _hoisted_4, [
            renderSlot(_ctx.$slots, "table-caption", {}, () => [
              createTextVNode(toDisplayString(unref(props).caption), 1)
            ])
          ])) : createCommentVNode("", true)
        ]),
        _: 3
      }, 16);
    };
  }
});
const useTableMapper = ({
  fields,
  items,
  stackedProps,
  provider,
  events,
  pagination
}) => {
  const sortByModelResolved = readonly(toRef(pagination.sort.by));
  const isSortableResolved = readonly(toRef(pagination.sort.isSortable));
  const filterResolved = readonly(toRef(pagination.filter.filter));
  const usesProviderResolved = readonly(toRef(provider.usesProvider));
  const isFilterableTable = computed(() => filterResolved.value !== void 0);
  const computedFields = computed(
    () => toValue(fields).map((el) => {
      if (!isTableField(el)) {
        const label = startCase(el);
        return {
          key: el,
          label,
          tdAttr: getDataLabelAttr(
            {
              stacked: toValue(stackedProps.stacked),
              labelStacked: toValue(stackedProps.labelStacked)
            },
            label
          )
        };
      }
      const value = sortByModelResolved.value?.find((sb) => el.key === sb.key);
      const sortValue = !el.sortable || isSortableResolved.value === false ? void 0 : value === void 0 ? "none" : value.order === "desc" ? "descending" : value.order === "asc" ? "ascending" : "none";
      return {
        ...el,
        thAttr: {
          "aria-sort": sortValue,
          ...el.thAttr
        },
        thClass: [
          el.thClass,
          {
            "b-table-sort-icon-left": toValue(pagination.sort.iconLeft) && sortValue !== void 0
          }
        ]
      };
    })
  );
  const getFormatter = (value) => typeof value.sortByFormatted === "function" ? value.sortByFormatted : value.formatter;
  const getStringValue = (ob, key) => {
    if (!isTableItem(ob)) return String(ob);
    const sortField = computedFields.value.find((el) => {
      if (isTableField(el)) return el.key === key;
      return false;
    });
    const val = isTableField(sortField) && sortField.accessor ? getWithGetter(ob, sortField.accessor) : getWithGetter(ob, key);
    if (isTableField(sortField) && !!sortField.sortByFormatted) {
      const formatter = getFormatter(sortField);
      if (formatter) {
        return String(formatItem(ob, { ...sortField, formatter }));
      }
    }
    return typeof val === "object" && val !== null ? JSON.stringify(val) : val?.toString() ?? "";
  };
  const fieldByKey = computed(() => {
    const map = /* @__PURE__ */ new Map();
    for (const f of computedFields.value) if (isTableField(f)) map.set(f.key, f);
    return map;
  });
  const computedItems = computed(() => {
    const filterableValue = toValue(pagination.filter.filterable);
    const filterFunctionValue = unref(pagination.filter.filterFunction);
    const itemsValue = toValue(items);
    const sortByItems = sortByModelResolved.value?.filter((el) => !!el.order);
    const mapItem = (item) => {
      if (typeof item === "object" && item !== null && Object.keys(item).some((key) => key.includes("."))) {
        let newItem = {};
        for (const key in item) {
          if (key.includes(".")) {
            newItem = set(newItem, key, item[key]);
          } else {
            newItem[key] = item[key];
          }
        }
        return newItem;
      }
      return item;
    };
    const filterItem = (item) => {
      if (!isTableItem(item)) return true;
      return Object.entries(item).some(([key, val]) => {
        if (val === null || val === void 0 || key[0] === "_" || !filterableValue?.includes(key) && !!filterableValue?.length)
          return false;
        if (typeof filterFunctionValue === "function") {
          return filterFunctionValue(item, filterResolved.value);
        }
        const realVal = () => {
          const filterField = computedFields.value.find((el) => {
            if (isTableField(el)) return el.key === key;
            return false;
          });
          if (isTableField(filterField) && !!filterField.filterByFormatted) {
            const formatter = getFormatter(filterField);
            if (formatter) {
              return String(formatter({ value: val, key: String(filterField.key), item }));
            }
          }
          return typeof val === "object" ? JSON.stringify(Object.values(val)) : val.toString();
        };
        const itemValue = realVal();
        return itemValue.toLowerCase().includes(filterResolved.value?.toLowerCase() ?? "");
      });
    };
    const noProviderFilteringValue = toValue(provider.noProviderFiltering);
    const mappedItems = itemsValue.reduce((acc, val) => {
      const item = mapItem(val);
      const shouldFilter = isFilterableTable.value && (!usesProviderResolved.value || noProviderFilteringValue);
      if (!shouldFilter || filterItem(item)) acc.push(item);
      return acc;
    }, []);
    if (sortByItems?.length && (isSortableResolved.value === true && !usesProviderResolved.value && !toValue(pagination.sort.noLocalSorting) || isSortableResolved.value === true && usesProviderResolved.value && toValue(provider.noProviderSorting))) {
      const sortCompareValue = unref(pagination.sort.sortCompare);
      return mappedItems.sort((a, b) => {
        for (let i = 0; i < sortByItems.length; i++) {
          const { key, order } = sortByItems[i];
          const field = fieldByKey.value.get(key);
          const comparer = field?.sortCompare || sortCompareValue;
          const comparison = comparer ? comparer(a, b, key) : getStringValue(a, key).localeCompare(getStringValue(b, key), void 0, {
            numeric: true
          });
          if (comparison !== 0) {
            return order === "asc" ? comparison : -comparison;
          }
        }
        return 0;
      });
    }
    return mappedItems;
  });
  const computedDisplayItems = computed(() => {
    const perPageNumber = toValue(pagination.perPage);
    const currentPageNumber = toValue(pagination.currentPage);
    if (Number.isNaN(perPageNumber) || usesProviderResolved.value && !toValue(provider.noProviderPaging)) {
      return computedItems.value;
    }
    return computedItems.value.slice(
      (currentPageNumber - 1) * (perPageNumber || Number.POSITIVE_INFINITY),
      currentPageNumber * (perPageNumber || Number.POSITIVE_INFINITY)
    );
  });
  watch(computedDisplayItems, (v) => {
    events.onChange([...v]);
  });
  return {
    items: computedItems,
    displayItems: computedDisplayItems,
    getStringValue,
    fields: computedFields,
    isFilterableTable
  };
};
const useTableKeyboardNavigationInjector = ({
  isSortable,
  selectable,
  noSelectOnClick
}) => {
  const keyboardRowNavigation = computed(() => !!(toValue(selectable) && !toValue(noSelectOnClick)));
  const keyboardHeaderNavigation = computed(() => !!toValue(isSortable));
  provide(tableKeyboardNavigationKey, {
    rowNavigation: keyboardRowNavigation,
    headerNavigation: keyboardHeaderNavigation
  });
};
const useTableSelectedItems = ({
  selectable,
  selectMode,
  selectedItems,
  events,
  primaryKey,
  allItems
}) => {
  const selectableResolved = readonly(toRef(selectable));
  const selectModeResolved = readonly(toRef(selectMode));
  const allItemsResolved = computed(() => toValue(allItems));
  const utils = useItemTracker({
    allItems: allItemsResolved,
    primaryKey,
    selectedItems
  });
  watch(selectedItems, (newValue, oldValue) => {
    Array.from(oldValue).filter((item) => !newValue.includes(item)).forEach((item) => {
      events.onRowUnselected(item);
    });
    Array.from(newValue).filter((item) => !oldValue.includes(item)).forEach((item) => {
      events.onRowSelected(item);
    });
  });
  const handleRowSelection = ({
    item,
    index,
    shiftClicked = false,
    ctrlClicked = false,
    metaClicked = false
  }) => {
    if (!selectableResolved.value) return;
    if (selectModeResolved.value === "single" || selectModeResolved.value === "multi") {
      if (shiftClicked || ctrlClicked) return;
      if (utils.has(item)) {
        utils.remove(item);
      } else {
        if (selectModeResolved.value === "single") {
          utils.set([item]);
        } else {
          utils.add(item);
        }
      }
    } else {
      if (ctrlClicked || metaClicked) {
        if (utils.has(item)) {
          utils.remove(item);
        } else {
          utils.add(item);
        }
      } else if (shiftClicked) {
        const lastSelectedItem = selectedItems.value[selectedItems.value.length - 1];
        const lastSelectedIndex = allItemsResolved.value.findIndex(
          (i) => utils.get(i) === lastSelectedItem
        );
        if (lastSelectedIndex === -1) {
          utils.set([item]);
          return;
        }
        const selectStartIndex = Math.min(lastSelectedIndex, index);
        const selectEndIndex = Math.max(lastSelectedIndex, index);
        const items = allItemsResolved.value.slice(selectStartIndex, selectEndIndex + 1);
        utils.set(items);
      } else {
        utils.set([item]);
      }
    }
  };
  return {
    ...utils,
    handleRowSelection,
    clear: () => {
      if (!selectableResolved.value) return;
      utils.clear();
    },
    setAll: () => {
      if (!selectableResolved.value || selectModeResolved.value === "single") return;
      utils.setAll();
    },
    add: (item) => {
      if (!selectableResolved.value || utils.has(item)) return;
      if (selectModeResolved.value === "single") {
        utils.set([item]);
      } else {
        utils.add(item);
      }
    },
    remove: (item) => {
      if (!selectableResolved.value) return;
      utils.remove(item);
    },
    has: (item) => {
      if (!selectableResolved.value) return false;
      return utils.has(item);
    }
  };
};
const useTableProvider = ({
  items,
  provider,
  busy,
  currentPage,
  debounce,
  perPage,
  noProvider,
  noProviderFiltering,
  noProviderPaging,
  noProviderSorting,
  filter,
  sortBy,
  events
}) => {
  const providerResolved = readonly(toRef(provider));
  const currentPageResolved = readonly(toRef(currentPage));
  const perPageResolved = readonly(toRef(perPage));
  const sortByResolved = readonly(toRef(sortBy));
  const filterResolved = readonly(toRef(filter));
  const usesProvider = computed(() => providerResolved.value !== void 0);
  let abortController = null;
  const callItemsProvider = async () => {
    if (!usesProvider.value || providerResolved.value === void 0) return;
    if (abortController) {
      abortController.abort();
    }
    abortController = new AbortController();
    const { signal } = abortController;
    busy.value = true;
    try {
      const response = providerResolved.value({
        currentPage: currentPageResolved.value,
        filter: filterResolved.value,
        sortBy: sortByResolved.value,
        perPage: perPageResolved.value,
        signal
      });
      const returnValue = response instanceof Promise ? await response : response;
      if (signal.aborted) return;
      if (returnValue === void 0) return;
      items.value = returnValue;
    } catch (error) {
      if (error instanceof Error && error.name === "AbortError") return;
      throw error;
    } finally {
      if (!signal.aborted) {
        busy.value = false;
      }
    }
  };
  const debouncedCallItemsProvider = useDebounceFn(callItemsProvider, debounce.wait, {
    maxWait: debounce.maxWait
  });
  const providerPropsWatch = async (prop, val, oldVal) => {
    if (deepEqual(val, oldVal)) return;
    const inNoProvider = (key) => toValue(noProvider)?.includes(key) === true;
    const noProvideWhenPaging = (prop === "currentPage" || prop === "perPage") && (inNoProvider("paging") || toValue(noProviderPaging) === true);
    const noProvideWhenFiltering = prop === "filter" && (inNoProvider("filtering") || toValue(noProviderFiltering) === true);
    const noProvideWhenSorting = (prop === "sortBy" || prop === "sortDesc") && (inNoProvider("sorting") || toValue(noProviderSorting) === true);
    if (noProvideWhenPaging || noProvideWhenFiltering || noProvideWhenSorting) return;
    if (usesProvider.value === true) {
      await debouncedCallItemsProvider();
    }
    if (!(prop === "currentPage" || prop === "perPage")) {
      events.onFiltered();
    }
  };
  watch(filterResolved, (filter2, oldFilter) => {
    providerPropsWatch("filter", filter2, oldFilter);
  });
  watch(currentPageResolved, (val, oldVal) => {
    providerPropsWatch("currentPage", val, oldVal);
  });
  watch(perPageResolved, (val, oldVal) => {
    providerPropsWatch("perPage", val, oldVal);
  });
  watch(
    sortByResolved,
    (val, oldVal) => {
      providerPropsWatch("sortBy", val, oldVal);
    },
    { deep: true }
  );
  watch(providerResolved, (newValue) => {
    if (newValue === void 0) {
      items.value = [];
      return;
    }
    callItemsProvider();
  });
  onMounted(callItemsProvider);
  return {
    usesProvider,
    callItemsProvider
  };
};
const useTableSort = ({
  fields,
  sortBy,
  initialSortDirection,
  multisort,
  mustSort,
  events
}) => {
  const isSortable = computed(
    () => sortBy.value !== void 0 || toValue(fields).some(
      (field) => typeof field === "object" && field !== null && field.sortable === true
    )
  );
  const handleFieldSorting = (field) => {
    if (!isSortable.value) return;
    const fieldKey = typeof field === "object" && field !== null ? field.key : field;
    const fieldSortable = typeof field === "object" && field !== null ? field.sortable : false;
    if (!(isSortable.value === true && fieldSortable === true)) return;
    const getLastSortDirection = () => {
      const lastSorted = [...sortBy.value ?? []].reverse().find((sort) => sort.order !== void 0 && sort.key !== fieldKey);
      return lastSorted?.order ?? "asc";
    };
    const getInitialSortDirection = () => {
      if (typeof field === "object" && field !== null && field.initialSortDirection) {
        if (field.initialSortDirection === "last") {
          return getLastSortDirection();
        }
        return field.initialSortDirection;
      }
      const initialSortDirectionValue = toValue(initialSortDirection);
      if (initialSortDirectionValue) {
        if (initialSortDirectionValue === "last") {
          return getLastSortDirection();
        }
        return initialSortDirectionValue;
      }
      return "asc";
    };
    const resolveOrder = (val) => {
      const mustSortValue = toValue(mustSort);
      if (val === void 0) return getInitialSortDirection();
      const initial = getInitialSortDirection();
      const must = mustSortValue === true || !!mustSortValue && mustSortValue.includes(fieldKey);
      if (val === "asc") {
        if (initial === "desc") {
          return must ? "desc" : void 0;
        }
        return "desc";
      }
      if (val === "desc") {
        if (initial === "desc") {
          return "asc";
        }
        return must ? "asc" : void 0;
      }
      return void 0;
    };
    const index = sortBy.value?.findIndex((el) => el.key === fieldKey) ?? -1;
    const originalValue = sortBy.value?.[index];
    const updatedValue = (
      // If value is new, we use the field's initialSortDirection or default to ascending
      // Otherwise we make a temp copy of the value
      index === -1 || !originalValue ? { key: fieldKey, order: getInitialSortDirection() } : { ...originalValue }
    );
    const handleMultiSort = () => {
      const tmp = [...sortBy.value ?? []];
      const val = updatedValue;
      if (index === -1) {
        tmp.push(val);
      } else {
        const order = resolveOrder(val.order);
        if (order) {
          val.order = order;
          tmp.splice(index, 1, val);
        } else {
          val.order = void 0;
          tmp.splice(index, 1);
        }
      }
      sortBy.value = tmp;
      return val;
    };
    const handleSingleSort = () => {
      const order = index === -1 ? updatedValue.order : resolveOrder(updatedValue.order);
      const val = {
        ...updatedValue,
        order
      };
      sortBy.value = order ? [val] : [];
      return val;
    };
    events.onSorted(toValue(multisort) === true ? handleMultiSort() : handleSingleSort());
  };
  return {
    isSortable,
    handleFieldSorting
  };
};
const _hoisted_1 = {
  role: "alert",
  "aria-live": "polite"
};
const _hoisted_2 = { class: "text-center my-2" };
const _sfc_main = /* @__PURE__ */ defineComponent({
  __name: "BTable",
  props: /* @__PURE__ */ mergeModels({
    provider: { type: Function, default: void 0 },
    noProvider: { default: void 0 },
    noProviderPaging: { type: Boolean, default: false },
    noProviderSorting: { type: Boolean, default: false },
    noProviderFiltering: { type: Boolean, default: false },
    sortCompare: { type: Function, default: void 0 },
    mustSort: { type: [Boolean, Array], default: false },
    initialSortDirection: { default: "asc" },
    selectable: { type: Boolean, default: false },
    multisort: { type: Boolean, default: false },
    stickySelect: { type: Boolean, default: false },
    selectHead: { type: [Boolean, String], default: true },
    selectMode: { default: "multi" },
    selectionVariant: { default: "primary" },
    perPage: { default: Number.POSITIVE_INFINITY },
    currentPage: { default: 1 },
    filter: { default: void 0 },
    filterFunction: { type: Function, default: void 0 },
    filterable: { default: void 0 },
    noLocalSorting: { type: Boolean, default: false },
    noSelectOnClick: { type: Boolean, default: false },
    noSortableIcon: { type: Boolean, default: false },
    sortIconLeft: { type: Boolean, default: false },
    emptyFilteredText: { default: "There are no records matching your request" },
    emptyText: { default: "There are no records to show" },
    showEmpty: { type: Boolean, default: false },
    align: { default: void 0 },
    caption: { default: void 0 },
    detailsTdClass: { default: void 0 },
    fieldColumnClass: { type: [Function, String, Object, Array], default: void 0 },
    fields: { default: () => [] },
    footClone: { type: Boolean, default: void 0 },
    footRowVariant: { default: void 0 },
    footVariant: { default: void 0 },
    headRowVariant: { default: void 0 },
    headVariant: { default: void 0 },
    labelStacked: { type: Boolean, default: void 0 },
    modelValue: { default: void 0 },
    expandedItems: {},
    primaryKey: { type: [String, Function], default: void 0 },
    tbodyClass: { default: void 0 },
    tbodyTrAttrs: {},
    tbodyTrClass: { type: [Function, String, Array, Object], default: void 0 },
    tfootClass: { default: void 0 },
    tfootTrClass: { default: void 0 },
    theadClass: { default: void 0 },
    theadTrClass: { default: void 0 },
    bordered: { type: Boolean, default: void 0 },
    borderless: { type: Boolean, default: void 0 },
    borderVariant: { default: void 0 },
    captionTop: { type: Boolean, default: void 0 },
    dark: { type: Boolean, default: void 0 },
    fixed: { type: Boolean, default: void 0 },
    hover: { type: Boolean, default: void 0 },
    id: { default: void 0 },
    noBorderCollapse: { type: Boolean, default: void 0 },
    outlined: { type: Boolean, default: void 0 },
    responsive: { type: [Boolean, String], default: void 0 },
    small: { type: Boolean, default: void 0 },
    stacked: { type: [Boolean, String], default: void 0 },
    stickyHeader: { type: [Boolean, String, Number], default: void 0 },
    striped: { type: Boolean, default: void 0 },
    stripedColumns: { type: Boolean, default: void 0 },
    variant: { default: void 0 },
    tableAttrs: {},
    debounce: { default: 0 },
    debounceMaxWait: { default: Number.NaN }
  }, {
    "sortBy": {
      default: void 0
    },
    "sortByModifiers": {},
    "busy": { type: Boolean, ...{
      default: false
    } },
    "busyModifiers": {},
    "selectedItems": {
      default: () => []
    },
    "selectedItemsModifiers": {},
    "expandedItems": {
      default: () => []
    },
    "expandedItemsModifiers": {},
    "items": {
      default: () => []
    },
    "itemsModifiers": {}
  }),
  emits: /* @__PURE__ */ mergeModels(["filtered", "row-selected", "row-unselected", "sorted", "change", "head-clicked", "row-clicked", "row-dblclicked", "row-contextmenu", "row-hovered", "row-unhovered", "row-middle-clicked"], ["update:sortBy", "update:busy", "update:selectedItems", "update:expandedItems", "update:items"]),
  setup(__props, { expose: __expose, emit: __emit }) {
    const _props = __props;
    const props = useDefaults(_props, "BTable");
    const emit = __emit;
    const slots = useSlots();
    const dynamicCellSlots = computed(
      () => Object.keys(slots).filter((key) => key.startsWith("cell("))
    );
    const dynamicFootSlots = computed(
      () => Object.keys(slots).filter((key) => key.startsWith("foot("))
    );
    const sortByModel = useModel(__props, "sortBy");
    const busyModel = useModel(__props, "busy");
    const selectedItemsModel = useModel(
      __props,
      "selectedItems"
    );
    const expandedItems = useModel(
      __props,
      "expandedItems"
    );
    const itemsModel = useModel(__props, "items");
    const computedId = useId(() => props.id);
    const perPageNumber = useToNumber(() => props.perPage, { method: "parseInt" });
    const currentPageNumber = useToNumber(() => props.currentPage, { method: "parseInt" });
    const debounceNumber = useToNumber(() => props.debounce ?? 0, { nanToZero: true });
    const debounceMaxWaitNumber = useToNumber(() => props.debounceMaxWait ?? Number.NaN);
    const sortController = useTableSort({
      fields: () => props.fields,
      sortBy: sortByModel,
      events: {
        onSorted: (v) => {
          emit("sorted", v);
        }
      },
      initialSortDirection: () => props.initialSortDirection,
      mustSort: () => props.mustSort,
      multisort: () => props.multisort
    });
    const providerController = useTableProvider({
      items: itemsModel,
      events: {
        onFiltered: () => {
          emit("filtered", computedItems.value);
        }
      },
      busy: busyModel,
      provider: toRef(() => props.provider),
      debounce: {
        maxWait: debounceMaxWaitNumber,
        wait: debounceNumber
      },
      currentPage: currentPageNumber,
      perPage: perPageNumber,
      filter: () => props.filter,
      noProvider: () => props.noProvider,
      noProviderFiltering: () => props.noProviderFiltering,
      noProviderPaging: () => props.noProviderPaging,
      noProviderSorting: () => props.noProviderSorting,
      sortBy: sortByModel
    });
    const expandedItemsController = useItemExpansion({
      allItems: itemsModel,
      primaryKey: toRef(() => props.primaryKey),
      expandedItems
    });
    const {
      items: computedItems,
      displayItems: computedDisplayItems,
      getStringValue,
      fields: computedFields,
      isFilterableTable
    } = useTableMapper({
      fields: () => props.fields,
      provider: {
        noProviderFiltering: () => props.noProviderFiltering,
        noProviderPaging: () => props.noProviderPaging,
        noProviderSorting: () => props.noProviderSorting,
        usesProvider: providerController.usesProvider
      },
      events: {
        onChange: (v) => {
          emit("change", v);
        }
      },
      items: itemsModel,
      pagination: {
        perPage: perPageNumber,
        currentPage: currentPageNumber,
        filter: {
          filter: () => props.filter,
          filterFunction: toRef(() => props.filterFunction),
          filterable: () => props.filterable
        },
        sort: {
          iconLeft: () => props.sortIconLeft,
          isSortable: sortController.isSortable,
          noLocalSorting: () => props.noLocalSorting,
          by: sortByModel,
          sortCompare: toRef(() => props.sortCompare)
        }
      },
      stackedProps: {
        stacked: () => props.stacked,
        labelStacked: () => props.labelStacked
      }
    });
    const selectedItemsController = useTableSelectedItems({
      selectable: () => props.selectable,
      primaryKey: toRef(() => props.primaryKey),
      selectedItems: selectedItemsModel,
      allItems: computedItems,
      selectMode: () => props.selectMode,
      events: {
        onRowSelected: (item) => {
          emit("row-selected", item);
        },
        onRowUnselected: (item) => {
          emit("row-unselected", item);
        }
      }
    });
    useTableKeyboardNavigationInjector({
      isSortable: sortController.isSortable,
      selectable: () => props.selectable,
      noSelectOnClick: () => props.noSelectOnClick
    });
    const tableClasses = computed(() => ({
      "b-table-busy": busyModel.value,
      "b-table-selectable": props.selectable,
      "user-select-none": props.selectable && !props.noSelectOnClick && selectedItemsController.isActivated.value,
      "b-table-fixed": props.fixed,
      "b-table-no-border-collapse": props.noBorderCollapse,
      "b-table-no-sort-icon": props.noSortableIcon
    }));
    const getBusyRowClasses = computed(() => [
      props.tbodyTrClass ? typeof props.tbodyTrClass === "function" ? props.tbodyTrClass(null, "table-busy") : props.tbodyTrClass : null
    ]);
    const getFieldColumnClasses = (field) => [
      {
        "b-table-sortable-column": sortController.isSortable.value && field.sortable
      }
    ];
    const getRowClasses = (item, type) => [
      {
        [`selected table-${props.selectionVariant}`]: props.selectable && !!item && selectedItemsController.has(item)
      },
      props.tbodyTrClass ? typeof props.tbodyTrClass === "function" ? props.tbodyTrClass(item, type) : props.tbodyTrClass : null
    ];
    const boundBTableLiteEmits = {
      onHeadClicked: ({ key, field, event, isFooter = false }) => {
        emit("head-clicked", { key, field, event, isFooter });
        sortController.handleFieldSorting(field);
      },
      onRowClicked: ({ item, index, event }) => {
        if (props.noSelectOnClick === false) {
          selectedItemsController.handleRowSelection({
            item,
            index,
            shiftClicked: event.shiftKey,
            ctrlClicked: event.ctrlKey,
            metaClicked: event.metaKey
          });
        }
        emit("row-clicked", { item, index, event });
      },
      onRowDblclicked: (...args) => emit("row-dblclicked", ...args),
      onRowContextmenu: (...args) => emit("row-contextmenu", ...args),
      onRowHovered: (...args) => emit("row-hovered", ...args),
      onRowUnhovered: (...args) => emit("row-unhovered", ...args),
      onRowMiddleClicked: (...args) => emit("row-middle-clicked", ...args)
    };
    const computedLiteProps = computed(() => ({
      ...pick(props, [...bTableLiteProps, ...bTableSimpleProps]),
      tableAttrs: {
        ariaBusy: busyModel.value
      },
      items: computedDisplayItems.value,
      fields: computedFields.value,
      tableClass: tableClasses.value,
      tbodyTrClass: getRowClasses,
      fieldColumnClass: getFieldColumnClasses,
      id: computedId.value,
      ...boundBTableLiteEmits
    }));
    const emptySlotScope = computed(() => ({
      emptyFilteredText: props.emptyFilteredText,
      emptyText: props.emptyText,
      fields: computedFields.value,
      items: computedItems.value
    }));
    const showEmptyFiltered = computed(
      () => isFilterableTable.value && props.filter !== void 0 && props.filter !== ""
    );
    __expose({
      expansion: {
        ...expandedItemsController,
        expandedItems: readonly(expandedItems)
      },
      selection: {
        ...selectedItemsController,
        selectedItems: readonly(selectedItemsModel)
      },
      items: computedItems,
      displayItems: computedDisplayItems,
      getStringValue,
      refresh: providerController.callItemsProvider
    });
    return (_ctx, _cache) => {
      return openBlock(), createBlock(_sfc_main$1, mergeProps(computedLiteProps.value, {
        "expanded-items": expandedItems.value,
        "onUpdate:expandedItems": _cache[0] || (_cache[0] = ($event) => expandedItems.value = $event)
      }), createSlots({
        "custom-body": withCtx((scope) => [
          busyModel.value && slots["table-busy"] ? (openBlock(), createBlock(_sfc_main$2, {
            key: 0,
            class: normalizeClass(["b-table-busy-slot", getBusyRowClasses.value])
          }, {
            default: withCtx(() => [
              createVNode(_sfc_main$6, {
                colspan: scope.fields.length
              }, {
                default: withCtx(() => [
                  renderSlot(_ctx.$slots, "table-busy")
                ]),
                _: 3
              }, 8, ["colspan"])
            ]),
            _: 2
          }, 1032, ["class"])) : !busyModel.value && unref(props).showEmpty === true && unref(computedItems).length === 0 ? (openBlock(), createBlock(_sfc_main$2, {
            key: 1,
            class: "b-table-empty-row"
          }, {
            default: withCtx(() => [
              createVNode(_sfc_main$6, {
                colspan: unref(computedFields).length
              }, {
                default: withCtx(() => [
                  createElementVNode("div", _hoisted_1, [
                    createElementVNode("div", _hoisted_2, [
                      showEmptyFiltered.value ? renderSlot(_ctx.$slots, "empty-filtered", normalizeProps(mergeProps({ key: 0 }, emptySlotScope.value)), () => [
                        createTextVNode(toDisplayString(unref(props).emptyFilteredText), 1)
                      ]) : renderSlot(_ctx.$slots, "empty", normalizeProps(mergeProps({ key: 1 }, emptySlotScope.value)), () => [
                        createTextVNode(toDisplayString(unref(props).emptyText), 1)
                      ])
                    ])
                  ])
                ]),
                _: 3
              }, 8, ["colspan"])
            ]),
            _: 3
          })) : createCommentVNode("", true)
        ]),
        _: 2
      }, [
        slots["table-colgroup"] ? {
          name: "table-colgroup",
          fn: withCtx((scope) => [
            renderSlot(_ctx.$slots, "table-colgroup", normalizeProps(guardReactiveProps(scope)))
          ]),
          key: "0"
        } : void 0,
        slots["thead-top"] ? {
          name: "thead-top",
          fn: withCtx((scope) => [
            renderSlot(_ctx.$slots, "thead-top", mergeProps(scope, {
              clearSelected: unref(selectedItemsController).clear,
              selectAllRows: unref(selectedItemsController).setAll,
              fields: unref(computedFields)
            }))
          ]),
          key: "1"
        } : void 0,
        slots["thead-sub"] ? {
          name: "thead-sub",
          fn: withCtx((scope) => [
            renderSlot(_ctx.$slots, "thead-sub", mergeProps(scope, { fields: unref(computedFields) }))
          ]),
          key: "2"
        } : void 0,
        slots["top-row"] ? {
          name: "top-row",
          fn: withCtx((scope) => [
            renderSlot(_ctx.$slots, "top-row", mergeProps(scope, { fields: unref(computedFields) }))
          ]),
          key: "3"
        } : void 0,
        slots["row-expansion"] ? {
          name: "row-expansion",
          fn: withCtx((scope) => [
            renderSlot(_ctx.$slots, "row-expansion", mergeProps(scope, {
              fields: unref(computedFields),
              selectRow: () => unref(selectedItemsController).add(scope.item),
              unselectRow: () => unref(selectedItemsController).remove(scope.item),
              rowSelected: unref(selectedItemsController).has(scope.item)
            }))
          ]),
          key: "4"
        } : void 0,
        slots["bottom-row"] ? {
          name: "bottom-row",
          fn: withCtx((scope) => [
            renderSlot(_ctx.$slots, "bottom-row", mergeProps(scope, { fields: unref(computedFields) }))
          ]),
          key: "5"
        } : void 0,
        slots["custom-foot"] ? {
          name: "custom-foot",
          fn: withCtx((scope) => [
            renderSlot(_ctx.$slots, "custom-foot", mergeProps(scope, { fields: unref(computedFields) }))
          ]),
          key: "6"
        } : void 0,
        slots["table-caption"] ? {
          name: "table-caption",
          fn: withCtx(() => [
            renderSlot(_ctx.$slots, "table-caption")
          ]),
          key: "7"
        } : void 0,
        renderList(dynamicCellSlots.value, (name) => {
          return {
            name,
            fn: withCtx((scope) => [
              renderSlot(_ctx.$slots, name, mergeProps(scope, {
                selectRow: () => unref(selectedItemsController).add(scope.item),
                unselectRow: () => unref(selectedItemsController).remove(scope.item),
                rowSelected: unref(selectedItemsController).has(scope.item)
              }))
            ])
          };
        }),
        renderList(dynamicFootSlots.value, (name) => {
          return {
            name,
            fn: withCtx((scope) => [
              renderSlot(_ctx.$slots, name, mergeProps(scope, {
                selectAllRows: unref(selectedItemsController).setAll,
                clearSelected: unref(selectedItemsController).clear
              }))
            ])
          };
        }),
        renderList(unref(computedFields), (field) => {
          return {
            name: `head(${String(field.key)})`,
            fn: withCtx((scope) => [
              renderSlot(
                _ctx.$slots,
                slots[`head(${String(field.key)})`] ? `head(${String(field.key)})` : "head()",
                mergeProps(scope, {
                  selectAllRows: unref(selectedItemsController).setAll,
                  clearSelected: unref(selectedItemsController).clear
                }),
                () => [
                  createTextVNode(toDisplayString(unref(getTableFieldHeadLabel)(field)), 1)
                ]
              )
            ])
          };
        })
      ]), 1040, ["expanded-items"]);
    };
  }
});
export {
  _sfc_main as _,
  _sfc_main$1 as a,
  _sfc_main$7 as b,
  _sfc_main$6 as c,
  _sfc_main$5 as d,
  _sfc_main$4 as e,
  _sfc_main$3 as f,
  _sfc_main$2 as g
};
//# sourceMappingURL=BTable.vue_vue_type_script_setup_true_lang-HbUJOeiX.mjs.map
