UNPKG

hy-vue-gantt

Version:

Evolution of vue-ganttastic package

8,570 lines 364 kB
import dayjs from "dayjs";
import isoWeek from "dayjs/plugin/isoWeek";
import isSameOrBefore from "dayjs/plugin/isSameOrBefore.js";
import isSameOrAfter from "dayjs/plugin/isSameOrAfter.js";
import isBetween from "dayjs/plugin/isBetween.js";
import weekOfYear from "dayjs/plugin/weekOfYear";
import advancedFormat from "dayjs/plugin/advancedFormat";
import customParseFormat from "dayjs/plugin/customParseFormat.js";
import dayOfYear from "dayjs/plugin/dayOfYear.js";
import localizedFormat from "dayjs/plugin/localizedFormat";
import utc from "dayjs/plugin/utc";
import { inject, computed, defineComponent, createElementBlock, openBlock, unref, Fragment, renderList, normalizeStyle, normalizeClass, ref, reactive, onMounted, createCommentVNode, createElementVNode, renderSlot, createTextVNode, toDisplayString, createVNode, watch, toRefs, nextTick, createBlock, Teleport, Transition, withCtx, normalizeProps, guardReactiveProps, withDirectives, vModelText, provide, resolveComponent, withModifiers, mergeProps, TransitionGroup, createSlots, useTemplateRef, vModelSelect, useCssVars, useSlots, toRef, onUnmounted, resolveDynamicComponent, isRef, createStaticVNode, h } from "vue";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { faChevronDown, faChevronRight, faSort, faArrowDownAZ, faArrowDownZA, faXmark, faCheck, faFileImport, faSpinner, faExclamationTriangle, faAngleUp, faAngleDown, faExpandAlt, faCompressAlt, faAnglesLeft, faAngleLeft, faAngleRight, faAnglesRight, faMagnifyingGlassMinus, faMagnifyingGlassPlus, faUndo, faRedo, faFileExport } from "@fortawesome/free-solid-svg-icons";
import { useIntervalFn, useMouseInElement, useElementBounding, computedWithControl, watchThrottled, useElementSize } from "@vueuse/core";
import { v4 } from "uuid";
import Holidays from "date-holidays";
import { cloneDeep } from "lodash-es";
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
import * as XLSX from "xlsx";
import "dayjs/locale/it";
import "dayjs/locale/en";
import "dayjs/locale/fr";
import "dayjs/locale/de";
import "dayjs/locale/es";
import "dayjs/locale/pt";
import "dayjs/locale/ru";
import "dayjs/locale/zh-cn";
import "dayjs/locale/zh-tw";
import "dayjs/locale/ja";
import "dayjs/locale/ko";
import "dayjs/locale/nl";
import "dayjs/locale/pl";
import "dayjs/locale/cs";
const CONFIG_KEY = Symbol("CONFIG_KEY");
const BOOLEAN_KEY = Symbol("BOOLEAN_KEY");
const EMIT_BAR_EVENT_KEY = Symbol("EMIT_BAR_EVENT_KEY");
const BAR_CONTAINER_KEY = Symbol("BAR_CONTAINER_KEY");
const CHART_AREA_KEY = Symbol("CHART_AREA_KEY");
const CHART_WRAPPER_KEY = Symbol("CHART_WRAPPER_KEY");
const GANTT_ID_KEY = Symbol("GANTT_ID_KEY");
function provideConfig() {
  const config = inject(CONFIG_KEY);
  if (!config) {
    throw Error("Failed to inject config!");
  }
  return config;
}
const DEFAULT_DATE_FORMAT = "YYYY-MM-DD HH:mm";
function useDayjsHelper(config = provideConfig()) {
  const { chartStart, chartEnd, barStart, barEnd, dateFormat, locale } = config;
  const chartStartDayjs = computed(() => toDayjs(chartStart.value));
  const chartEndDayjs = computed(() => toDayjs(chartEnd.value));
  dayjs.locale(locale.value);
  const toDayjs = (input, startOrEnd) => {
    let value;
    if (startOrEnd !== void 0 && typeof input !== "string" && !(input instanceof Date)) {
      value = startOrEnd === "start" ? input[barStart.value] : input[barEnd.value];
    }
    if (typeof input === "string") {
      value = input;
    } else if (input instanceof Date) {
      return dayjs(input);
    }
    const format2 = dateFormat.value || DEFAULT_DATE_FORMAT;
    return dayjs(value, format2, false);
  };
  const format = (input, pattern) => {
    if (pattern === false) {
      return input instanceof Date ? input : dayjs(input).toDate();
    }
    const inputDayjs = typeof input === "string" || input instanceof Date ? toDayjs(input) : input;
    return inputDayjs.format(pattern);
  };
  const diffDates = () => {
    return chartEndDayjs.value.diff(chartStartDayjs.value, "day");
  };
  return {
    chartStartDayjs,
    chartEndDayjs,
    toDayjs,
    format,
    diffDates
  };
}
const _hoisted_1$a = {
  class: "g-grid-container",
  ref: "time"
};
const _sfc_main$b = /* @__PURE__ */ defineComponent({
  __name: "GGanttGrid",
  props: {
    timeaxisUnits: {},
    internalPrecision: {}
  },
  setup(__props) {
    const props = __props;
    const { toDayjs } = useDayjsHelper();
    const {
      colors,
      highlightedHours,
      highlightedDaysInWeek,
      highlightedDaysInMonth,
      highlightedMonths,
      highlightedWeek,
      enableMinutes
    } = provideConfig();
    const highlightLine = (date) => {
      if (props.internalPrecision === "hour") {
        return isHighlightedHour(date) || isHighlightedDay(date) || isHighlightedMonth(date) || isHighlightedWeek(date);
      }
      if (props.internalPrecision === "day" || props.internalPrecision === "date") {
        return isHighlightedDay(date) || isHighlightedMonth(date) || isHighlightedWeek(date);
      }
      if (props.internalPrecision === "week") {
        return isHighlightedWeek(date) || isHighlightedMonth(date);
      }
      if (props.internalPrecision === "month") {
        return isHighlightedMonth(date);
      }
      return false;
    };
    const isHighlightedHour = (date) => highlightedHours == null ? void 0 : highlightedHours.value.includes(date.getHours());
    const isHighlightedDay = (date) => {
      return (highlightedDaysInWeek == null ? void 0 : highlightedDaysInWeek.value.includes(date.getDay())) || (highlightedDaysInMonth == null ? void 0 : highlightedDaysInMonth.value.includes(date.getDate()));
    };
    const isHighlightedWeek = (date) => highlightedWeek == null ? void 0 : highlightedWeek.value.includes(toDayjs(date).week());
    const isHighlightedMonth = (date) => highlightedMonths == null ? void 0 : highlightedMonths.value.includes(date.getMonth());
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", _hoisted_1$a, [
        !unref(enableMinutes) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(_ctx.timeaxisUnits.result.lowerUnits, ({ label, date, width }, index) => {
          return openBlock(), createElementBlock("div", {
            key: `${label}_${index}`,
            class: "g-grid-line",
            style: normalizeStyle({
              width,
              borderLeft: `1px solid ${unref(colors).gridAndBorder}`,
              background: highlightLine(date) ? unref(colors).hoverHighlight : void 0
            })
          }, null, 4);
        }), 128)) : (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(_ctx.timeaxisUnits.result.lowerUnits, ({ label, date, width }, index) => {
          return openBlock(), createElementBlock(Fragment, {
            key: `${label}_${index}`
          }, [
            (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.timeaxisUnits.globalMinuteStep, (step) => {
              return openBlock(), createElementBlock("div", {
                key: `${date}-${step}`,
                class: normalizeClass([step, "g-grid-line step"]),
                style: normalizeStyle({
                  width,
                  borderLeft: `1px solid ${unref(colors).gridAndBorder}`,
                  background: highlightLine(date) ? unref(colors).hoverHighlight : void 0
                })
              }, null, 6);
            }), 128))
          ], 64);
        }), 128))
      ], 512);
    };
  }
});
function useRowDragAndDrop(rows, isSorted, updateRows, emit) {
  const dragState = ref({
    isDragging: false,
    draggedRow: null,
    dropTarget: {
      row: null,
      position: "before"
    }
  });
  const originalOrder = ref(/* @__PURE__ */ new Map());
  const isValidDrop = (source, target) => {
    const isParentOfTarget = (row) => {
      var _a;
      if (!((_a = row.children) == null ? void 0 : _a.length)) return false;
      return row.children.some((child) => child === target || isParentOfTarget(child));
    };
    return !isParentOfTarget(source);
  };
  const handleDragStart = (row, event) => {
    if (isSorted.value) return;
    dragState.value.isDragging = true;
    dragState.value.draggedRow = row;
    if (event.dataTransfer) {
      event.dataTransfer.effectAllowed = "move";
      event.dataTransfer.setData("text/plain", "");
    }
    if (originalOrder.value.size === 0) {
      rows.value.forEach((row2, index) => {
        if (row2.id) {
          originalOrder.value.set(row2.id, index);
        }
      });
    }
  };
  const handleDragOver = (row, event) => {
    var _a;
    if (!dragState.value.draggedRow || !isValidDrop(dragState.value.draggedRow, row)) {
      return;
    }
    event.preventDefault();
    const rect = event.currentTarget.getBoundingClientRect();
    const mouseY = event.clientY - rect.top;
    if ((_a = row.children) == null ? void 0 : _a.length) {
      if (mouseY < rect.height * 0.25) {
        dragState.value.dropTarget = { row, position: "before" };
      } else if (mouseY > rect.height * 0.75) {
        dragState.value.dropTarget = { row, position: "after" };
      } else {
        dragState.value.dropTarget = { row, position: "child" };
      }
    } else {
      dragState.value.dropTarget = {
        row,
        position: mouseY < rect.height / 2 ? "before" : "after"
      };
    }
  };
  const isDescendant = (parent, potentialChild) => {
    if (!parent.children) {
      return false;
    }
    return parent.children.some(
      (child) => child.id === potentialChild.id || isDescendant(child, potentialChild)
    );
  };
  const findRowIndexById = (rows2, id) => {
    var _a;
    for (let i = 0; i < rows2.length; i++) {
      if (rows2[i].id === id) {
        return [i, rows2];
      }
      if ((_a = rows2[i].children) == null ? void 0 : _a.length) {
        const [index, parentRows] = findRowIndexById(rows2[i].children, id);
        if (index !== -1) {
          return [index, parentRows];
        }
      }
    }
    return [-1, rows2];
  };
  const handleDrop = () => {
    const { draggedRow, dropTarget } = dragState.value;
    if (!draggedRow || !dropTarget.row || isSorted.value || draggedRow === dropTarget.row) {
      return;
    }
    if (isDescendant(draggedRow, dropTarget.row)) {
      return;
    }
    const [sourceIndex, sourceParentRows] = findRowIndexById(rows.value, draggedRow.id);
    const [targetIndex, targetParentRows] = findRowIndexById(rows.value, dropTarget.row.id);
    if (sourceIndex === -1 || targetIndex === -1) {
      return;
    }
    const [removed] = sourceParentRows.splice(sourceIndex, 1);
    const insertIndex = dropTarget.position === "after" ? targetIndex + 1 : targetIndex;
    targetParentRows.splice(insertIndex, 0, removed);
    updateRows([...rows.value]);
    emit("row-drop", {
      sourceRow: draggedRow,
      targetRow: dropTarget.row,
      newIndex: insertIndex,
      parentId: targetParentRows === rows.value ? void 0 : dropTarget.row.id
    });
    dragState.value = {
      isDragging: false,
      draggedRow: null,
      dropTarget: { row: null, position: "before" }
    };
  };
  const resetOrder = () => {
    if (originalOrder.value.size === 0) return;
    rows.value.sort((a, b) => {
      const aIndex = a.id ? originalOrder.value.get(a.id) ?? 0 : 0;
      const bIndex = b.id ? originalOrder.value.get(b.id) ?? 0 : 0;
      return aIndex - bIndex;
    });
  };
  return {
    dragState,
    handleDragStart,
    handleDragOver,
    handleDrop,
    resetOrder,
    isDescendant,
    findRowIndexById
  };
}
function useColumnTouchResize() {
  const touchState = ref({
    isResizing: false,
    startX: 0,
    currentColumn: null,
    initialWidth: 0
  });
  const resetTouchState = () => {
    touchState.value = {
      isResizing: false,
      startX: 0,
      currentColumn: null,
      initialWidth: 0
    };
  };
  const handleTouchStart = (e, column, currentWidth) => {
    const touch = e.touches[0];
    if (!touch) return;
    e.preventDefault();
    touchState.value = {
      isResizing: true,
      startX: touch.clientX,
      currentColumn: column,
      initialWidth: currentWidth
    };
  };
  const handleTouchMove = (e, onResize) => {
    const touch = e.touches[0];
    if (!touch || !touchState.value.isResizing) return;
    e.preventDefault();
    const deltaX = touch.clientX - touchState.value.startX;
    const newWidth = Math.max(50, touchState.value.initialWidth + deltaX);
    if (touchState.value.currentColumn) {
      onResize(touchState.value.currentColumn, newWidth);
    }
  };
  const handleTouchEnd = () => {
    if (touchState.value.isResizing) {
      resetTouchState();
    }
  };
  const handleTouchCancel = handleTouchEnd;
  return {
    touchState,
    handleTouchStart,
    handleTouchMove,
    handleTouchEnd,
    handleTouchCancel
  };
}
function useRowTouchDrag() {
  const touchState = ref({
    isDragging: false,
    startY: 0,
    currentY: 0,
    draggedRow: null,
    dropTarget: {
      row: null,
      position: "before"
    },
    dragElement: null,
    initialTransform: ""
  });
  const resetTouchState = () => {
    if (touchState.value.dragElement) {
      touchState.value.dragElement.style.transform = touchState.value.initialTransform;
    }
    touchState.value = {
      isDragging: false,
      startY: 0,
      currentY: 0,
      draggedRow: null,
      dropTarget: {
        row: null,
        position: "before"
      },
      dragElement: null,
      initialTransform: ""
    };
  };
  const handleTouchStart = (event, row, element) => {
    const touch = event.touches[0];
    if (!touch) return;
    setTimeout(() => {
      if (touchState.value.isDragging) {
        event.preventDefault();
      }
    }, 100);
    touchState.value = {
      isDragging: true,
      startY: touch.clientY,
      currentY: touch.clientY,
      draggedRow: row,
      dropTarget: {
        row: null,
        position: "before"
      },
      dragElement: element,
      initialTransform: element.style.transform || ""
    };
  };
  const handleTouchMove = (event, targetRow, rowElement) => {
    var _a;
    const touch = event.touches[0];
    if (!touch || !touchState.value.isDragging || !touchState.value.dragElement) return;
    event.preventDefault();
    touchState.value.currentY = touch.clientY;
    const deltaY = touch.clientY - touchState.value.startY;
    touchState.value.dragElement.style.transform = `translateY(${deltaY}px)`;
    const rect = rowElement.getBoundingClientRect();
    const relativeY = touch.clientY - rect.top;
    const position = relativeY / rect.height;
    if (touchState.value.draggedRow !== targetRow) {
      if ((_a = targetRow.children) == null ? void 0 : _a.length) {
        if (position < 0.25) {
          touchState.value.dropTarget = { row: targetRow, position: "before" };
        } else if (position > 0.75) {
          touchState.value.dropTarget = { row: targetRow, position: "after" };
        } else {
          touchState.value.dropTarget = { row: targetRow, position: "child" };
        }
      } else {
        touchState.value.dropTarget = {
          row: targetRow,
          position: position < 0.5 ? "before" : "after"
        };
      }
    }
  };
  const handleTouchEnd = (event) => {
    if (!touchState.value.isDragging) return null;
    const touch = event.changedTouches[0];
    if (!touch) return null;
    const result = {
      sourceRow: touchState.value.draggedRow,
      dropTarget: touchState.value.dropTarget,
      dropPosition: touchState.value.dropTarget.position
    };
    resetTouchState();
    return result;
  };
  return {
    touchState,
    handleTouchStart,
    handleTouchMove,
    handleTouchEnd,
    resetTouchState
  };
}
const _hoisted_1$9 = ["onClick"];
const _hoisted_2$7 = { class: "text-ellipsis" };
const _hoisted_3$7 = {
  key: 0,
  class: "sort-icon"
};
const _hoisted_4$6 = ["onMousedown", "onTouchstart"];
const _hoisted_5$6 = ["data-row-id", "draggable", "onDragstart", "onDragover", "onTouchstart", "onTouchmove"];
const _hoisted_6$5 = { class: "g-label-column-row-inner" };
const _hoisted_7$5 = ["onClick"];
const _hoisted_8$5 = { class: "text-ellipsis-value" };
const LONG_PRESS_DURATION = 500;
const INDENT_WIDTH = 24;
const _sfc_main$a = /* @__PURE__ */ defineComponent({
  __name: "GGanttLabelColumn",
  emits: ["scroll", "row-drop"],
  setup(__props, { expose: __expose, emit: __emit }) {
    const emit = __emit;
    const rowManager = inject("useRows");
    if (!rowManager) {
      throw new Error("useRows does not provide ");
    }
    const { rows, sortState, toggleSort } = rowManager;
    const {
      font,
      colors,
      labelColumnTitle,
      labelColumnWidth,
      rowHeight,
      maxRows,
      multiColumnLabel,
      precision,
      barStart,
      barEnd,
      dateFormat,
      rowLabelClass,
      labelResizable,
      enableRowDragAndDrop,
      hideTimeaxis,
      sortable,
      showEventsAxis,
      eventsAxisHeight
    } = provideConfig();
    const { toDayjs, format } = useDayjsHelper();
    const columnWidths = reactive(/* @__PURE__ */ new Map());
    const isDragging = ref(false);
    const dragStartX = ref(0);
    const draggedColumn = ref(null);
    const labelContainer = ref(null);
    const {
      dragState,
      handleDragStart: handleRowDragStart,
      handleDragOver,
      handleDrop
    } = useRowDragAndDrop(
      rows,
      computed(() => sortState.value.direction !== "none"),
      rowManager.updateRows,
      (_event, payload) => emit("row-drop", payload)
    );
    const { touchState, handleTouchStart, handleTouchMove, handleTouchEnd, handleTouchCancel } = useColumnTouchResize();
    const {
      touchState: rowTouchState,
      handleTouchStart: handleRowTouchStart,
      handleTouchMove: handleRowTouchMove,
      handleTouchEnd: handleRowTouchEnd,
      resetTouchState: resetRowTouchState
    } = useRowTouchDrag();
    const columns = computed(() => {
      var _a;
      if (!((_a = multiColumnLabel.value) == null ? void 0 : _a.length) || !labelColumnTitle.value) {
        return [{ field: "Label", sortable: sortable.value }];
      }
      const filteredColumns = multiColumnLabel.value.filter((col) => col.field !== "Label");
      const labelColumn = { field: "Label", sortable: sortable.value };
      return [labelColumn, ...filteredColumns];
    });
    const totalWidth = computed(() => {
      let total = 0;
      columnWidths.forEach((width) => total += width);
      return total;
    });
    const getProcessedRows = computed(() => {
      const processRows = (rows2, level = 0) => {
        return rows2.flatMap((row) => {
          var _a;
          const processedRow = {
            ...row,
            indentLevel: level
          };
          const isExpanded = row.id ? rowManager.isGroupExpanded(row.id) : false;
          if (((_a = row.children) == null ? void 0 : _a.length) && isExpanded) {
            return [processedRow, ...processRows(row.children, level + 1)];
          }
          return [processedRow];
        });
      };
      return processRows(rows.value);
    });
    const labelContainerStyle = computed(() => {
      if (maxRows.value === 0) return {};
      const minRows = Math.min(maxRows.value, getProcessedRows.value.length);
      return {
        height: `${minRows * rowHeight.value}px`,
        "overflow-y": "auto"
      };
    });
    const columnSortableStates = computed(
      () => columns.value.reduce(
        (acc, column) => {
          acc[column.field] = !!(column.sortable !== false && (sortable.value || !sortable.value && column.sortable) && (isValidColumn(column.field) || column.sortFn));
          return acc;
        },
        {}
      )
    );
    const headerHeight = computed(() => {
      if (hideTimeaxis.value) return 0;
      return showEventsAxis.value ? 80 + (eventsAxisHeight.value || 25) : 80;
    });
    let touchStartTime = 0;
    const onRowTouchStart = (e, row) => {
      if (!enableRowDragAndDrop.value || sortState.value.direction !== "none") return;
      touchStartTime = Date.now();
      const element = e.currentTarget;
      handleRowTouchStart(e, row, element);
    };
    const onRowTouchMove = (e, targetRow) => {
      if (!enableRowDragAndDrop.value || sortState.value.direction !== "none") return;
      if (Date.now() - touchStartTime < LONG_PRESS_DURATION) {
        resetRowTouchState();
        return;
      }
      const rowElement = e.currentTarget;
      handleRowTouchMove(e, targetRow, rowElement);
    };
    const onRowTouchEnd = (e) => {
      if (!enableRowDragAndDrop.value || sortState.value.direction !== "none") return;
      if (Date.now() - touchStartTime < LONG_PRESS_DURATION) {
        const target = e.target;
        const button = target.closest(".group-toggle-button");
        if (button) {
          const rowElement = target.closest("[data-row-id]");
          if (rowElement) {
            const rowId = rowElement.dataset.rowId;
            if (rowId) {
              rowManager.toggleGroupExpansion(rowId);
            }
          }
        }
        resetRowTouchState();
        return;
      }
      const result = handleRowTouchEnd(e);
      if (result && result.sourceRow && result.dropTarget.row) {
        let newIndex = getProcessedRows.value.findIndex((r) => r === result.dropTarget.row);
        if (result.dropTarget.position === "after") {
          newIndex += 1;
        }
        const sourceIndex = getProcessedRows.value.findIndex((r) => r === result.sourceRow);
        if (sourceIndex < newIndex) {
          newIndex -= 1;
        }
        const payload = {
          sourceRow: result.sourceRow,
          targetRow: result.dropTarget.row,
          newIndex,
          parentId: result.dropTarget.position === "child" ? result.dropTarget.row.id : void 0
        };
        const newRows = [...getProcessedRows.value];
        newRows.splice(sourceIndex, 1);
        newRows.splice(newIndex, 0, result.sourceRow);
        rowManager.updateRows(newRows);
        emit("row-drop", payload);
      }
    };
    const handleColumnTouchStart = (e, column) => {
      if (!labelResizable) return;
      const currentWidth = columnWidths.get(column) || labelColumnWidth.value;
      handleTouchStart(e, column, currentWidth);
    };
    const handleColumnTouchMove = (e) => {
      if (!labelResizable) return;
      handleTouchMove(e, (column, newWidth) => {
        columnWidths.set(column, newWidth);
      });
    };
    const initializeColumnWidths = () => {
      columns.value.forEach((column) => {
        if (!columnWidths.has(column.field)) {
          columnWidths.set(column.field, labelColumnWidth.value);
        }
      });
    };
    const isValidColumn = (field) => {
      return ["Id", "Label", "StartDate", "EndDate", "Duration", "Progress"].includes(field);
    };
    const getSortIcon = (field) => {
      if (field !== sortState.value.column || sortState.value.direction === "none") {
        return faSort;
      }
      return sortState.value.direction === "asc" ? faArrowDownAZ : faArrowDownZA;
    };
    const getVisibleColumns = (row) => {
      if (row.children && row.children.length > 0) {
        return [{ field: "Label", sortable: sortable.value }];
      }
      return columns.value;
    };
    const rowClasses = (row) => {
      var _a;
      const classes = ["g-label-column-row"];
      if (rowLabelClass.value) {
        classes.push(rowLabelClass.value(row));
      }
      if ((_a = row.children) == null ? void 0 : _a.length) {
        classes.push("g-label-column-group");
      }
      return classes;
    };
    const getDragClasses = (row) => {
      if (!enableRowDragAndDrop.value) return {};
      const isTarget = dragState.value.dropTarget.row === row;
      const isDragged = dragState.value.draggedRow === row;
      return {
        "g-label-column-row-draggable": true,
        "g-label-column-row-dragging": isDragged,
        "g-label-column-row-drop-target": isTarget,
        [`g-label-column-row-drop-${dragState.value.dropTarget.position}`]: isTarget
      };
    };
    const getRowStyle = (row, isLabelColumn) => {
      var _a;
      if (!isLabelColumn) {
        return {
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          width: "100%"
        };
      }
      const style = {
        display: "flex",
        alignItems: "center",
        width: "100%",
        position: "relative"
      };
      if (!((_a = row.children) == null ? void 0 : _a.length) && !row.indentLevel) {
        style.paddingLeft = `${INDENT_WIDTH}px`;
      } else if (row.indentLevel) {
        style.paddingLeft = `${row.indentLevel * INDENT_WIDTH}px`;
      }
      return style;
    };
    const getCellStyle = (isLabelColumn) => {
      const style = {
        display: "flex",
        alignItems: "center",
        width: "100%"
      };
      if (!isLabelColumn) {
        style.justifyContent = "center";
        style.paddingLeft = "0";
      }
      return style;
    };
    const getColumnStyle = (column, isGroup) => {
      if (isGroup && column === "Label") {
        return {
          width: "100%",
          minWidth: "100%",
          maxWidth: "100%",
          position: "relative",
          flexShrink: 0,
          flexGrow: 0
        };
      }
      return {
        width: `${columnWidths.get(column) || labelColumnWidth.value}px`,
        minWidth: `${columnWidths.get(column) || labelColumnWidth.value}px`,
        maxWidth: `${columnWidths.get(column) || labelColumnWidth.value}px`,
        position: "relative",
        flexShrink: 0,
        flexGrow: 0
      };
    };
    const getRowValue = (row, column, index) => {
      if (column.valueGetter) {
        return column.valueGetter(row);
      }
      switch (column.field) {
        case "Id":
          return row.id ?? index + 1;
        case "Label":
          return row.label;
        case "StartDate": {
          if (!row.bars.length) return "-";
          const minDate = row.bars.reduce((min, bar) => {
            const currentStart = bar[barStart.value];
            return !min || toDayjs(currentStart).isBefore(toDayjs(min)) ? currentStart : min;
          }, "");
          return format(minDate, dateFormat.value);
        }
        case "EndDate": {
          if (!row.bars.length) return "-";
          const maxDate = row.bars.reduce((max, bar) => {
            const currentEnd = bar[barEnd.value];
            return !max || toDayjs(currentEnd).isAfter(toDayjs(max)) ? currentEnd : max;
          }, "");
          return format(maxDate, dateFormat.value);
        }
        case "Duration": {
          if (!row.bars.length) return "-";
          const minStart = row.bars.reduce((min, bar) => {
            const currentStart = bar[barStart.value];
            return !min || toDayjs(currentStart).isBefore(toDayjs(min)) ? currentStart : min;
          }, "");
          const maxEnd = row.bars.reduce((max, bar) => {
            const currentEnd = bar[barEnd.value];
            return !max || toDayjs(currentEnd).isAfter(toDayjs(max)) ? currentEnd : max;
          }, "");
          return calculateDuration(minStart, maxEnd);
        }
        case "Progress": {
          if (!row.bars.length) return "-";
          const progressValues = row.bars.map((bar) => bar.ganttBarConfig.progress).filter((progress) => progress !== void 0);
          if (progressValues.length === 0) return "-";
          const averageProgress = progressValues.reduce((sum, curr) => sum + curr, 0) / progressValues.length;
          return `${Math.round(averageProgress)}%`;
        }
        default:
          return "";
      }
    };
    const calculateDuration = (startDate, endDate) => {
      const start = toDayjs(startDate);
      const end = toDayjs(endDate);
      switch (precision.value) {
        case "hour":
          return `${end.diff(start, "hour")}h`;
        case "day":
        case "date":
          return `${end.diff(start, "day")}d`;
        case "week":
          return `${end.diff(start, "week")}w`;
        case "month":
          return `${end.diff(start, "month")}m`;
        default:
          return `${end.diff(start, "day")}d`;
      }
    };
    const handleLabelScroll = (e) => {
      const target = e.target;
      emit("scroll", target.scrollTop);
    };
    const handleGroupToggle = (row, event) => {
      event.stopPropagation();
      if (row.id) {
        rowManager.toggleGroupExpansion(row.id);
      }
    };
    const handleDragStart = (e, column) => {
      isDragging.value = true;
      dragStartX.value = e.clientX;
      draggedColumn.value = column;
      document.addEventListener("mousemove", handleDrag);
      document.addEventListener("mouseup", handleDragEnd);
    };
    const handleDrag = (e) => {
      if (!isDragging.value || !draggedColumn.value) return;
      const deltaX = e.clientX - dragStartX.value;
      const currentWidth = columnWidths.get(draggedColumn.value) || labelColumnWidth.value;
      const newWidth = Math.max(50, currentWidth + deltaX);
      columnWidths.set(draggedColumn.value, newWidth);
      dragStartX.value = e.clientX;
    };
    const handleDragEnd = () => {
      isDragging.value = false;
      draggedColumn.value = null;
      document.removeEventListener("mousemove", handleDrag);
      document.removeEventListener("mouseup", handleDragEnd);
    };
    onMounted(() => {
      initializeColumnWidths();
    });
    __expose({
      setScroll: (value) => {
        if (labelContainer.value) {
          labelContainer.value.scrollTop = value;
        }
      }
    });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        class: "g-label-column",
        style: normalizeStyle({
          fontFamily: unref(font),
          color: unref(colors).text,
          minWidth: `100%`,
          flex: `0 0 ${totalWidth.value}px`,
          borderRight: `1px solid ${unref(colors).gridAndBorder}`
        })
      }, [
        !unref(hideTimeaxis) ? (openBlock(), createElementBlock("div", {
          key: 0,
          class: "g-label-column-header",
          style: normalizeStyle({
            background: unref(colors).primary,
            borderBottom: `1px solid ${unref(colors).gridAndBorder}`,
            height: `${headerHeight.value}px`,
            minHeight: `${headerHeight.value}px`
          })
        }, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(columns.value, (column) => {
            return openBlock(), createElementBlock(Fragment, { key: column }, [
              isValidColumn(column.field) || column.valueGetter ? (openBlock(), createElementBlock("div", {
                key: 0,
                class: normalizeClass(["g-label-column-header-cell", { sortable: columnSortableStates.value[column.field] }]),
                role: "columnheader",
                style: normalizeStyle(getColumnStyle(column.field, false))
              }, [
                createElementVNode("div", {
                  class: "header-content",
                  onClick: ($event) => columnSortableStates.value[column.field] ? unref(toggleSort)(column.field) : void 0
                }, [
                  createElementVNode("span", _hoisted_2$7, [
                    renderSlot(_ctx.$slots, `label-column-title-${column.field.toLowerCase()}`, {}, () => [
                      createTextVNode(toDisplayString(column.field), 1)
                    ])
                  ]),
                  columnSortableStates.value[column.field] ? (openBlock(), createElementBlock("span", _hoisted_3$7, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: getSortIcon(column.field)
                    }, null, 8, ["icon"])
                  ])) : createCommentVNode("", true)
                ], 8, _hoisted_1$9),
                unref(labelResizable) ? (openBlock(), createElementBlock("div", {
                  key: 0,
                  class: normalizeClass(["column-resizer", {
                    "is-dragging": isDragging.value && draggedColumn.value === column.field,
                    "is-touch-resizing": unref(touchState).isResizing && unref(touchState).currentColumn === column.field
                  }]),
                  onMousedown: (e) => handleDragStart(e, column.field),
                  onTouchstart: (e) => handleColumnTouchStart(e, column.field),
                  onTouchmove: handleColumnTouchMove,
                  onTouchend: _cache[0] || (_cache[0] = //@ts-ignore
                  (...args) => unref(handleTouchEnd) && unref(handleTouchEnd)(...args)),
                  onTouchcancel: _cache[1] || (_cache[1] = //@ts-ignore
                  (...args) => unref(handleTouchCancel) && unref(handleTouchCancel)(...args))
                }, null, 42, _hoisted_4$6)) : createCommentVNode("", true)
              ], 6)) : createCommentVNode("", true)
            ], 64);
          }), 128))
        ], 4)) : createCommentVNode("", true),
        createElementVNode("div", {
          class: "g-label-column-rows",
          style: normalizeStyle(labelContainerStyle.value),
          ref_key: "labelContainer",
          ref: labelContainer,
          onScroll: handleLabelScroll
        }, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(getProcessedRows.value, (row, index) => {
            var _a;
            return openBlock(), createElementBlock("div", {
              key: `${row.id || row.label}_${index}`,
              "data-row-id": row.id,
              style: normalizeStyle({
                background: ((_a = row.children) == null ? void 0 : _a.length) ? unref(colors).rowContainer : index % 2 === 0 ? unref(colors).ternary : unref(colors).quartenary,
                height: `${unref(rowHeight)}px`,
                borderBottom: `1px solid ${unref(colors).gridAndBorder}`,
                transform: unref(rowTouchState).draggedRow === row ? `translateY(${unref(rowTouchState).currentY - unref(rowTouchState).startY}px)` : void 0,
                zIndex: unref(rowTouchState).draggedRow === row ? 1e3 : void 0
              }),
              class: normalizeClass([
                rowClasses(row),
                getDragClasses(row),
                {
                  "is-touch-dragging": unref(rowTouchState).draggedRow === row,
                  "is-touch-drop-target": unref(rowTouchState).dropTarget.row === row,
                  [`is-touch-drop-${unref(rowTouchState).dropTarget.position}`]: unref(rowTouchState).dropTarget.row === row
                }
              ]),
              draggable: unref(enableRowDragAndDrop),
              onDragstart: ($event) => unref(handleRowDragStart)(row, $event),
              onDragover: ($event) => unref(handleDragOver)(row, $event),
              onDrop: _cache[2] || (_cache[2] = ($event) => unref(handleDrop)()),
              onTouchstart: (e) => onRowTouchStart(e, row),
              onTouchmove: (e) => onRowTouchMove(e, row),
              onTouchend: onRowTouchEnd,
              onTouchcancel: _cache[3] || (_cache[3] = //@ts-ignore
              (...args) => unref(resetRowTouchState) && unref(resetRowTouchState)(...args))
            }, [
              createElementVNode("div", _hoisted_6$5, [
                (openBlock(true), createElementBlock(Fragment, null, renderList(getVisibleColumns(row), (column) => {
                  var _a2, _b;
                  return openBlock(), createElementBlock(Fragment, {
                    key: column.field
                  }, [
                    isValidColumn(column.field) || column.valueGetter ? (openBlock(), createElementBlock("div", {
                      key: 0,
                      class: "g-label-column-cell",
                      style: normalizeStyle(getColumnStyle(column.field, Boolean((_a2 = row.children) == null ? void 0 : _a2.length)))
                    }, [
                      createElementVNode("div", {
                        style: normalizeStyle(getCellStyle(column.field === "Label"))
                      }, [
                        createElementVNode("div", {
                          style: normalizeStyle(getRowStyle(row, column.field === "Label")),
                          class: "cell-content"
                        }, [
                          column.field === "Label" && row.children && row.children.length > 0 ? (openBlock(), createElementBlock("button", {
                            key: 0,
                            class: "group-toggle-button",
                            onClick: ($event) => handleGroupToggle(row, $event)
                          }, [
                            createVNode(unref(FontAwesomeIcon), {
                              icon: row.id && unref(rowManager).isGroupExpanded(row.id) ? unref(faChevronDown) : unref(faChevronRight),
                              class: "group-icon"
                            }, null, 8, ["icon"])
                          ], 8, _hoisted_7$5)) : createCommentVNode("", true),
                          createElementVNode("span", _hoisted_8$5, [
                            ((_b = row.children) == null ? void 0 : _b.length) ? renderSlot(_ctx.$slots, `label-column-${column.field.toLowerCase()}-group`, {
                              key: 0,
                              row,
                              value: getRowValue(row, column, index)
                            }, () => [
                              renderSlot(_ctx.$slots, `label-column-${column.field.toLowerCase()}`, {
                                row,
                                value: getRowValue(row, column, index)
                              }, () => [
                                createTextVNode(toDisplayString(getRowValue(row, column, index)), 1)
                              ])
                            ]) : renderSlot(_ctx.$slots, `label-column-${column.field.toLowerCase()}`, {
                              key: 1,
                              row,
                              value: getRowValue(row, column, index)
                            }, () => [
                              createTextVNode(toDisplayString(getRowValue(row, column, index)), 1)
                            ])
                          ])
                        ], 4)
                      ], 4)
                    ], 4)) : createCommentVNode("", true)
                  ], 64);
                }), 128))
              ])
            ], 46, _hoisted_5$6);
          }), 128))
        ], 36)
      ], 4);
    };
  }
});
function useHolidays(config) {
  const { chartStartDayjs, chartEndDayjs } = useDayjsHelper(config);
  const holidays = ref([]);
  const hd = new Holidays();
  const loadHolidays = (country) => {
    hd.init(country);
    const start = chartStartDayjs.value.toDate();
    const end = chartEndDayjs.value.toDate();
    const holidaysListStart = hd.getHolidays(start);
    const holidaysListEnd = hd.getHolidays(end);
    const startHolidays = holidaysListStart.map((h2) => ({
      date: new Date(h2.date),
      name: h2.name,
      type: h2.type
    }));
    const endHolidays = holidaysListEnd.map((h2) => ({
      date: new Date(h2.date),
      name: h2.name,
      type: h2.type
    }));
    holidays.value = [...startHolidays, ...endHolidays];
  };
  const getHolidayInfo = (date) => {
    const holiday = holidays.value.find((h2) => h2.date.toDateString() === date.toDateString());
    if (!holiday) return null;
    return {
      isHoliday: true,
      holidayName: holiday.name,
      holidayType: holiday.type
    };
  };
  watch(
    () => {
      var _a;
      return (_a = config.holidayHighlight.value) == null ? void 0 : _a.toUpperCase();
    },
    (newCountry) => {
      if (newCountry) {
        loadHolidays(newCountry);
      } else {
        holidays.value = [];
      }
    },
    { immediate: true }
  );
  return {
    holidays,
    getHolidayInfo
  };
}
const ganttWidth = ref();
const MAX_ZOOM = 10;
const MIN_ZOOM = 1;
const CACHE_TTL = 5 * 60 * 1e3;
const capitalizeString = (str) => {
  if (!str) return str;
  return str.normalize("NFD").replace(new RegExp("^\\p{L}", "u"), (letter) => letter.toLocaleUpperCase());
};
const capitalizeWords = (str) => {
  return str.split(/(\s+|\.|\,)/).map((word) => {
    if (new RegExp("^\\p{L}", "u").test(word)) {
      return capitalizeString(word);
    }
    return word;
  }).join("");
};
function useTimeaxisUnits(config = provideConfig()) {
  const { getHolidayInfo } = useHolidays(config);
  const {
    precision: configPrecision,
    holidayHighlight,
    locale,
    timeaxisEvents,
    baseUnitWidth,
    defaultZoom
  } = config;
  const internalPrecision = ref(configPrecision.value);
  const zoomLevel = ref(defaultZoom.value);
  const processedTimeaxisEvents = ref([]);
  const cache = {
    lower: /* @__PURE__ */ new Map(),
    upper: /* @__PURE__ */ new Map(),
    events: /* @__PURE__ */ new Map()
  };
  const displayFormats = {
    hour: "HH",
    date: "DD.MMM",
    day: "DD.MMM",
    week: "WW",
    month: "MMMM YYYY",
    year: "YYYY"
  };
  const getDisplayFormat = (unit) => {
    if (unit === "isoWeek") return displayFormats.week;
    return displayFormats[unit] || displayFormats.day;
  };
  const precisionHierarchy = ["hour", "day", "week", "month"];
  const unitWidth = computed(() => baseUnitWidth.value * zoomLevel.value);
  const getNextPrecision = (currentPrecision) => {
    const currentIndex = precisionHierarchy.indexOf(currentPrecision);
    if (currentIndex < precisionHierarchy.length - 1) {
      return precisionHierarchy[currentIndex + 1];
    }
    return currentPrecision;
  };
  const getPreviousPrecision = (currentPrecision) => {
    const currentIndex = precisionHierarchy.indexOf(currentPrecision);
    const configIndex = precisionHierarchy.indexOf(configPrecision.value);
    if (currentIndex > 0 && currentIndex > configIndex) {
      return precisionHierarchy[currentIndex - 1];
    }
    return currentPrecision;
  };
  const upperPrecision = computed(() => {
    const precisionMap = {
      hour: "day",
      day: "month",
      date: "month",
      week: "month",
      month: "year"
    };
    return precisionMap[internalPrecision.value] || "month";
  });
  const getCacheKey = (startDate, endDate, precision, zoom) => {
    return `${startDate.valueOf()}-${endDate.valueOf()}-${precision}-${zoom}`;
  };
  const getEventsCacheKey = (startDate, endDate, zoom) => {
    return `${startDate.valueOf()}-${endDate.valueOf()}-${zoom}`;
  };
  const getFromCache = (cacheMap, key) => {
    const entry = cacheMap.get(key);
    if (!entry) return null;
    if (Date.now() - entry.timestamp > CACHE_TTL) {
      cacheMap.delete(key);
      return null;
    }
    return entry.units;
  };
  const getEventsFromCache = (key) => {
    const entry = cache.events.get(key);
    if (!entry) return null;
    if (Date.now() - entry.timestamp > CACHE_TTL) {
      cache.events.delete(key);
      return null;
    }
    return entry.events;
  };
  const setInCache = (cacheMap, key, units) => {
    cacheMap.set(key, {
      timestamp: Date.now(),
      units
    });
  };
  const setEventsInCache = (key, events) => {
    cache.events.set(key, {
      timestamp: Date.now(),
      events
    });
  };
  const getDayjsUnit = (unit) => {
    const unitMap = {
      hour: "hour",
      day: "day",
      date: "day",
      week: "week",
      month: "month",
      year: "year",
      isoWeek: "week"
    };
    return unitMap[unit];
  };
  const createTimeaxisUnit = (moment, format, width) => {
    const date = moment.toDate();
    const holidayInfo = holidayHighlight.value ? getHolidayInfo(date) : null;
    const formattedLabel = moment.format(format);
    const capitalizedLabel = capitalizeWords(formattedLabel);
    return {
      label: capitalizedLabel,
      value: String(moment),
      date,
      width,
      isHoliday: (holidayInfo == null ? void 0 : holidayInfo.isHoliday) || false,
      holidayName: holidayInfo == null ? void 0 : holidayInfo.holidayName,
      holidayType: holidayInfo == null ? void 0 : holidayInfo.holidayType
    };
  };
  const updateEventPositions = () => {
    var _a;
    if (!((_a = timeaxisEvents.value) == null ? void 0 : _a.length)) {
      processedTimeaxisEvents.value = [];
      return;
    }
    const { chartStartDayjs, chartEndDayjs } = useDayjsHelper(config);
    const totalMinutes = chartEndDayjs.value.diff(chartStartDayjs.value, "minutes");
    const eventsCacheKey = getEventsCacheKey(
      chartStartDayjs.value,
      chartEndDayjs.value,
      zoomLevel.value
    );
    const cachedEvents = getEventsFromCache(eventsCacheKey);
    if (cachedEvents) {
      processedTimeaxisEvents.value = cachedEvents;
      return;
    }
    const processedEvents = timeaxisEvents.value.map((event) => {
      const eventStartDayjs = dayjs(event.startDate);
      const eventEndDayjs = dayjs(event.endDate);
      if (eventEndDayjs.isBefore(chartStartDayjs.value) || eventStartDayjs.isAfter(chartEndDayjs.value)) {
        return {
          ...event,
          width: "0px",
          xPosition: 0
        };
      }
      const startTime = eventStartDayjs.isBefore(chartStartDayjs.value) ? chartStartDayjs.value : eventStartDayjs;
      const endTime = eventEndDayjs.isAfter(chartEndDayjs.value) ? chartEndDayjs.value : eventEndDayjs;
      const startMinutes = startTime.diff(chartStartDayjs.value, "minutes");
      const endMinutes = endTime.diff(chartStartDayjs.value, "minutes");
      const startPosition = startMinutes / totalMinutes * ganttWidth.value;
      const endPosition = endMinutes / totalMinutes * ganttWidth.value;
      const width = Math.max(endPosition - startPosition, 2);
      return {
        ...event,
        width: `${width}px`,
        xPosition: startPosition
      };
    });
    processedTimeaxisEvents.value = processedEvents;
    setEventsInCache(eventsCacheKey, processedEvents);
  };
  watch(
    () => configPrecision.value,
    () => {
      internalPrecision.value = configPrecision.value;
      zoomLevel.value = defaultZoom.value;
    }
  );
  watch([() => holidayHighlight.value, () => locale.value], () => {
    dayjs.locale(locale.value);
    cache.lower.clear();
    cache.upper.clear();
  });
  watch(ganttWidth, () => {
    updateEventPositions();
  });
  watch(
    [() => timeaxisEvents.value, () => config.chartStart.value, () => config.chartEnd.value],
    () => {
      updateEventPositions();
    },
    { deep: true }
  );
  const timeaxisUnits = computed(() => {
    var _a;
    const { chartStartDayjs, chartEndDayjs } = useDayjsHelper(config);
    const lowerCacheKey = getCacheKey(
      chartStartDayjs.value,
      chartEndDayjs.value,
      internalPrecision.value,
      zoomLevel.value
    );
    let lowerUnits = getFromCache(cache.lower, lowerCacheKey);
    const lowerUnitsByStartTime = /* @__PURE__ */ new Map();
    if (!lowerUnits) {
      lowerUnits = [];
      let currentLower = chartStartDayjs.value.clone();
      while (currentLower.isBefore(chartEndDayjs.value)) {
        const unit = createTimeaxisUnit(
          currentLower,
          getDisplayFormat(internalPrecision.value),
          `${unitWidth.value}px`
        );
        lowerUnits.push(unit);
        lowerUnitsByStartTime.set(currentLower.valueOf(), unit);
        currentLower = currentLower.add(1, getDayjsUnit(internalPrecision.value));
      }
      setInCache(cache.lower, lowerCacheKey, lowerUnits);
    }
    const upperCacheKey = getCacheKey(
      chartStartDayjs.value,
      chartEndDayjs.value,
      upperPrecision.value,
      zoomLevel.value
    );
    let upperUnits = getFromCache(cache.upper, upperCacheKey);
    if (!upperUnits) {
      upperUnits = [];
      let currentUpper = chartStartDayjs.value.startOf(getDayjsUnit(upperPrecision.value));
      while (currentUpper.isBefore(chartEndDayjs.value)) {
        const nextUpper = currentUpper.add(1, getDayjsUnit(upperPrecision.value));
        const effectiveStart = currentUpper.isBefore(chartStartDayjs.value) ? chartStartDayjs.value : currentUpper;
        const effectiveEnd = nextUpper.isAfter(chartEndDayjs.value) ? chartEndDayjs.value : nextUpper;
        let unitsInPeriod = 0;
        if (internalPrecision.value === "day") {
          unitsInPeriod = Math.ceil(effectiveEnd.diff(effectiveStart, "day", true));
        } else if (internalPrecision.value === "month") {
          unitsInPeriod = Math.ceil(effectiveEnd.diff(effectiveStart, "month", true));
        } else if (internalPrecision.value === "week") {
          unitsInPeriod = Math.ceil(effectiveEnd.diff(effectiveStart, "week", true));
        } else {
          unitsInPeriod = Math.ceil(effectiveEnd.diff(effectiveStart, "hour", true));
        }
        const totalWidth = unitsInPeriod * unitWidth.value;
        if (totalWidth > 0) {
          upperUnits.push(
            createTimeaxisUnit(
              currentUpper,
              getDisplayFormat(upperPrecision.value),
              `${totalWidth}px`
            )
          );
        }
        currentUpper = nextUpper;
      }
      setInCache(cache.upper, upperCacheKey, upperUnits);
    }
    if (((_a = timeaxisEvents.value) == null ? void 0 : _a.length) && processedTimeaxisEvents.value.length === 0) {
      updateEventPositions();
    }
    const minuteSteps = calculateMinuteSteps();
    cleanExpiredCache();
    return {
      result: {
        upperUnits,
        lowerUnits,
        events: processedTimeaxisEvents.value
      },
      globalMinuteStep: minuteSteps
    };
  });
  const calculateMinuteSteps = () => {
    if (!config.enableMinutes.value || internalPrecision.value !== "hour") {
      return [];
    }
    const cellWidth = unitWidth.value;
    const minCellWidth = 16;
    const possibleDivisions = Math.floor(cellWidth / minCellWidth);
    let step;
    if (possibleDivisions >= 60) step = 1;
    else if (possibleDivisions >= 12) step = 5;
    else if (possibleDivisions >= 6) step = 10;
    else if (possibleDivisions >= 4) step = 15;
    else if (possibleDivisions >= 2) step = 30;
    else return ["00"];
    return Array.from({ length: 60 / step }, (_, i) => (i * step).toString().padStart(2, "0"));
  };
  const cleanExpiredCache = () => {
    const now = Date.now();
    for (const [key, entry] of cache.lower.entries()) {
      if (now - entry.timestamp > CACHE_TTL) {
        cache.lower.delete(key);
      }
    }
    for (const [key, entry] of cache.upper.entries()) {
      if (now - entry.timestamp > CACHE_TTL) {
        cache.upper.delete(key);
      }
    }
    for (const [key, entry] of cache.events.entries()) {
      if (now - entry.timestamp > CACHE_TTL) {
        cache.events.delete(key);
      }
    }
  };
  const adjustZoomAndPrecision = (increase) => {
    if (increase) {
      if (zoomLevel.value === MAX_ZOOM) {
        const previousPrecision = getPreviousPrecision(internalPrecision.value);
        if (previousPrecision !== internalPrecision.value) {
          internalPrecision.value = previousPrecision;
          zoomLevel.value = MIN_ZOOM;
        }
      } else {
        zoomLevel.value += 1;
      }
    } else {
      if (zoomLevel.value === MIN_ZOOM) {
        const nextPrecision = getNextPrecision(internalPrecision.value);
        if (nextPrecision !== internalPrecision.value) {
          internalPrecision.value = nextPrecision;
          zoomLevel.value = MAX_ZOOM;
        }
      } else {
        zoomLevel.value -= 1;
      }
    }
  };
  watch(
    [
      () => config.chartStart.value,
      () => config.chartEnd.value,
      internalPrecision,
      zoomLevel,
      () => config.timeaxisEvents.value
    ],
    () => {
      cache.lower.clear();
      cache.upper.clear();
      cache.events.clear();
      updateEventPositions();
    }
  );
  updateEventPositions();
  return {
    timeaxisUnits,
    internalPrecision,
    zoomLevel,
    adjustZoomAndPrecision
  };
}
const _hoisted_1$8 = { class: "g-gantt-event-tooltip-content" };
const _hoisted_2$6 = { class: "g-gantt-event-tooltip-title" };
const _hoisted_3$6 = { class: "g-gantt-event-tooltip-time" };
const _hoisted_4$5 = {
  key: 0,
  class: "g-gantt-event-tooltip-description"
};
const _hoisted_5$5 = { class: "g-gantt-holiday-tooltip-content" };
const DEFAULT_DOT_COLOR = "cadetblue";
const _sfc_main$9 = /* @__PURE__ */ defineComponent({
  __name: "GGanttTooltip",
  props: {
    modelValue: { type: Boolean },
    type: {},
    bar: {},
    event: {},
    unit: {},
    targetElement: {}
  },
  setup(__props) {
    const TOOLTIP_FORMATS = {
      hour: "HH:mm",
      day: "DD. MMM HH:mm",
      date: "DD. MMMM YYYY",
      month: "DD. MMMM YYYY",
      week: "DD. MMMM YYYY (WW)"
    };
    const props = __props;
    const { bar, event, unit, targetElement, type } = toRefs(props);
    const { precision, font, barStart, barEnd, rowHeight, milestones, colors, dateFormat } = provideConfig();
    const tooltipTop = ref("0px");
    const tooltipLeft = ref("0px");
    const { toDayjs, format } = useDayjsHelper();
    watch(
      [
        () => props.bar,
        () => props.event,
        () => props.unit,
        () => props.targetElement,
        () => props.type
      ],
      async () => {
        var _a;
        await nextTick();
        if (type.value === "bar" && bar.value) {
          const barId = bar.value.ganttBarConfig.id || "";
          if (!barId) {
            return;
          }
          const barElement = document.getElementById(barId);
          const { top, left } = (barElement == null ? void 0 : barElement.getBoundingClientRect()) || {
            top: 0,
            left: 0
          };
          const leftValue = Math.max(left, 10);
          tooltipTop.value = `${top + rowHeight.value - 10}px`;
          tooltipLeft.value = `${leftValue}px`;
        } else if (type.value === "event" && event.value && targetElement.value) {
          const rect = targetElement.value.getBoundingClientRect();
          tooltipTop.value = `${rect.top - 95}px`;
          tooltipLeft.value = `${rect.left + rect.width / 2}px`;
        } else if (type.value === "holiday" && ((_a = unit.value) == null ? void 0 : _a.holidayName) && targetElement.value) {
          const rect = targetElement.value.getBoundingClientRect();
          tooltipTop.value = `${rect.top - 30}px`;
          tooltipLeft.value = `${rect.left + rect.width / 2}px`;
        }
      },
      { deep: true, immediate: true }
    );
    const dotColor = computed(() => {
      var _a, _b;
      return ((_b = (_a = bar.value) == null ? void 0 : _a.ganttBarConfig.style) == null ? void 0 : _b.background) || DEFAULT_DOT_COLOR;
    });
    const barStartRaw = computed(() => {
      var _a;
      return (_a = bar.value) == null ? void 0 : _a[barStart.value];
    });
    const barEndRaw = computed(() => {
      var _a;
      return (_a = bar.value) == null ? void 0 : _a[barEnd.value];
    });
    const tooltipContent = computed(() => {
      if (!bar.value) {
        return "";
      }
      const milestone = milestones.value.find((m) => {
        var _a;
        return m.id === ((_a = bar.value) == null ? void 0 : _a.ganttBarConfig.milestoneId);
      });
      const format2 = TOOLTIP_FORMATS[precision.value];
      const barStartFormatted = toDayjs(barStartRaw.value).format(format2);
      const barEndFormatted = toDayjs(barEndRaw.value).format(format2);
      const milestoneName = milestone ? ` - (${milestone.name})` : "";
      return `${barStartFormatted} – ${barEndFormatted}${milestoneName}`;
    });
    const formatDate = (date) => {
      return format(date, dateFormat.value);
    };
    const tooltipClass = computed(() => {
      switch (type.value) {
        case "bar":
          return "g-gantt-tooltip";
        case "event":
          return "g-gantt-event-tooltip";
        case "holiday":
          return "g-gantt-holiday-tooltip";
        default:
          return "g-gantt-tooltip";
      }
    });
    const tooltipStyle = computed(() => {
      const baseStyle = {
        top: tooltipTop.value,
        left: tooltipLeft.value,
        fontFamily: font.value
      };
      switch (type.value) {
        case "bar":
          return baseStyle;
        case "event":
          return {
            ...baseStyle,
            background: colors.value.primary,
            color: colors.value.text
          };
        case "holiday":
          return baseStyle;
        default:
          return baseStyle;
      }
    });
    return (_ctx, _cache) => {
      return openBlock(), createBlock(Teleport, { to: "body" }, [
        createVNode(Transition, {
          name: "g-fade",
          mode: "out-in"
        }, {
          default: withCtx(() => {
            var _a;
            return [
              _ctx.modelValue && unref(type) === "bar" && unref(bar) ? (openBlock(), createElementBlock("div", {
                key: 0,
                class: normalizeClass(tooltipClass.value),
                style: normalizeStyle(tooltipStyle.value)
              }, [
                createElementVNode("div", {
                  class: "g-gantt-tooltip-color-dot",
                  style: normalizeStyle({ background: dotColor.value })
                }, null, 4),
                renderSlot(_ctx.$slots, "default", {
                  bar: unref(bar),
                  barStart: barStartRaw.value,
                  barEnd: barEndRaw.value
                }, () => [
                  createTextVNode(toDisplayString(tooltipContent.value), 1)
                ])
              ], 6)) : _ctx.modelValue && unref(type) === "event" && unref(event) ? (openBlock(), createElementBlock("div", {
                key: 1,
                class: normalizeClass(tooltipClass.value),
                style: normalizeStyle(tooltipStyle.value)
              }, [
                renderSlot(_ctx.$slots, "event-tooltip", {
                  event: unref(event),
                  formatDate
                }, () => [
                  createElementVNode("div", _hoisted_1$8, [
                    createElementVNode("div", _hoisted_2$6, toDisplayString(unref(event).label), 1),
                    createElementVNode("div", _hoisted_3$6, toDisplayString(formatDate(unref(event).startDate)) + " - " + toDisplayString(formatDate(unref(event).endDate)), 1),
                    unref(event).description ? (openBlock(), createElementBlock("div", _hoisted_4$5, toDisplayString(unref(event).description), 1)) : createCommentVNode("", true)
                  ])
                ])
              ], 6)) : _ctx.modelValue && unref(type) === "holiday" && ((_a = unref(unit)) == null ? void 0 : _a.holidayName) ? (openBlock(), createElementBlock("div", {
                key: 2,
                class: normalizeClass(tooltipClass.value),
                style: normalizeStyle(tooltipStyle.value)
              }, [
                renderSlot(_ctx.$slots, "holiday-tooltip", { unit: unref(unit) }, () => [
                  createElementVNode("div", _hoisted_5$5, toDisplayString(unref(unit).holidayName), 1)
                ])
              ], 6)) : createCommentVNode("", true)
            ];
          }),
          _: 3
        })
      ]);
    };
  }
});
const _hoisted_1$7 = { class: "g-timeunits-container" };
const _hoisted_2$5 = ["onMouseenter"];
const _hoisted_3$5 = { class: "g-timeunits-container" };
const _hoisted_4$4 = ["onMouseenter"];
const _hoisted_5$4 = { class: "g-timeunit-min" };
const _hoisted_6$4 = { class: "label-unit" };
const _hoisted_7$4 = {
  key: 0,
  class: "g-timeunit-step"
};
const _hoisted_8$4 = { class: "label-unit" };
const _hoisted_9$4 = ["onMouseenter"];
const _hoisted_10$3 = { class: "g-timeaxis-event-label" };
const _sfc_main$8 = /* @__PURE__ */ defineComponent({
  __name: "GGanttTimeaxis",
  props: {
    timeaxisUnits: {},
    internalPrecision: {}
  },
  emits: ["dragStart", "drag", "dragEnd"],
  setup(__props, { expose: __expose, emit: __emit }) {
    const props = __props;
    const { timeaxisUnits, internalPrecision } = toRefs(props);
    const emit = __emit;
    const timeaxisElement = ref(null);
    const hoveredUnit = ref();
    const showTooltip = ref(false);
    const hoveredElement = ref(null);
    const hoveredEvent = ref();
    const showEventTooltip = ref(false);
    const hoveredEventElement = ref(null);
    const {
      precision,
      colors,
      holidayHighlight,
      dayOptionLabel,
      enableMinutes,
      showEventsAxis,
      eventsAxisHeight
    } = provideConfig();
    const { toDayjs } = useDayjsHelper();
    const handleMouseDown = (e) => {
      emit("dragStart", e);
    };
    const dayUnitLevel = computed(() => {
      if (internalPrecision.value === "hour") {
        return "upper";
      } else if (internalPrecision.value === "day") {
        return "lower";
      }
      return null;
    });
    const getHolidayStyle = (unit, unitType) => {
      if (!holidayHighlight.value || dayUnitLevel.value !== unitType || !unit.isHoliday) {
        return {};
      }
      return {
        background: colors.value.holidayHighlight || "#ffebee"
      };
    };
    const handleUnitMouseEnter = (unit, unitType, event) => {
      if (!holidayHighlight.value || dayUnitLevel.value === unitType || !unit.isHoliday) {
        hoveredUnit.value = unit;
        hoveredElement.value = event.currentTarget;
        showTooltip.value = true;
      }
    };
    const handleUnitMouseLeave = () => {
      showTooltip.value = false;
      hoveredUnit.value = void 0;
      hoveredElement.value = null;
    };
    const handleEventMouseEnter = (event, mouseEvent) => {
      hoveredEvent.value = event;
      hoveredEventElement.value = mouseEvent.currentTarget;
      showEventTooltip.value = true;
    };
    const handleEventMouseLeave = () => {
      showEventTooltip.value = false;
      hoveredEvent.value = void 0;
      hoveredEventElement.value = null;
    };
    const formatTimeUnitLabel = (unit, unitType) => {
      if (dayUnitLevel.value !== unitType || !dayOptionLabel.value) {
        return unit.label;
      }
      let result = "";
      for (const option of dayOptionLabel.value) {
        if (result) result += " ";
        switch (option) {
          case "day":
            result += unit.label;
            break;
          case "doy":
            result += `(${toDayjs(unit.date).dayOfYear()})`;
            break;
          case "name":
            result += capitalizeWords(toDayjs(unit.date).format("dd")[0]);
            break;
          case "number":
            result += toDayjs(unit.date).date();
            break;
        }
      }
      return result;
    };
    const eventsAxisHeightValue = computed(() => {
      return eventsAxisHeight.value || 25;
    });
    const shouldShowEventsAxis = computed(() => {
      return showEventsAxis.value && timeaxisUnits.value.result.events.length > 0;
    });
    const eventPositions = computed(() => {
      if (!timeaxisUnits.value.result.events.length) return [];
      const { chartStartDayjs, chartEndDayjs } = useDayjsHelper();
      const totalMinutes = chartEndDayjs.value.diff(chartStartDayjs.value, "minutes");
      return timeaxisUnits.value.result.events.map((event) => {
        const eventStartDayjs = dayjs(event.startDate);
        const eventEndDayjs = dayjs(event.endDate);
        const startTime = eventStartDayjs.isBefore(chartStartDayjs.value) ? chartStartDayjs.value : eventStartDayjs;
        const endTime = eventEndDayjs.isAfter(chartEndDayjs.value) ? chartEndDayjs.value : eventEndDayjs;
        const startMinutes = startTime.diff(chartStartDayjs.value, "minutes");
        const endMinutes = endTime.diff(chartStartDayjs.value, "minutes");
        const xPosition = startMinutes / totalMinutes * ganttWidth.value;
        const width = Math.max((endMinutes - startMinutes) / totalMinutes * ganttWidth.value, 2);
        return {
          ...event,
          calculatedWidth: `${width}px`,
          calculatedX: xPosition
        };
      });
    });
    __expose({ timeaxisElement });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        ref_key: "timeaxisElement",
        ref: timeaxisElement,
        class: "g-timeaxis",
        onMousedown: handleMouseDown,
        role: "tablist",
        "aria-label": "Time Axis",
        style: normalizeStyle({
          borderBottom: `1px solid ${unref(colors).gridAndBorder}`,
          height: shouldShowEventsAxis.value ? `${80 + eventsAxisHeightValue.value}px` : "80px"
        })
      }, [
        createElementVNode("div", _hoisted_1$7, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(unref(timeaxisUnits).result.upperUnits, (unit, index) => {
            return openBlock(), createElementBlock("div", {
              key: unit.date.toISOString(),
              class: "g-upper-timeunit",
              style: normalizeStyle({
                background: index % 2 === 0 ? unref(colors).primary : unref(colors).secondary,
                ...getHolidayStyle(unit, "upper"),
                color: unref(colors).text,
                width: unit.width
              }),
              onMouseenter: (e) => handleUnitMouseEnter(unit, "upper", e),
              onMouseleave: handleUnitMouseLeave
            }, [
              renderSlot(_ctx.$slots, "upper-timeunit", {
                label: formatTimeUnitLabel(unit, "upper"),
                value: unit.value,
                date: unit.date
              }, () => [
                createTextVNode(toDisplayString(formatTimeUnitLabel(unit, "upper")), 1)
              ])
            ], 44, _hoisted_2$5);
          }), 128))
        ]),
        createElementVNode("div", _hoisted_3$5, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(unref(timeaxisUnits).result.lowerUnits, (unit, index) => {
            return openBlock(), createElementBlock("div", {
              key: unit.date.toISOString(),
              class: "g-timeunit",
              style: normalizeStyle({
                background: index % 2 === 0 ? unref(colors).ternary : unref(colors).quartenary,
                ...getHolidayStyle(unit, "lower"),
                color: unref(colors).text,
                flexDirection: unref(precision) === "hour" ? unref(enableMinutes) ? "column" : "row-reverse" : "row",
                alignItems: "center",
                width: unit.width
              }),
              onMouseenter: (e) => handleUnitMouseEnter(unit, "lower", e),
              onMouseleave: handleUnitMouseLeave
            }, [
              createElementVNode("div", _hoisted_5$4, [
                renderSlot(_ctx.$slots, "timeunit", {
                  label: formatTimeUnitLabel(unit, "lower"),
                  value: unit.value,
                  date: unit.date
                }, () => [
                  createElementVNode("div", _hoisted_6$4, toDisplayString(formatTimeUnitLabel(unit, "lower")), 1)
                ]),
                unref(precision) === "hour" ? (openBlock(), createElementBlock("div", {
                  key: 0,
                  class: "g-timeaxis-hour-pin",
                  style: normalizeStyle({ background: unref(colors).text })
                }, null, 4)) : createCommentVNode("", true)
              ]),
              unref(precision) === "hour" && unref(enableMinutes) ? (openBlock(), createElementBlock("div", _hoisted_7$4, [
                (openBlock(true), createElementBlock(Fragment, null, renderList(unref(timeaxisUnits).globalMinuteStep, (step) => {
                  return openBlock(), createElementBlock("div", {
                    key: `${unit.label}-${step}`,
                    style: normalizeStyle({
                      background: index % 2 === 0 ? unref(colors).ternary : unref(colors).quartenary,
                      color: unref(colors).text,
                      display: "flex",
                      flexGrow: 1,
                      flexDirection: "row-reverse",
                      alignItems: "center"
                    })
                  }, [
                    createElementVNode("div", _hoisted_8$4, toDisplayString(step), 1),
                    createElementVNode("div", {
                      class: "g-timeaxis-hour-pin",
                      style: normalizeStyle({ background: unref(colors).text })
                    }, null, 4)
                  ], 4);
                }), 128))
              ])) : createCommentVNode("", true)
            ], 44, _hoisted_4$4);
          }), 128))
        ]),
        shouldShowEventsAxis.value ? (openBlock(), createElementBlock("div", {
          key: 0,
          class: "g-events-container",
          style: normalizeStyle({
            height: `${eventsAxisHeightValue.value}px`,
            background: unref(colors).background
          })
        }, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(eventPositions.value, (event) => {
            return openBlock(), createElementBlock("div", {
              key: event.id,
              class: "g-timeaxis-event",
              style: normalizeStyle({
                left: `${event.calculatedX}px`,
                width: event.calculatedWidth,
                backgroundColor: event.backgroundColor || unref(colors).primary,
                color: event.color || unref(colors).text,
                borderColor: event.color || unref(colors).primary
              }),
              onMouseenter: (e) => handleEventMouseEnter(event, e),
              onMouseleave: handleEventMouseLeave
            }, [
              createElementVNode("div", _hoisted_10$3, [
                renderSlot(_ctx.$slots, "timeaxis-event", { event }, () => [
                  createTextVNode(toDisplayString(event.label), 1)
                ])
              ])
            ], 44, _hoisted_9$4);
          }), 128))
        ], 4)) : createCommentVNode("", true),
        createVNode(_sfc_main$9, {
          type: "holiday",
          "model-value": showTooltip.value,
          unit: hoveredUnit.value,
          "target-element": hoveredElement.value
        }, {
          "holiday-tooltip": withCtx((slotProps) => [
            renderSlot(_ctx.$slots, "holiday-tooltip", normalizeProps(guardReactiveProps(slotProps)))
          ]),
          _: 3
        }, 8, ["model-value", "unit", "target-element"]),
        createVNode(_sfc_main$9, {
          type: "event",
          "model-value": showEventTooltip.value,
          event: hoveredEvent.value,
          "target-element": hoveredEventElement.value
        }, {
          "event-tooltip": withCtx((slotProps) => [
            renderSlot(_ctx.$slots, "event-tooltip", normalizeProps(guardReactiveProps(slotProps)))
          ]),
          _: 3
        }, 8, ["model-value", "event", "target-element"])
      ], 36);
    };
  }
});
function useTimePositionMapping(config = provideConfig()) {
  const { dateFormat } = config;
  const { chartStartDayjs, chartEndDayjs, toDayjs, format } = useDayjsHelper(config);
  const totalNumOfMinutes = computed(() => {
    return chartEndDayjs.value.diff(chartStartDayjs.value, "minutes");
  });
  const mapTimeToPosition = (time) => {
    const width = ganttWidth.value || 0;
    const diffFromStart = toDayjs(time).diff(chartStartDayjs.value, "minutes", true);
    const position = Math.ceil(diffFromStart / totalNumOfMinutes.value * width);
    return position;
  };
  const mapPositionToTime = (xPos) => {
    const width = ganttWidth.value || 0;
    const diffFromStart = xPos / width * totalNumOfMinutes.value;
    return format(chartStartDayjs.value.add(diffFromStart, "minutes"), dateFormat.value);
  };
  return {
    mapTimeToPosition,
    mapPositionToTime
  };
}
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
  __name: "GGanttCurrentTime",
  setup(__props) {
    const { mapTimeToPosition } = useTimePositionMapping();
    const currentMoment = ref(dayjs());
    const { colors, dateFormat, currentTimeLabel, utc: utc2 } = provideConfig();
    const xDist = ref();
    const loopTime = () => {
      const now = utc2.value ? dayjs().utc() : dayjs();
      currentMoment.value = now;
      const format = dateFormat.value || "YYYY-MM-DD HH:mm:ss";
      xDist.value = mapTimeToPosition(dayjs(currentMoment.value, format).format(format));
    };
    useIntervalFn(loopTime, 1e3);
    const currentTimeDisplay = computed(() => {
      if (utc2.value) {
        return `${currentTimeLabel.value} (UTC)`;
      }
      return currentTimeLabel.value;
    });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        class: "g-grid-current-time",
        style: normalizeStyle({
          left: `${xDist.value}px`
        })
      }, [
        createElementVNode("div", {
          class: "g-grid-current-time-marker",
          style: normalizeStyle({
            border: `1px dashed ${unref(colors).markerCurrentTime}`
          })
        }, null, 4),
        createElementVNode("span", {
          class: "g-grid-current-time-text",
          style: normalizeStyle({ color: unref(colors).markerCurrentTime })
        }, [
          renderSlot(_ctx.$slots, "current-time-label", {}, () => [
            createTextVNode(toDisplayString(currentTimeDisplay.value), 1)
          ])
        ], 4)
      ], 4);
    };
  }
});
const _hoisted_1$6 = {
  class: "gantt-connector",
  style: {
    position: "absolute",
    top: 0,
    left: 0,
    width: "100%",
    height: "100%",
    zIndex: 1001,
    overflow: "visible"
  }
};
const _hoisted_2$4 = ["id"];
const _hoisted_3$4 = ["fill"];
const _hoisted_4$3 = ["id"];
const _hoisted_5$3 = ["stop-color"];
const _hoisted_6$3 = ["stop-color"];
const _hoisted_7$3 = ["stop-color"];
const _hoisted_8$3 = ["stop-color"];
const _hoisted_9$3 = ["dur"];
const _hoisted_10$2 = ["dur"];
const _hoisted_11$2 = ["d", "stroke", "stroke-width", "stroke-dasharray"];
const _hoisted_12$2 = ["x", "y"];
const _hoisted_13$2 = ["cx", "cy"];
const _hoisted_14$2 = ["cx", "cy"];
const STANDARD_OFFSET = 20;
const _sfc_main$6 = /* @__PURE__ */ defineComponent({
  __name: "GGanttConnector",
  props: {
    sourceBar: {},
    targetBar: {},
    type: { default: "straight" },
    color: { default: "#ff0000" },
    strokeWidth: { default: 2 },
    pattern: { default: "solid" },
    animated: { type: Boolean, default: false },
    animationSpeed: { default: "normal" },
    marker: {},
    isSelected: { type: Boolean, default: false },
    relation: { default: "FS" },
    label: { default: "" },
    labelAlwaysVisible: { type: Boolean, default: false },
    labelStyle: { default: () => ({}) }
  },
  setup(__props) {
    const props = __props;
    const { enableConnectionDeletion } = provideConfig();
    const pathRef = ref(null);
    const animationClass = computed(() => {
      if (!props.animated) return "";
      return `connector-animated-${props.pattern}-${props.animationSpeed}`;
    });
    const markerId = computed(() => `marker-${props.sourceBar.id}-${props.targetBar.id}`);
    const hasMarkerEnd = computed(() => props.marker === "bidirectional" || props.marker === "forward");
    const hasMarkerStart = computed(() => props.marker === "bidirectional");
    const markerDelta = computed(() => 4);
    const shouldShowLabel = computed(() => {
      return props.label && (props.labelAlwaysVisible || props.isSelected);
    });
    const labelComputedStyle = computed(() => {
      const defaultStyle = {
        fill: props.color,
        fontWeight: "bold"
      };
      return {
        ...defaultStyle,
        ...props.labelStyle
      };
    });
    const connectionPoints = computed(() => {
      const { sourceBar, targetBar, relation } = props;
      switch (relation) {
        case "FS":
          return {
            sourceX: sourceBar.x + sourceBar.width,
            sourceY: sourceBar.y + sourceBar.height / 2,
            targetX: targetBar.x,
            targetY: targetBar.y + targetBar.height / 2
          };
        case "SS":
          return {
            sourceX: sourceBar.x,
            sourceY: sourceBar.y + sourceBar.height / 2,
            targetX: targetBar.x,
            targetY: targetBar.y + targetBar.height / 2
          };
        case "FF":
          return {
            sourceX: sourceBar.x + sourceBar.width,
            sourceY: sourceBar.y + sourceBar.height / 2,
            targetX: targetBar.x + targetBar.width,
            targetY: targetBar.y + targetBar.height / 2
          };
        case "SF":
          return {
            sourceX: sourceBar.x,
            sourceY: sourceBar.y + sourceBar.height / 2,
            targetX: targetBar.x + targetBar.width,
            targetY: targetBar.y + targetBar.height / 2
          };
        default:
          return {
            sourceX: sourceBar.x + sourceBar.width,
            sourceY: sourceBar.y + sourceBar.height / 2,
            targetX: targetBar.x,
            targetY: targetBar.y + targetBar.height / 2
          };
      }
    });
    const pathData = computed(() => {
      const { sourceX, sourceY, targetX, targetY } = connectionPoints.value;
      const { relation, type } = props;
      const verticalDiff = targetY - sourceY;
      const extraOffset = relation === "FF" || relation === "SF" ? 20 : 0;
      const horizontalSpace = targetX - sourceX;
      const isOverlapping = Math.abs(horizontalSpace) < STANDARD_OFFSET * (relation === "FS" ? 1 : 2);
      const offset = isOverlapping ? Math.max(STANDARD_OFFSET, Math.abs(horizontalSpace) / 2) : STANDARD_OFFSET;
      const verticalOffset = verticalDiff === 0 && isOverlapping ? 20 : 0;
      const startAdjust = hasMarkerStart.value ? markerDelta.value : 0;
      const endAdjust = hasMarkerEnd.value ? markerDelta.value : 0;
      switch (type) {
        case "straight":
          if (isOverlapping) {
            const midY = (sourceY + targetY) / 2 + verticalOffset * (sourceY > targetY ? -1 : 1);
            return `M ${sourceX + startAdjust},${sourceY} 
                Q ${sourceX + offset},${midY} ${(sourceX + targetX) / 2},${midY} 
                Q ${targetX - offset},${midY} ${targetX - endAdjust},${targetY}`;
          } else {
            return `M ${sourceX + startAdjust},${sourceY} L ${targetX - endAdjust},${targetY}`;
          }
        case "squared":
          if (relation === "FS") {
            return `M ${sourceX + startAdjust},${sourceY}
                  h ${offset / 2}
                  v ${verticalDiff}
                  h ${horizontalSpace - offset / 2 - endAdjust}`;
          } else if (relation === "SS") {
            return `M ${sourceX + startAdjust},${sourceY}
                  h ${-offset / 2}
                  v ${verticalDiff}
                  h ${horizontalSpace + offset / 2 - endAdjust}`;
          } else if (relation === "FF") {
            return `M ${sourceX + startAdjust},${sourceY}
                h ${offset / 2}
                v ${verticalDiff / 2}
                h ${horizontalSpace + offset / 2}
                v ${verticalDiff / 2}
                h ${-offset / 2 - endAdjust}`;
          } else if (relation === "SF") {
            return `M ${sourceX + startAdjust},${sourceY}
                h ${-offset / 2}
                v ${verticalDiff / 2}
                h ${horizontalSpace + offset * 1.5}
                v ${verticalDiff / 2}
                h ${-offset / 2 - endAdjust}`;
          }
          return `M ${sourceX + startAdjust},${sourceY}
              h ${offset}
              v ${verticalDiff}
              h ${horizontalSpace - offset - endAdjust}`;
        case "bezier":
        default:
          let controlOffset = Math.max(Math.abs(horizontalSpace) / 3, offset * 1.5);
          if (isOverlapping) controlOffset = Math.max(controlOffset, offset * 2);
          if (relation === "FF" || relation === "SF") {
            const midX = targetX + extraOffset;
            return `M ${sourceX + (hasMarkerStart.value ? startAdjust : 0)},${sourceY}
                C ${midX},${sourceY}
                  ${midX},${targetY}
                  ${targetX + (hasMarkerEnd.value ? endAdjust : 0)},${targetY}`;
          } else {
            let cp1x, cp2x;
            switch (relation) {
              case "FS":
                cp1x = sourceX + controlOffset;
                cp2x = targetX - controlOffset;
                break;
              case "SS":
                cp1x = sourceX - controlOffset;
                cp2x = targetX - controlOffset;
                break;
              default:
                cp1x = sourceX + controlOffset;
                cp2x = targetX - controlOffset;
            }
            return `M ${sourceX + (hasMarkerStart.value ? startAdjust : 0)},${sourceY}
                C ${cp1x},${sourceY}
                  ${cp2x},${targetY}
                  ${targetX - (hasMarkerEnd.value ? endAdjust : 0)},${targetY}`;
          }
      }
    });
    const nonAnimatedDashArray = computed(() => {
      if (props.animated) return void 0;
      switch (props.pattern) {
        case "dash":
          return "8,8";
        case "dot":
          return "2,6";
        case "dashdot":
          return "12,6,3,6";
        default:
          return "";
      }
    });
    const getStrokeWidth = computed(() => {
      if (props.isSelected && enableConnectionDeletion.value) {
        return props.strokeWidth * 1.5;
      }
      return props.strokeWidth;
    });
    const endpointPositions = computed(() => {
      const { sourceX, sourceY, targetX, targetY } = connectionPoints.value;
      return {
        source: { x: sourceX, y: sourceY },
        target: { x: targetX, y: targetY }
      };
    });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("svg", _hoisted_1$6, [
        createElementVNode("defs", null, [
          createElementVNode("marker", {
            id: markerId.value,
            viewBox: "0 0 10 10",
            refX: "5",
            refY: "5",
            markerWidth: "6",
            markerHeight: "6",
            orient: "auto-start-reverse"
          }, [
            createElementVNode("path", {
              d: "M 0 0 L 10 5 L 0 10 z",
              fill: _ctx.color
            }, null, 8, _hoisted_3$4)
          ], 8, _hoisted_2$4),
          _ctx.animated && _ctx.pattern === "solid" ? (openBlock(), createElementBlock("linearGradient", {
            key: 0,
            id: `gradient-${_ctx.sourceBar.id}-${_ctx.targetBar.id}`,
            gradientUnits: "userSpaceOnUse",
            x1: "0%",
            y1: "0%",
            x2: "100%",
            y2: "0%"
          }, [
            createElementVNode("stop", {
              offset: "0%",
              "stop-color": _ctx.color,
              "stop-opacity": "0.3"
            }, null, 8, _hoisted_5$3),
            createElementVNode("stop", {
              offset: "45%",
              "stop-color": _ctx.color,
              "stop-opacity": "1"
            }, null, 8, _hoisted_6$3),
            createElementVNode("stop", {
              offset: "55%",
              "stop-color": _ctx.color,
              "stop-opacity": "1"
            }, null, 8, _hoisted_7$3),
            createElementVNode("stop", {
              offset: "100%",
              "stop-color": _ctx.color,
              "stop-opacity": "0.3"
            }, null, 8, _hoisted_8$3),
            createElementVNode("animate", {
              attributeName: "x1",
              from: "-100%",
              to: "100%",
              dur: _ctx.animationSpeed === "slow" ? "4s" : _ctx.animationSpeed === "fast" ? "1s" : "2s",
              repeatCount: "indefinite"
            }, null, 8, _hoisted_9$3),
            createElementVNode("animate", {
              attributeName: "x2",
              from: "0%",
              to: "200%",
              dur: _ctx.animationSpeed === "slow" ? "4s" : _ctx.animationSpeed === "fast" ? "1s" : "2s",
              repeatCount: "indefinite"
            }, null, 8, _hoisted_10$2)
          ], 8, _hoisted_4$3)) : createCommentVNode("", true)
        ]),
        createElementVNode("path", {
          ref_key: "pathRef",
          ref: pathRef,
          d: pathData.value,
          fill: "none",
          stroke: _ctx.animated && _ctx.pattern === "solid" ? `url(#gradient-${_ctx.sourceBar.id}-${_ctx.targetBar.id})` : _ctx.color,
          "stroke-width": getStrokeWidth.value,
          "stroke-dasharray": nonAnimatedDashArray.value,
          class: normalizeClass([
            "connector-path",
            animationClass.value,
            { selected: _ctx.isSelected && unref(enableConnectionDeletion) },
            `connector-relation-${_ctx.relation || "FS"}`
          ]),
          style: normalizeStyle({
            markerStart: hasMarkerStart.value ? `url(#${markerId.value})` : "none",
            markerEnd: hasMarkerEnd.value ? `url(#${markerId.value})` : "none",
            cursor: unref(enableConnectionDeletion) ? "pointer" : "inherit",
            pointerEvents: unref(enableConnectionDeletion) ? "all" : "none"
          })
        }, null, 14, _hoisted_11$2),
        shouldShowLabel.value ? (openBlock(), createElementBlock("text", {
          key: 0,
          x: (endpointPositions.value.source.x + endpointPositions.value.target.x) / 2 - 50,
          y: (endpointPositions.value.source.y + endpointPositions.value.target.y) / 2 - 20,
          class: "connection-label-container",
          "text-anchor": "middle",
          style: normalizeStyle({
            pointerEvents: "none",
            ...labelComputedStyle.value
          })
        }, toDisplayString(_ctx.label), 13, _hoisted_12$2)) : createCommentVNode("", true),
        _ctx.isSelected && unref(enableConnectionDeletion) ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
          createElementVNode("circle", {
            cx: endpointPositions.value.source.x,
            cy: endpointPositions.value.source.y,
            r: "6",
            fill: "white",
            class: "connection-endpoint"
          }, null, 8, _hoisted_13$2),
          createElementVNode("circle", {
            cx: endpointPositions.value.target.x,
            cy: endpointPositions.value.target.y,
            r: "6",
            fill: "white",
            class: "connection-endpoint"
          }, null, 8, _hoisted_14$2)
        ], 64)) : createCommentVNode("", true)
      ]);
    };
  }
});
const _export_sfc = (sfc, props) => {
  const target = sfc.__vccOpts || sfc;
  for (const [key, val] of props) {
    target[key] = val;
  }
  return target;
};
const GGanttConnector = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-652d5ef8"]]);
const _hoisted_1$5 = { class: "g-gantt-milestone-tooltip-title" };
const _hoisted_2$3 = { class: "g-gantt-milestone-tooltip-date" };
const _hoisted_3$3 = { class: "g-gantt-milestone-tooltip-description" };
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
  __name: "GGanttMilestone",
  props: {
    milestone: {}
  },
  setup(__props) {
    const props = __props;
    const { mapTimeToPosition } = useTimePositionMapping();
    const { colors } = provideConfig();
    const showTooltip = ref(false);
    const tooltipPosition = ref({ x: 0, y: 0 });
    const milestoneDate = computed(() => {
      const date = dayjs(props.milestone.date);
      if (!date.hour() && !date.minute()) {
        return date.hour(12).minute(0).format("YYYY-MM-DD HH:mm");
      }
      return props.milestone.date;
    });
    const xPosition = computed(() => {
      return mapTimeToPosition(milestoneDate.value);
    });
    const styleConfig = computed(() => {
      if (props.milestone.color) {
        return {
          label: {
            background: props.milestone.color,
            color: "#000",
            border: `2px solid ${props.milestone.color}`
          },
          marker: {
            borderLeft: `2px solid ${props.milestone.color}`
          }
        };
      }
      return {
        label: {
          background: colors.value.primary,
          color: colors.value.text,
          border: "none"
        },
        marker: {
          borderLeft: `2px solid ${colors.value.markerCurrentTime}`
        }
      };
    });
    const handleMouseEnter = (event) => {
      const element = event.target;
      const rect = element.getBoundingClientRect();
      tooltipPosition.value = {
        x: rect.left,
        y: rect.top + 10
      };
      showTooltip.value = true;
    };
    const handleMouseLeave = () => {
      showTooltip.value = false;
    };
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        class: "g-gantt-milestone",
        style: normalizeStyle({
          left: `${xPosition.value}px`
        }),
        onMouseenter: handleMouseEnter,
        onMouseleave: handleMouseLeave
      }, [
        renderSlot(_ctx.$slots, `milestone-${_ctx.milestone.id}`, {
          milestone: _ctx.milestone,
          styleConfig: styleConfig.value,
          position: xPosition.value
        }, () => [
          renderSlot(_ctx.$slots, "milestone", {
            milestone: _ctx.milestone,
            styleConfig: styleConfig.value,
            position: xPosition.value
          }, () => [
            createElementVNode("div", {
              class: "g-gantt-milestone-label",
              style: normalizeStyle(styleConfig.value.label)
            }, toDisplayString(_ctx.milestone.name), 5)
          ])
        ]),
        createElementVNode("div", {
          class: "g-gantt-milestone-marker",
          style: normalizeStyle(styleConfig.value.marker)
        }, null, 4),
        (openBlock(), createBlock(Teleport, { to: "body" }, [
          createVNode(Transition, {
            name: "g-fade",
            mode: "out-in"
          }, {
            default: withCtx(() => [
              showTooltip.value ? (openBlock(), createElementBlock("div", {
                key: 0,
                class: "g-gantt-milestone-tooltip",
                style: normalizeStyle({
                  top: `${tooltipPosition.value.y}px`,
                  left: `${tooltipPosition.value.x}px`,
                  background: unref(colors).primary,
                  color: unref(colors).text
                })
              }, [
                createElementVNode("div", _hoisted_1$5, toDisplayString(_ctx.milestone.name), 1),
                createElementVNode("div", _hoisted_2$3, toDisplayString(_ctx.milestone.date), 1),
                createElementVNode("div", _hoisted_3$3, toDisplayString(_ctx.milestone.description), 1)
              ], 4)) : createCommentVNode("", true)
            ]),
            _: 1
          })
        ]))
      ], 36);
    };
  }
});
function provideEmitBarEvent() {
  const emitBarEvent = inject(EMIT_BAR_EVENT_KEY);
  if (!emitBarEvent) {
    throw Error("Failed to inject emitBarEvent!");
  }
  return emitBarEvent;
}
function useBarSelector() {
  const findBarElement = (ganttId, barId) => {
    const ganttContainer = document.getElementById(ganttId);
    if (!ganttContainer) return null;
    return ganttContainer.querySelector(`#${CSS.escape(barId)}`);
  };
  const findAllBarElements = (ganttId) => {
    const ganttContainer = document.getElementById(ganttId);
    if (!ganttContainer) return document.querySelectorAll(".non-existent");
    return ganttContainer.querySelectorAll(".g-gantt-bar");
  };
  const barExistsInGantt = (ganttId, barId) => {
    return !!findBarElement(ganttId, barId);
  };
  return {
    findBarElement,
    findAllBarElements,
    barExistsInGantt
  };
}
function createBarDrag(bar, onDrag = () => null, onEndDrag = () => null, config, movementAPI, ganttId) {
  const { findBarElement } = useBarSelector();
  const { barStart, barEnd } = config;
  const isDragging = ref(false);
  let cursorOffsetX = 0;
  let initialBarLeft = 0;
  let dragCallBack;
  const { mapPositionToTime } = useTimePositionMapping(config);
  const { toDayjs } = useDayjsHelper(config);
  const initDrag = (e) => {
    if (bar.ganttBarConfig.immobile) {
      return;
    }
    const barElement = findBarElement(ganttId, bar.ganttBarConfig.id);
    if (!barElement) {
      return;
    }
    const rect = barElement.getBoundingClientRect();
    initialBarLeft = rect.left;
    cursorOffsetX = e.clientX - initialBarLeft;
    const mousedownType = e.target.className;
    switch (mousedownType) {
      case "g-gantt-bar-handle-left":
        document.body.style.cursor = "ew-resize";
        dragCallBack = dragByLeftHandle;
        break;
      case "g-gantt-bar-handle-right":
        document.body.style.cursor = "ew-resize";
        dragCallBack = dragByRightHandle;
        break;
      default:
        dragCallBack = drag;
    }
    isDragging.value = true;
    window.addEventListener("mousemove", dragCallBack);
    window.addEventListener("mouseup", endDrag);
  };
  const getBarElements = () => {
    const barElement = findBarElement(ganttId, bar.ganttBarConfig.id);
    let currentElement = barElement;
    let barContainer = null;
    while (currentElement && !barContainer) {
      const container = currentElement.closest(".g-gantt-row-bars-container");
      if (container) {
        barContainer = container.getBoundingClientRect();
      }
      currentElement = currentElement.parentElement;
    }
    return { barElement, barContainer };
  };
  const drag = (e) => {
    const { barElement, barContainer } = getBarElements();
    if (!barElement || !barContainer) {
      console.warn("Missing elements:", { barElement, barContainer });
      return;
    }
    const barWidth = barElement.getBoundingClientRect().width;
    const relativeX = e.clientX - cursorOffsetX - barContainer.left;
    const xStart = Math.max(0, relativeX);
    const xEnd = xStart + barWidth;
    const newBarStart = mapPositionToTime(xStart);
    const newBarEnd = mapPositionToTime(xEnd);
    const currentStart = bar[barStart.value];
    const currentEnd = bar[barEnd.value];
    const result = movementAPI.moveBar(bar, newBarStart, newBarEnd);
    if (!result.success) {
      bar[barStart.value] = currentStart;
      bar[barEnd.value] = currentEnd;
      endDrag(e);
      return;
    }
    onDrag(e, bar);
  };
  const dragByLeftHandle = (e) => {
    const { barContainer } = getBarElements();
    if (!barContainer) {
      return;
    }
    const xStart = e.clientX - barContainer.left;
    const newBarStart = mapPositionToTime(xStart);
    if (toDayjs(newBarStart).isSameOrAfter(toDayjs(bar[barEnd.value]))) {
      return;
    }
    const result = movementAPI.moveBar(bar, newBarStart, bar[barEnd.value]);
    if (result.success) {
      onDrag(e, bar);
    }
  };
  const dragByRightHandle = (e) => {
    const { barContainer } = getBarElements();
    if (!barContainer) {
      return;
    }
    const xEnd = e.clientX - barContainer.left;
    const newBarEnd = mapPositionToTime(xEnd);
    if (toDayjs(newBarEnd).isSameOrBefore(toDayjs(bar[barStart.value]))) {
      return;
    }
    const result = movementAPI.moveBar(bar, bar[barStart.value], newBarEnd);
    if (result.success) {
      onDrag(e, bar);
    }
  };
  const endDrag = (e) => {
    isDragging.value = false;
    document.body.style.cursor = "";
    window.removeEventListener("mousemove", dragCallBack);
    window.removeEventListener("mouseup", endDrag);
    onEndDrag(e, bar);
  };
  return {
    isDragging,
    initDrag
  };
}
function useBarMovement(config, rowManager, dayjsHelper) {
  const { barStart, barEnd, dateFormat, pushOnOverlap, pushOnConnect } = config;
  const processedBars = /* @__PURE__ */ new Set();
  const formatDate = (date) => {
    const result = dayjsHelper.format(date, dateFormat.value);
    return typeof result === "string" ? result : result.toISOString();
  };
  const checkMilestoneConstraint = (bar, newEnd) => {
    if (!bar.ganttBarConfig.milestoneId || !config.milestones.value) return true;
    const milestone = config.milestones.value.find((m) => m.id === bar.ganttBarConfig.milestoneId);
    if (!milestone) return true;
    const endDate = dayjsHelper.toDayjs(newEnd);
    const date = dayjs(milestone.date);
    let milestoneDate = date;
    if (!date.hour() && !date.minute()) {
      milestoneDate = dayjsHelper.toDayjs(date.hour(23).minute(59).format("YYYY-MM-DD HH:mm"));
    }
    return endDate.isSameOrBefore(milestoneDate);
  };
  const getAllBars = () => {
    const extractBarsFromRow = (row) => {
      var _a;
      let bars = [...row.bars];
      if ((_a = row.children) == null ? void 0 : _a.length) {
        row.children.forEach((child) => {
          bars = [...bars, ...extractBarsFromRow(child)];
        });
      }
      return bars;
    };
    return rowManager.rows.value.flatMap((row) => extractBarsFromRow(row));
  };
  const moveBar = (bar, newStart, newEnd, initialMove = true) => {
    if (processedBars.has(bar.ganttBarConfig.id)) {
      return { success: true, affectedBars: /* @__PURE__ */ new Set() };
    }
    if (!checkMilestoneConstraint(bar, newEnd)) {
      return { success: false, affectedBars: /* @__PURE__ */ new Set() };
    }
    processedBars.add(bar.ganttBarConfig.id);
    const affectedBars = /* @__PURE__ */ new Set();
    const originalStart = bar[barStart.value];
    const originalEnd = bar[barEnd.value];
    bar[barStart.value] = newStart;
    bar[barEnd.value] = newEnd;
    if (bar.ganttBarConfig.bundle && initialMove) {
      const bundleBars = getAllBars().filter(
        (b) => b.ganttBarConfig.bundle === bar.ganttBarConfig.bundle && b !== bar
      );
      const timeDiff = dayjsHelper.toDayjs(newStart).diff(dayjsHelper.toDayjs(originalStart), "minutes");
      for (const bundleBar of bundleBars) {
        const bundleBarNewStart = formatDate(
          dayjsHelper.toDayjs(bundleBar[barStart.value]).add(timeDiff, "minutes")
        );
        const bundleBarNewEnd = formatDate(
          dayjsHelper.toDayjs(bundleBar[barEnd.value]).add(timeDiff, "minutes")
        );
        const bundleResult = moveBar(bundleBar, bundleBarNewStart, bundleBarNewEnd, false);
        if (!bundleResult.success) {
          bar[barStart.value] = originalStart;
          bar[barEnd.value] = originalEnd;
          processedBars.delete(bar.ganttBarConfig.id);
          return { success: false, affectedBars: /* @__PURE__ */ new Set() };
        }
        bundleResult.affectedBars.forEach((b) => affectedBars.add(b));
      }
    }
    const result = handleBarInteractions(bar, affectedBars);
    if (!result.success) {
      bar[barStart.value] = originalStart;
      bar[barEnd.value] = originalEnd;
      processedBars.delete(bar.ganttBarConfig.id);
      return { success: false, affectedBars: /* @__PURE__ */ new Set() };
    }
    if (initialMove) {
      processedBars.clear();
    }
    affectedBars.add(bar);
    return { success: true, affectedBars };
  };
  const handleBarInteractions = (bar, affectedBars) => {
    const overlappingBars = pushOnOverlap.value ? findOverlappingBars(bar) : [];
    const connectedBars = pushOnConnect.value ? findConnectedBars(bar) : [];
    const impactedBars = [.../* @__PURE__ */ new Set([...overlappingBars, ...connectedBars])];
    for (const impactedBar of impactedBars) {
      if (impactedBar.ganttBarConfig.immobile) {
        return { success: false };
      }
      const { shouldMove, minutesToMove, direction } = calculateMovement(bar, impactedBar);
      if (!shouldMove) continue;
      const newStart = formatDate(
        direction === "left" ? dayjsHelper.toDayjs(impactedBar[barStart.value]).subtract(minutesToMove, "minutes") : dayjsHelper.toDayjs(impactedBar[barStart.value]).add(minutesToMove, "minutes")
      );
      const newEnd = formatDate(
        direction === "left" ? dayjsHelper.toDayjs(impactedBar[barEnd.value]).subtract(minutesToMove, "minutes") : dayjsHelper.toDayjs(impactedBar[barEnd.value]).add(minutesToMove, "minutes")
      );
      if (!checkMilestoneConstraint(impactedBar, newEnd)) {
        return { success: false };
      }
      const result = moveBar(impactedBar, newStart, newEnd, false);
      if (!result.success) {
        return { success: false };
      }
      affectedBars.add(impactedBar);
      result.affectedBars.forEach((b) => affectedBars.add(b));
    }
    return { success: true };
  };
  const calculateMovement = (sourceBar, targetBar) => {
    const sourceStart = dayjsHelper.toDayjs(sourceBar[barStart.value]);
    const sourceEnd = dayjsHelper.toDayjs(sourceBar[barEnd.value]);
    const targetStart = dayjsHelper.toDayjs(targetBar[barStart.value]);
    const targetEnd = dayjsHelper.toDayjs(targetBar[barEnd.value]);
    if (targetBar.ganttBarConfig.immobile && (sourceStart.isBefore(targetEnd) && sourceEnd.isAfter(targetStart) || sourceEnd.isAfter(targetStart) && sourceStart.isBefore(targetEnd))) {
      return { shouldMove: false, minutesToMove: 0, direction: "right" };
    }
    if (sourceEnd.isSameOrBefore(targetStart) || sourceStart.isSameOrAfter(targetEnd)) {
      return { shouldMove: false, minutesToMove: 0, direction: "right" };
    }
    const direction = sourceStart.isBefore(targetStart) ? "right" : "left";
    let minutesToMove = 0;
    if (direction === "right") {
      minutesToMove = sourceEnd.diff(targetStart, "minutes", true);
    } else {
      minutesToMove = targetEnd.diff(sourceStart, "minutes", true);
    }
    return {
      shouldMove: true,
      minutesToMove: Math.abs(minutesToMove),
      direction
    };
  };
  const findOverlappingBars = (bar) => {
    const findRowForBar = (searchBar, rows) => {
      var _a;
      for (const row of rows) {
        if (row.bars.includes(searchBar)) return row;
        if ((_a = row.children) == null ? void 0 : _a.length) {
          const foundInChildren = findRowForBar(searchBar, row.children);
          if (foundInChildren) return foundInChildren;
        }
      }
      return null;
    };
    const barRow = findRowForBar(bar, rowManager.rows.value);
    if (!barRow) return [];
    return barRow.bars.filter((otherBar) => {
      if (otherBar === bar || otherBar.ganttBarConfig.pushOnOverlap === false) return false;
      if (otherBar.ganttBarConfig.id.startsWith("group-")) return false;
      const start1 = dayjsHelper.toDayjs(bar[barStart.value]);
      const end1 = dayjsHelper.toDayjs(bar[barEnd.value]);
      const start2 = dayjsHelper.toDayjs(otherBar[barStart.value]);
      const end2 = dayjsHelper.toDayjs(otherBar[barEnd.value]);
      return start1.isBefore(end2) && end1.isAfter(start2) || start2.isBefore(end1) && end2.isAfter(start1);
    });
  };
  const findConnectedBars = (bar) => {
    var _a;
    const allBars = getAllBars();
    const connectedBars = [];
    (_a = bar.ganttBarConfig.connections) == null ? void 0 : _a.forEach((conn) => {
      const targetBar = allBars.find((b) => b.ganttBarConfig.id === conn.targetId);
      if (targetBar && targetBar.ganttBarConfig.pushOnConnect !== false) {
        connectedBars.push(targetBar);
      }
    });
    allBars.forEach((otherBar) => {
      var _a2;
      (_a2 = otherBar.ganttBarConfig.connections) == null ? void 0 : _a2.forEach((conn) => {
        if (conn.targetId === bar.ganttBarConfig.id && otherBar.ganttBarConfig.pushOnConnect !== false) {
          connectedBars.push(otherBar);
        }
      });
    });
    return connectedBars;
  };
  return {
    moveBar,
    findOverlappingBars,
    findConnectedBars,
    getAllBars
  };
}
const useBarDragManagement = () => {
  const config = provideConfig();
  const emitBarEvent = provideEmitBarEvent();
  const dayjs2 = useDayjsHelper(config);
  const { barStart, barEnd } = config;
  const rowManager = inject("useRows");
  const ganttId = inject(GANTT_ID_KEY);
  const movement = useBarMovement(config, rowManager, dayjs2);
  const dragState = {
    movedBars: /* @__PURE__ */ new Map(),
    isDragging: false
  };
  const getBundleBars = (bundle) => {
    const res = [];
    if (bundle != null) {
      const allBars = movement.getAllBars();
      allBars.forEach((bar) => {
        if (bar.ganttBarConfig.bundle === bundle) {
          res.push(bar);
        }
      });
    }
    return res;
  };
  const initDragOfBar = (bar, e) => {
    if (bar.ganttBarConfig.bundle) {
      initDragOfBundle(bar, e);
      return;
    }
    const dragHandler = createDragHandler(bar);
    dragHandler.initiateDrag(e);
    addBarToMovedBars(bar);
    emitBarEvent({ ...e, type: "dragstart" }, bar);
  };
  const initDragOfBundle = (mainBar, e) => {
    const bundle = mainBar.ganttBarConfig.bundle;
    if (!bundle) return;
    const bundleBars = getBundleBars(bundle);
    bundleBars.forEach((bar) => {
      const isMainBar = bar === mainBar;
      const dragHandler = createDragHandler(bar, isMainBar);
      dragHandler.initiateDrag(e);
      addBarToMovedBars(bar);
    });
    emitBarEvent({ ...e, type: "dragstart" }, mainBar);
  };
  const createDragHandler = (bar, isMainBar = true) => ({
    initiateDrag: (e) => {
      const { initDrag } = createBarDrag(
        bar,
        (e2) => handleDrag(e2, bar),
        isMainBar ? handleDragEnd : () => null,
        config,
        movement,
        ganttId
      );
      initDrag(e);
    }
  });
  const handleDrag = (e, bar) => {
    emitBarEvent({ ...e, type: "drag" }, bar);
    const result = movement.moveBar(bar, bar[barStart.value], bar[barEnd.value]);
    if (!result.success) {
      snapBackMovedBars();
    } else {
      result.affectedBars.forEach((affectedBar) => {
        if (!dragState.movedBars.has(affectedBar)) {
          addBarToMovedBars(affectedBar);
        }
      });
    }
  };
  const handleDragEnd = (e, bar) => {
    emitBarEvent({ ...e, type: "dragend" }, bar, void 0, new Map(dragState.movedBars));
    dragState.movedBars.clear();
    dragState.isDragging = false;
  };
  const addBarToMovedBars = (bar) => {
    if (!dragState.movedBars.has(bar)) {
      dragState.movedBars.set(bar, {
        oldStart: bar[barStart.value],
        oldEnd: bar[barEnd.value]
      });
    }
  };
  const snapBackMovedBars = () => {
    dragState.movedBars.forEach(({ oldStart, oldEnd }, bar) => {
      bar[barStart.value] = oldStart;
      bar[barEnd.value] = oldEnd;
    });
  };
  return {
    initDragOfBar,
    initDragOfBundle,
    snapBackMovedBars,
    handleDrag,
    getConnectedBars: movement.findConnectedBars
  };
};
function useBarDragLimit() {
  const { pushOnOverlap, pushOnConnect } = provideConfig();
  const { getConnectedBars } = useBarDragManagement();
  const rowManager = inject("useRows");
  const ganttId = inject(GANTT_ID_KEY);
  const { findBarElement } = useBarSelector();
  const getBarsFromBundle = (bundle) => {
    const res = [];
    if (bundle != null) {
      rowManager.rows.value.forEach((row) => {
        row.bars.forEach((bar) => {
          if (bar.ganttBarConfig.bundle === bundle) {
            res.push(bar);
          }
        });
      });
    }
    return res;
  };
  const setDragLimitsOfGanttBar = (bar) => {
    if (!pushOnOverlap.value || bar.ganttBarConfig.pushOnOverlap === false || !pushOnConnect.value || bar.ganttBarConfig.pushOnConnect === false) {
      return;
    }
    for (const sideValue of ["left", "right"]) {
      const side = sideValue;
      const { gapDistanceSoFar, bundleBarsAndGapDist } = countGapDistanceToNextImmobileBar(
        bar,
        0,
        side
      );
      let totalGapDistance = gapDistanceSoFar;
      const bundleBarsOnPath = bundleBarsAndGapDist;
      if (!bundleBarsOnPath) {
        continue;
      }
      for (let i = 0; i < bundleBarsOnPath.length; i++) {
        const barFromBundle = bundleBarsOnPath[i].bar;
        const gapDist = bundleBarsOnPath[i].gapDistance;
        const otherBarsFromBundle = getBarsFromBundle(barFromBundle.ganttBarConfig.bundle).filter(
          (otherBar) => otherBar !== barFromBundle
        );
        otherBarsFromBundle.forEach((otherBar) => {
          const nextGapDistanceAndBars = countGapDistanceToNextImmobileBar(otherBar, gapDist, side);
          const newGapDistance = nextGapDistanceAndBars.gapDistanceSoFar;
          const newBundleBars = nextGapDistanceAndBars.bundleBarsAndGapDist;
          if (newGapDistance != null && (!totalGapDistance || newGapDistance < totalGapDistance)) {
            totalGapDistance = newGapDistance;
          }
          newBundleBars.forEach((newBundleBar) => {
            if (!bundleBarsOnPath.find((barAndGap) => barAndGap.bar === newBundleBar.bar)) {
              bundleBarsOnPath.push(newBundleBar);
            }
          });
        });
      }
      const barElem = findBarElement(ganttId, bar.ganttBarConfig.id);
      if (totalGapDistance != null && side === "left") {
        bar.ganttBarConfig.dragLimitLeft = barElem.offsetLeft - totalGapDistance;
      } else if (totalGapDistance != null && side === "right") {
        bar.ganttBarConfig.dragLimitRight = barElem.offsetLeft + barElem.offsetWidth + totalGapDistance;
      }
    }
    const barsFromBundleOfClickedBar = getBarsFromBundle(bar.ganttBarConfig.bundle);
    barsFromBundleOfClickedBar.forEach((barFromBundle) => {
      barFromBundle.ganttBarConfig.dragLimitLeft = bar.ganttBarConfig.dragLimitLeft;
      barFromBundle.ganttBarConfig.dragLimitRight = bar.ganttBarConfig.dragLimitRight;
    });
  };
  const countGapDistanceToNextImmobileBar = (bar, gapDistanceSoFar = 0, side) => {
    const bundleBarsAndGapDist = bar.ganttBarConfig.bundle ? [{ bar, gapDistance: gapDistanceSoFar }] : [];
    let currentBar = bar;
    let nextBar = getNextGanttBar(currentBar, side);
    if (side === "left") {
      while (nextBar) {
        const currentBarElem = findBarElement(ganttId, currentBar.ganttBarConfig.id);
        const nextBarElem = findBarElement(ganttId, nextBar.ganttBarConfig.id);
        const nextBarOffsetRight = nextBarElem.offsetLeft + nextBarElem.offsetWidth;
        gapDistanceSoFar += currentBarElem.offsetLeft - nextBarOffsetRight;
        if (nextBar.ganttBarConfig.immobile) {
          return { gapDistanceSoFar, bundleBarsAndGapDist };
        } else if (nextBar.ganttBarConfig.bundle) {
          bundleBarsAndGapDist.push({
            bar: nextBar,
            gapDistance: gapDistanceSoFar
          });
        }
        currentBar = nextBar;
        nextBar = getNextGanttBar(nextBar, "left");
      }
    }
    if (side === "right") {
      while (nextBar) {
        const currentBarElem = findBarElement(ganttId, currentBar.ganttBarConfig.id);
        const nextBarElem = findBarElement(ganttId, nextBar.ganttBarConfig.id);
        const currentBarOffsetRight = currentBarElem.offsetLeft + currentBarElem.offsetWidth;
        gapDistanceSoFar += nextBarElem.offsetLeft - currentBarOffsetRight;
        if (nextBar.ganttBarConfig.immobile) {
          return { gapDistanceSoFar, bundleBarsAndGapDist };
        } else if (nextBar.ganttBarConfig.bundle) {
          bundleBarsAndGapDist.push({
            bar: nextBar,
            gapDistance: gapDistanceSoFar
          });
        }
        currentBar = nextBar;
        nextBar = getNextGanttBar(nextBar, "right");
      }
    }
    return { gapDistanceSoFar: null, bundleBarsAndGapDist };
  };
  const getNextGanttBar = (bar, side) => {
    var _a;
    const barElem = findBarElement(ganttId, bar.ganttBarConfig.id);
    let allBarsInRow = [];
    if (pushOnOverlap.value) {
      allBarsInRow = ((_a = rowManager.rows.value.find((row) => row.bars.includes(bar))) == null ? void 0 : _a.bars) || [];
    }
    if (pushOnConnect.value) {
      allBarsInRow = [...allBarsInRow, ...getConnectedBars(bar)];
    }
    let allBarsLeftOrRight = [];
    if (side === "left") {
      allBarsLeftOrRight = allBarsInRow.filter((otherBar) => {
        const otherBarElem = findBarElement(ganttId, otherBar.ganttBarConfig.id);
        return otherBarElem && otherBarElem.offsetLeft < barElem.offsetLeft && otherBar.ganttBarConfig.pushOnOverlap !== false && otherBar.ganttBarConfig.pushOnConnect !== false;
      });
    } else {
      allBarsLeftOrRight = allBarsInRow.filter((otherBar) => {
        const otherBarElem = findBarElement(ganttId, otherBar.ganttBarConfig.id);
        return otherBarElem && otherBarElem.offsetLeft > barElem.offsetLeft && otherBar.ganttBarConfig.pushOnOverlap !== false && otherBar.ganttBarConfig.pushOnConnect !== false;
      });
    }
    if (allBarsLeftOrRight.length > 0) {
      return allBarsLeftOrRight.reduce((bar1, bar2) => {
        const bar1Elem = findBarElement(ganttId, bar1.ganttBarConfig.id);
        const bar2Elem = findBarElement(ganttId, bar2.ganttBarConfig.id);
        const bar1Dist = Math.abs(bar1Elem.offsetLeft - barElem.offsetLeft);
        const bar2Dist = Math.abs(bar2Elem.offsetLeft - barElem.offsetLeft);
        return bar1Dist < bar2Dist ? bar1 : bar2;
      }, allBarsLeftOrRight[0]);
    } else {
      return null;
    }
  };
  return {
    setDragLimitsOfGanttBar
  };
}
function useBarKeyboardControl(bar, config, emitBarEvent) {
  const dayjs2 = useDayjsHelper(config);
  const { barStart, barEnd, dateFormat, precision } = config;
  const rowManager = inject("useRows");
  const movement = useBarMovement(config, rowManager, dayjs2);
  const TIME_STEP = {
    hour: 5,
    day: 120,
    week: 840,
    month: 3600
  };
  const getTimeStep = (isShiftPressed) => {
    const baseStep = TIME_STEP[precision.value] || TIME_STEP.hour;
    return isShiftPressed ? baseStep * 12 : baseStep;
  };
  const moveBarPosition = (direction, isShiftPressed) => {
    const multiplier = direction === "forward" ? 1 : -1;
    const minutesToMove = getTimeStep(isShiftPressed);
    const currentStart = dayjs2.toDayjs(bar[barStart.value]);
    const currentEnd = dayjs2.toDayjs(bar[barEnd.value]);
    const newStart = currentStart.add(minutesToMove * multiplier, "minutes");
    const newEnd = currentEnd.add(minutesToMove * multiplier, "minutes");
    if (newStart.isBefore(config.chartStart.value) || newEnd.isAfter(config.chartEnd.value)) {
      return;
    }
    const newStartStr = dayjs2.format(newStart, dateFormat.value);
    const newEndStr = dayjs2.format(newEnd, dateFormat.value);
    const result = movement.moveBar(bar, newStartStr, newEndStr);
    if (result.success) {
      emitDragEvents();
    }
  };
  const resizeBar = (type, isShiftPressed) => {
    const currentStart = dayjs2.toDayjs(bar[barStart.value]);
    const currentEnd = dayjs2.toDayjs(bar[barEnd.value]);
    let minutesToMove = getTimeStep(isShiftPressed);
    if (minutesToMove === 5) {
      minutesToMove = 10;
    }
    const timePerSide = minutesToMove / 2;
    let newStart;
    let newEnd;
    if (type === "expand") {
      newStart = dayjs2.format(
        currentStart.subtract(timePerSide, "minutes"),
        dateFormat.value
      );
      newEnd = dayjs2.format(currentEnd.add(timePerSide, "minutes"), dateFormat.value);
    } else {
      const currentDuration = currentEnd.diff(currentStart, "minutes");
      if (currentDuration <= minutesToMove) {
        return;
      }
      newStart = dayjs2.format(currentStart.add(timePerSide, "minutes"), dateFormat.value);
      newEnd = dayjs2.format(currentEnd.subtract(timePerSide, "minutes"), dateFormat.value);
    }
    const startDayjs = dayjs2.toDayjs(newStart);
    const endDayjs = dayjs2.toDayjs(newEnd);
    if (startDayjs.isBefore(config.chartStart.value) || endDayjs.isAfter(config.chartEnd.value)) {
      return;
    }
    const result = movement.moveBar(bar, newStart, newEnd);
    if (result.success) {
      emitDragEvents();
    }
  };
  const emitDragEvents = () => {
    const mockEvent = new MouseEvent("drag", { bubbles: true });
    emitBarEvent(mockEvent, bar);
    const mockEndEvent = new MouseEvent("dragend", { bubbles: true });
    emitBarEvent(mockEndEvent, bar);
  };
  const onBarKeyDown = (event) => {
    const target = event.target;
    if (!target.id || target.id !== bar.ganttBarConfig.id || bar.ganttBarConfig.immobile) {
      return;
    }
    switch (event.key) {
      case "ArrowLeft":
        event.preventDefault();
        moveBarPosition("backward", event.shiftKey);
        break;
      case "ArrowRight":
        event.preventDefault();
        moveBarPosition("forward", event.shiftKey);
        break;
      case "ArrowUp":
        event.preventDefault();
        resizeBar("expand", event.shiftKey);
        break;
      case "ArrowDown":
        event.preventDefault();
        resizeBar("shrink", event.shiftKey);
        break;
    }
  };
  return {
    onBarKeyDown
  };
}
function useTouchEvents(initDragCallback, threshold = 5) {
  const touchState = ref({
    isDragging: false,
    startX: 0,
    startY: 0,
    lastX: 0,
    lastY: 0,
    currentBar: null,
    dragTarget: null
  });
  const resetTouchState = () => {
    touchState.value = {
      isDragging: false,
      startX: 0,
      startY: 0,
      lastX: 0,
      lastY: 0,
      currentBar: null,
      dragTarget: null
    };
  };
  const determineDragTarget = (element) => {
    if (element.classList.contains("g-gantt-bar-handle-left")) {
      return "leftHandle";
    }
    if (element.classList.contains("g-gantt-bar-handle-right")) {
      return "rightHandle";
    }
    if (element.classList.contains("g-gantt-bar")) {
      return "bar";
    }
    const barElement = element.closest(".g-gantt-bar");
    if (barElement) {
      return "bar";
    }
    return null;
  };
  const createMouseEventFromTouch = (touch, eventType, movementX = 0, movementY = 0) => {
    const mouseEvent = new MouseEvent(eventType, {
      bubbles: true,
      cancelable: true,
      clientX: touch.clientX,
      clientY: touch.clientY,
      movementX,
      movementY,
      view: window
    });
    if (touchState.value.currentBar) {
      const targetElement = document.querySelector(
        `#${touchState.value.currentBar.ganttBarConfig.id}`
      );
      if (targetElement) {
        Object.defineProperty(mouseEvent, "target", { value: targetElement });
      }
    }
    return mouseEvent;
  };
  const handleTouchStart = (event, bar) => {
    const touch = event.touches[0];
    if (!touch || !bar) return;
    const targetElement = event.target;
    if (!targetElement) return;
    const dragTarget = determineDragTarget(targetElement);
    if (!dragTarget) return;
    event.preventDefault();
    touchState.value = {
      isDragging: false,
      startX: touch.clientX,
      startY: touch.clientY,
      lastX: touch.clientX,
      lastY: touch.clientY,
      currentBar: bar,
      dragTarget
    };
    const mouseEvent = createMouseEventFromTouch(touch, "mousedown");
    initDragCallback(bar, mouseEvent);
  };
  const handleTouchMove = (event) => {
    const touch = event.touches[0];
    if (!touch || !touchState.value.currentBar) return;
    const deltaX = Math.abs(touch.clientX - touchState.value.startX);
    const deltaY = Math.abs(touch.clientY - touchState.value.startY);
    if (!touchState.value.isDragging && (deltaX > threshold || deltaY > threshold)) {
      touchState.value.isDragging = true;
    }
    if (touchState.value.isDragging) {
      event.preventDefault();
      const movementX = touch.clientX - touchState.value.lastX;
      const movementY = touch.clientY - touchState.value.lastY;
      touchState.value.lastX = touch.clientX;
      touchState.value.lastY = touch.clientY;
      const mouseEvent = createMouseEventFromTouch(touch, "mousemove", movementX, movementY);
      window.dispatchEvent(mouseEvent);
    }
  };
  const handleTouchEnd = (event) => {
    const touch = event.changedTouches[0];
    if (!touch || !touchState.value.currentBar) return;
    if (touchState.value.isDragging) {
      event.preventDefault();
      const mouseEvent = createMouseEventFromTouch(touch, "mouseup");
      window.dispatchEvent(mouseEvent);
    }
    resetTouchState();
  };
  const handleTouchCancel = handleTouchEnd;
  return {
    handleTouchStart,
    handleTouchMove,
    handleTouchEnd,
    handleTouchCancel
  };
}
const _hoisted_1$4 = ["id", "aria-label", "aria-grabbed", "aria-describedby"];
const _hoisted_2$2 = {
  key: 0,
  class: "progress-text"
};
const _hoisted_3$2 = ["width", "height"];
const _hoisted_4$2 = ["d", "fill"];
const _hoisted_5$2 = {
  key: 3,
  class: "g-gantt-bar-label"
};
const _hoisted_6$2 = { key: 0 };
const _hoisted_7$2 = {
  key: 0,
  class: "g-gantt-bar-label-edit"
};
const _hoisted_8$2 = { key: 1 };
const _hoisted_9$2 = ["innerHTML"];
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
  __name: "GGanttBar",
  props: {
    bar: {}
  },
  setup(__props) {
    const props = __props;
    const ganttId = inject(GANTT_ID_KEY);
    const connectionCreation = inject("connectionCreation");
    const emitBarEvent = provideEmitBarEvent();
    const config = provideConfig();
    const { rowHeight } = config;
    const { bar } = toRefs(props);
    const { mapTimeToPosition, mapPositionToTime } = useTimePositionMapping();
    const { initDragOfBar, initDragOfBundle } = useBarDragManagement();
    const { setDragLimitsOfGanttBar } = useBarDragLimit();
    const isDragging = ref(false);
    const isEditing = ref(false);
    const editedLabel = ref("");
    const labelInput = ref(null);
    const {
      barStart,
      barEnd,
      width,
      chartStart,
      chartEnd,
      chartSize,
      showLabel,
      showProgress,
      defaultProgressResizable,
      enableConnectionCreation,
      barLabelEditable
    } = config;
    const xStart = ref(0);
    const xEnd = ref(0);
    const barConfig = computed(() => bar.value.ganttBarConfig);
    const isGroupBar = computed(() => {
      return bar.value.ganttBarConfig.id.startsWith("group-");
    });
    const progressStyle = computed(() => {
      var _a;
      const progress = props.bar.ganttBarConfig.progress ?? 0;
      const baseStyle = props.bar.ganttBarConfig.progressStyle || {};
      const barColor = ((_a = props.bar.ganttBarConfig.style) == null ? void 0 : _a.background) || "#5F9EA0";
      return {
        ...baseStyle,
        left: 0,
        width: `${Math.min(Math.max(progress, 0), 100)}%`,
        backgroundColor: baseStyle.backgroundColor || getDarkerColor(barColor),
        transition: "width 0.3s ease",
        borderRadius: "inherit",
        height: "100%"
      };
    });
    const connectionPointStyle = computed(() => ({
      width: "12px",
      height: "12px",
      borderRadius: "50%",
      cursor: "pointer",
      background: canBeTarget.value ? "#00ff00" : "#ff0000",
      transition: "all 0.2s ease",
      opacity: (connectionCreation == null ? void 0 : connectionCreation.connectionState.value.isCreating) || isBarHovered.value || startPointHover.value || endPointHover.value ? 1 : 0,
      zIndex: 1e3
    }));
    const startPointStyle = computed(() => ({
      ...connectionPointStyle.value,
      left: 0,
      top: "50%",
      transform: "translate(-50%, -50%)"
    }));
    const endPointStyle = computed(() => ({
      ...connectionPointStyle.value,
      right: 0,
      top: "50%",
      transform: "translate(50%, -50%)"
    }));
    const canBeTarget = computed(() => {
      if (!(connectionCreation == null ? void 0 : connectionCreation.connectionState.value.isCreating)) return false;
      return connectionCreation.canBeConnectionTarget.value(props.bar);
    });
    const firstMousemoveCallback = (e) => {
      if (barConfig.value.bundle != null) {
        initDragOfBundle(bar.value, e);
      } else {
        initDragOfBar(bar.value, e);
      }
      isDragging.value = true;
    };
    const prepareForDrag = () => {
      setDragLimitsOfGanttBar(bar.value);
      if (barConfig.value.immobile) {
        return;
      }
      window.addEventListener("mousemove", firstMousemoveCallback, {
        once: true
      });
      window.addEventListener(
        "mouseup",
        () => {
          window.removeEventListener("mousemove", firstMousemoveCallback);
          isDragging.value = false;
        },
        { once: true }
      );
    };
    const onMouseEvent = (e) => {
      var _a;
      e.preventDefault();
      if (e.type === "mousedown") {
        prepareForDrag();
      }
      const barContainer = (_a = barContainerEl == null ? void 0 : barContainerEl.value) == null ? void 0 : _a.getBoundingClientRect();
      if (!barContainer) {
        return;
      }
      const datetime = mapPositionToTime(e.clientX - barContainer.left);
      emitBarEvent(e, bar.value, datetime);
    };
    const barContainerEl = inject(BAR_CONTAINER_KEY);
    const { handleTouchStart, handleTouchMove, handleTouchEnd, handleTouchCancel } = useTouchEvents(
      (_draggedBar, e) => {
        firstMousemoveCallback(e);
        isDragging.value = true;
      }
    );
    const onTouchEvent = (e) => {
      if (bar.value.ganttBarConfig.immobile) return;
      let mouseEvent;
      switch (e.type) {
        case "touchstart":
          mouseEvent = handleTouchStart(e, bar.value);
          break;
        case "touchmove":
          mouseEvent = handleTouchMove(e);
          break;
        case "touchend":
          mouseEvent = handleTouchEnd(e);
          break;
        case "touchcancel":
          mouseEvent = handleTouchCancel(e);
          break;
      }
      if (mouseEvent) {
        onMouseEvent(mouseEvent);
      }
    };
    const isProgressDragging = ref(false);
    const progressDragStart = ref(0);
    const initialProgress = ref(0);
    const handleProgressDragStart = (e) => {
      if (!props.bar.ganttBarConfig.progressResizable && !defaultProgressResizable.value) return;
      e.stopPropagation();
      isProgressDragging.value = true;
      progressDragStart.value = e.clientX;
      initialProgress.value = props.bar.ganttBarConfig.progress ?? 0;
      window.addEventListener("mousemove", handleProgressDrag);
      window.addEventListener("mouseup", handleProgressDragEnd);
      emitBarEvent(
        {
          ...e,
          type: "progress-drag-start"
        },
        props.bar
      );
    };
    const { findBarElement } = useBarSelector();
    const handleProgressDrag = (e) => {
      if (!isProgressDragging.value) return;
      const barElement = findBarElement(ganttId, props.bar.ganttBarConfig.id);
      if (!barElement) return;
      const rect = barElement.getBoundingClientRect();
      const deltaX = e.clientX - progressDragStart.value;
      const percentageDelta = deltaX / rect.width * 100;
      const newProgress = Math.min(Math.max(initialProgress.value + percentageDelta, 0), 100);
      bar.value.ganttBarConfig.progress = Math.round(newProgress);
      emitBarEvent(
        {
          ...e,
          type: "progress-change"
        },
        props.bar
      );
    };
    const handleProgressDragEnd = (e) => {
      if (!isProgressDragging.value) return;
      isProgressDragging.value = false;
      window.removeEventListener("mousemove", handleProgressDrag);
      window.removeEventListener("mouseup", handleProgressDragEnd);
      emitBarEvent(
        {
          ...e,
          type: "progress-drag-end"
        },
        props.bar
      );
    };
    const startPointHover = ref(false);
    const endPointHover = ref(false);
    const isBarHovered = ref(false);
    const handleConnectionPointMouseEnter = (point) => {
      if (!enableConnectionCreation.value) return;
      if (point === "start") {
        startPointHover.value = true;
      } else {
        endPointHover.value = true;
      }
      connectionCreation == null ? void 0 : connectionCreation.handleConnectionPointHover(props.bar.ganttBarConfig.id, point, true);
    };
    const handleConnectionPointMouseLeave = (point) => {
      if (!enableConnectionCreation.value) return;
      if (point === "start") {
        startPointHover.value = false;
      } else {
        endPointHover.value = false;
      }
      connectionCreation == null ? void 0 : connectionCreation.handleConnectionPointHover(props.bar.ganttBarConfig.id, point, false);
    };
    const handleConnectionPointMouseDown = (e, point) => {
      if (!enableConnectionCreation.value) return;
      e.stopPropagation();
      connectionCreation == null ? void 0 : connectionCreation.startConnectionCreation(props.bar, point, e);
    };
    const handleConnectionDrop = (e, point) => {
      if (!enableConnectionCreation.value) return;
      e.stopPropagation();
      connectionCreation == null ? void 0 : connectionCreation.completeConnection(props.bar, point, e);
    };
    const handleBarMouseEnter = (e) => {
      isBarHovered.value = true;
      onMouseEvent(e);
    };
    const handleBarMouseLeave = (e) => {
      isBarHovered.value = false;
      onMouseEvent(e);
    };
    const startEditing = (e) => {
      if (!barLabelEditable.value || isGroupBar.value) return;
      e.stopPropagation();
      bar.value.ganttBarConfig._previousLabel = barConfig.value.label || "";
      isEditing.value = true;
      editedLabel.value = barConfig.value.label || "";
      setTimeout(() => {
        if (labelInput.value) {
          labelInput.value.focus();
          labelInput.value.select();
        }
      }, 0);
    };
    const saveLabel = () => {
      if (!isEditing.value) return;
      bar.value.ganttBarConfig.label = editedLabel.value;
      emitBarEvent(
        {
          type: "label-edit",
          preventDefault: () => {
          },
          stopPropagation: () => {
          }
        },
        bar.value
      );
      isEditing.value = false;
    };
    const cancelEditing = () => {
      isEditing.value = false;
    };
    const handleLabelKeydown = (e) => {
      if (e.key === "Enter") {
        saveLabel();
      } else if (e.key === "Escape") {
        cancelEditing();
      }
    };
    const handleInputBlur = () => {
      saveLabel();
    };
    const getDarkerColor = (color) => {
      const rgb = color.startsWith("#") ? hexToRgb(color) : parseRgb(color);
      return `rgba(${Math.max(0, rgb.r - 40)}, ${Math.max(0, rgb.g - 40)}, ${Math.max(0, rgb.b - 40)}, ${rgb.a})`;
    };
    const hexToRgb = (hex) => {
      const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
      return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16),
        a: 1
      } : { r: 0, g: 0, b: 0, a: 1 };
    };
    const parseRgb = (color) => {
      const matches = color.match(/(\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?/);
      if (matches) {
        return {
          r: parseInt(matches[1]),
          g: parseInt(matches[2]),
          b: parseInt(matches[3]),
          a: matches[4] ? parseFloat(matches[4]) : 1
        };
      }
      return { r: 0, g: 0, b: 0, a: 1 };
    };
    const getGroupBarPath = (width2, height) => {
      const mainBarHeight = height * 0.5;
      return `
    M 0 0
    L 0 ${height}
    L ${15} ${mainBarHeight}
    L ${width2 - 15} ${mainBarHeight}
    L ${width2} ${height}
    L ${width2} 0
    L 0 0
  `;
    };
    const { onBarKeyDown } = useBarKeyboardControl(bar.value, config, emitBarEvent);
    onMounted(() => {
      xStart.value = mapTimeToPosition(bar.value[barStart.value]);
      xEnd.value = mapTimeToPosition(bar.value[barEnd.value]);
      watch(
        [() => bar.value, width, chartStart, chartEnd, chartSize.width],
        () => {
          const newXStart = mapTimeToPosition(bar.value[barStart.value]);
          const newXEnd = mapTimeToPosition(bar.value[barEnd.value]);
          xStart.value = newXStart;
          xEnd.value = newXEnd;
        },
        { deep: true, immediate: true }
      );
    });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        id: barConfig.value.id,
        class: normalizeClass(["g-gantt-bar", barConfig.value.class || ""]),
        style: normalizeStyle({
          ...barConfig.value.style,
          position: "absolute",
          top: `${unref(rowHeight) * 0.15}px`,
          left: `${xStart.value}px`,
          width: `${xEnd.value - xStart.value}px`,
          height: `${unref(rowHeight) * 0.7}px`,
          zIndex: isDragging.value ? 3 : 2,
          cursor: unref(bar).ganttBarConfig.immobile ? "" : "grab"
        }),
        onMousedown: onMouseEvent,
        onClick: onMouseEvent,
        onMouseenter: handleBarMouseEnter,
        onMouseleave: handleBarMouseLeave,
        onContextmenu: onMouseEvent,
        onTouchstart: onTouchEvent,
        onTouchmove: onTouchEvent,
        onTouchend: onTouchEvent,
        onTouchcancel: onTouchEvent,
        onKeydown: _cache[9] || (_cache[9] = //@ts-ignore
        (...args) => unref(onBarKeyDown) && unref(onBarKeyDown)(...args)),
        onDblclick: startEditing,
        role: "listitem",
        "aria-label": `Activity ${barConfig.value.label}`,
        "aria-grabbed": isDragging.value,
        tabindex: "0",
        "aria-describedby": `tooltip-${barConfig.value.id}`
      }, [
        unref(enableConnectionCreation) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
          createElementVNode("div", {
            class: "connection-point start",
            style: normalizeStyle([startPointStyle.value, { position: "absolute" }]),
            onMouseenter: _cache[0] || (_cache[0] = ($event) => handleConnectionPointMouseEnter("start")),
            onMouseleave: _cache[1] || (_cache[1] = ($event) => handleConnectionPointMouseLeave("start")),
            onMousedown: _cache[2] || (_cache[2] = ($event) => handleConnectionPointMouseDown($event, "start")),
            onMouseup: _cache[3] || (_cache[3] = ($event) => handleConnectionDrop($event, "start"))
          }, null, 36),
          createElementVNode("div", {
            class: "connection-point end",
            style: normalizeStyle([endPointStyle.value, { position: "absolute" }]),
            onMouseenter: _cache[4] || (_cache[4] = ($event) => handleConnectionPointMouseEnter("end")),
            onMouseleave: _cache[5] || (_cache[5] = ($event) => handleConnectionPointMouseLeave("end")),
            onMousedown: _cache[6] || (_cache[6] = ($event) => handleConnectionPointMouseDown($event, "end")),
            onMouseup: _cache[7] || (_cache[7] = ($event) => handleConnectionDrop($event, "end"))
          }, null, 36)
        ], 64)) : createCommentVNode("", true),
        barConfig.value.progress !== void 0 ? (openBlock(), createElementBlock("div", {
          key: 1,
          class: "g-gantt-progress-bar",
          style: normalizeStyle(progressStyle.value)
        }, [
          unref(showProgress) ? (openBlock(), createElementBlock("span", _hoisted_2$2, toDisplayString(Math.round(barConfig.value.progress)) + "%", 1)) : createCommentVNode("", true),
          barConfig.value.progressResizable || unref(defaultProgressResizable) ? (openBlock(), createElementBlock("div", {
            key: 1,
            class: "g-gantt-progress-handle",
            style: normalizeStyle({ right: unref(bar).ganttBarConfig.progress === 0 ? 0 : "-4px" }),
            onMousedown: handleProgressDragStart
          }, null, 36)) : createCommentVNode("", true)
        ], 4)) : createCommentVNode("", true),
        isGroupBar.value ? renderSlot(_ctx.$slots, "group-bar", {
          key: 2,
          width: xEnd.value - xStart.value,
          height: unref(rowHeight) * 0.7,
          bar: unref(bar)
        }, () => [
          (openBlock(), createElementBlock("svg", {
            class: "group-bar-decoration",
            width: xEnd.value - xStart.value,
            height: unref(rowHeight) * 0.7
          }, [
            createElementVNode("path", {
              d: getGroupBarPath(xEnd.value - xStart.value, unref(rowHeight) * 0.65),
              fill: unref(config).colors.value.barContainer
            }, null, 8, _hoisted_4$2)
          ], 8, _hoisted_3$2))
        ]) : (openBlock(), createElementBlock("div", _hoisted_5$2, [
          renderSlot(_ctx.$slots, "bar-label", { bar: unref(bar) }, () => [
            !isGroupBar.value && unref(showLabel) ? (openBlock(), createElementBlock("div", _hoisted_6$2, [
              isEditing.value && unref(barLabelEditable) ? (openBlock(), createElementBlock("div", _hoisted_7$2, [
                withDirectives(createElementVNode("input", {
                  ref_key: "labelInput",
                  ref: labelInput,
                  "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => editedLabel.value = $event),
                  onKeydown: handleLabelKeydown,
                  onBlur: handleInputBlur,
                  class: "g-gantt-bar-label-input"
                }, null, 544), [
                  [vModelText, editedLabel.value]
                ])
              ])) : (openBlock(), createElementBlock("div", _hoisted_8$2, toDisplayString(barConfig.value.label || ""), 1))
            ])) : createCommentVNode("", true),
            barConfig.value.html ? (openBlock(), createElementBlock("div", {
              key: 1,
              innerHTML: barConfig.value.html
            }, null, 8, _hoisted_9$2)) : createCommentVNode("", true)
          ])
        ])),
        barConfig.value.hasHandles ? (openBlock(), createElementBlock(Fragment, { key: 4 }, [
          _cache[10] || (_cache[10] = createElementVNode("div", { class: "g-gantt-bar-handle-left" }, null, -1)),
          _cache[11] || (_cache[11] = createElementVNode("div", { class: "g-gantt-bar-handle-right" }, null, -1))
        ], 64)) : createCommentVNode("", true)
      ], 46, _hoisted_1$4);
    };
  }
});
const _hoisted_1$3 = {
  key: 0,
  class: "g-gantt-row-children"
};
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
  __name: "GGanttRow",
  props: {
    label: {},
    bars: {},
    highlightOnHover: { type: Boolean },
    id: {},
    children: {},
    connections: {}
  },
  emits: ["drop", "range-selection"],
  setup(__props, { emit: __emit }) {
    const props = __props;
    const emit = __emit;
    const rowManager = inject("useRows");
    const { rowHeight, colors, labelColumnTitle, rowClass } = provideConfig();
    const { highlightOnHover } = toRefs(props);
    const barContainer = ref(null);
    const isHovering = ref(false);
    const isSelecting = ref(false);
    const selectionStartX = ref(0);
    const selectionEndX = ref(0);
    const selectionVisible = ref(false);
    const isGroup = computed(() => {
      var _a;
      return Boolean((_a = props.children) == null ? void 0 : _a.length);
    });
    const isExpanded = computed(() => {
      if (!isGroup.value || !props.id) return false;
      return rowManager.isGroupExpanded(props.id);
    });
    const rowStyle = computed(() => {
      const baseStyle = {
        height: `${rowHeight.value}px`,
        borderBottom: `1px solid ${colors.value.gridAndBorder}`,
        background: (highlightOnHover == null ? void 0 : highlightOnHover.value) && isHovering.value ? colors.value.hoverHighlight : void 0
      };
      if (isGroup.value) {
        return {
          ...baseStyle,
          background: (highlightOnHover == null ? void 0 : highlightOnHover.value) && isHovering.value ? colors.value.hoverHighlight : void 0
        };
      }
      return baseStyle;
    });
    const rowClasses = computed(() => {
      const classes = ["g-gantt-row"];
      if (rowClass.value && props) {
        classes.push(rowClass.value(props));
      }
      if (isGroup.value) {
        classes.push("g-gantt-row-group");
      }
      return classes;
    });
    const visibleChildRows = computed(() => {
      if (!isGroup.value || !isExpanded.value) return [];
      return props.children || [];
    });
    const selectionStyle = computed(() => {
      if (!selectionVisible.value) return { display: "none" };
      const left = Math.min(selectionStartX.value, selectionEndX.value);
      const width = Math.abs(selectionEndX.value - selectionStartX.value);
      return {
        position: "absolute",
        left: `${left}px`,
        width: `${width}px`,
        height: `${rowHeight.value - 4}px`,
        background: colors.value.rangeHighlight,
        opacity: 0.6,
        pointerEvents: "none",
        zIndex: 1,
        margin: "auto 0",
        top: "1px"
      };
    });
    const { mapPositionToTime } = useTimePositionMapping();
    const isBlank = (str) => {
      return !str || /^\s*$/.test(str);
    };
    const onDrop = (e) => {
      var _a;
      if (isGroup.value) return;
      const container = (_a = barContainer.value) == null ? void 0 : _a.getBoundingClientRect();
      if (!container) {
        console.error("Hyper Vue Gantt: failed to find bar container element for row.");
        return;
      }
      const xPos = e.clientX - container.left;
      const datetime = mapPositionToTime(xPos);
      emit("drop", { e, datetime });
    };
    const handleGroupToggle = (event) => {
      event.stopPropagation();
      if (props.id) {
        rowManager.toggleGroupExpansion(props.id);
      }
    };
    const handleSelectionStart = (e) => {
      var _a;
      if (isGroup.value) return;
      const target = e.target;
      if (target.closest(".g-gantt-bar")) return;
      const container = (_a = barContainer.value) == null ? void 0 : _a.getBoundingClientRect();
      if (!container) return;
      const xPos = e.clientX - container.left;
      isSelecting.value = true;
      selectionStartX.value = xPos;
      selectionEndX.value = xPos;
      selectionVisible.value = false;
      e.preventDefault();
      document.addEventListener("mousemove", handleSelectionMove);
      document.addEventListener("mouseup", handleSelectionEnd);
    };
    const handleSelectionMove = (e) => {
      if (!isSelecting.value || !barContainer.value) return;
      const container = barContainer.value.getBoundingClientRect();
      const xPos = Math.max(0, e.clientX - container.left);
      selectionEndX.value = xPos;
      selectionVisible.value = Math.abs(selectionEndX.value - selectionStartX.value) > 5;
    };
    const handleSelectionEnd = (e) => {
      document.removeEventListener("mousemove", handleSelectionMove);
      document.removeEventListener("mouseup", handleSelectionEnd);
      if (!isSelecting.value || !selectionVisible.value) {
        resetSelection();
        return;
      }
      const startTime = mapPositionToTime(Math.min(selectionStartX.value, selectionEndX.value));
      const endTime = mapPositionToTime(Math.max(selectionStartX.value, selectionEndX.value));
      const rowData = {
        id: props.id,
        label: props.label,
        bars: props.bars,
        children: props.children,
        connections: props.connections
      };
      emit("range-selection", {
        row: rowData,
        startDate: startTime,
        endDate: endTime,
        e
      });
      resetSelection();
    };
    const resetSelection = () => {
      isSelecting.value = false;
      selectionVisible.value = false;
      selectionStartX.value = 0;
      selectionEndX.value = 0;
    };
    provide(BAR_CONTAINER_KEY, barContainer);
    return (_ctx, _cache) => {
      const _component_g_gantt_row = resolveComponent("g-gantt-row", true);
      return openBlock(), createElementBlock(Fragment, null, [
        createElementVNode("div", {
          class: normalizeClass(rowClasses.value),
          style: normalizeStyle(rowStyle.value),
          onDragover: _cache[2] || (_cache[2] = withModifiers(($event) => isHovering.value = true, ["prevent"])),
          onDragleave: _cache[3] || (_cache[3] = ($event) => isHovering.value = false),
          onDrop: _cache[4] || (_cache[4] = ($event) => onDrop($event)),
          onMouseover: _cache[5] || (_cache[5] = ($event) => isHovering.value = true),
          onMouseleave: _cache[6] || (_cache[6] = ($event) => isHovering.value = false),
          role: "list",
          onMousedown: handleSelectionStart
        }, [
          !isBlank(_ctx.label) && !unref(labelColumnTitle) ? (openBlock(), createElementBlock("div", {
            key: 0,
            class: normalizeClass(["g-gantt-row-label", { "g-gantt-row-group-label": isGroup.value }]),
            style: normalizeStyle({ background: unref(colors).primary, color: unref(colors).text }),
            onClick: _cache[1] || (_cache[1] = ($event) => isGroup.value ? handleGroupToggle($event) : void 0)
          }, [
            isGroup.value ? (openBlock(), createElementBlock("button", {
              key: 0,
              class: "group-toggle-button",
              onClick: _cache[0] || (_cache[0] = ($event) => handleGroupToggle($event))
            }, [
              createVNode(unref(FontAwesomeIcon), {
                icon: isExpanded.value ? unref(faChevronDown) : unref(faChevronRight),
                class: "group-icon"
              }, null, 8, ["icon"])
            ])) : createCommentVNode("", true),
            renderSlot(_ctx.$slots, "label", {}, () => [
              createTextVNode(toDisplayString(_ctx.label), 1)
            ])
          ], 6)) : createCommentVNode("", true),
          createElementVNode("div", mergeProps({
            ref_key: "barContainer",
            ref: barContainer,
            class: "g-gantt-row-bars-container"
          }, _ctx.$attrs), [
            selectionVisible.value ? (openBlock(), createElementBlock("div", {
              key: 0,
              class: "g-gantt-range-selection",
              style: normalizeStyle(selectionStyle.value)
            }, null, 4)) : createCommentVNode("", true),
            createVNode(TransitionGroup, {
              name: "bar-transition",
              tag: "div"
            }, {
              default: withCtx(() => [
                (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.bars, (bar) => {
                  return openBlock(), createBlock(_sfc_main$4, {
                    key: bar.ganttBarConfig.id,
                    bar,
                    class: normalizeClass({ "g-gantt-group-bar": isGroup.value })
                  }, createSlots({ _: 2 }, [
                    renderList(_ctx.$slots, (_, name) => {
                      return {
                        name,
                        fn: withCtx((slotProps) => [
                          renderSlot(_ctx.$slots, name, mergeProps({ ref_for: true }, slotProps))
                        ])
                      };
                    })
                  ]), 1032, ["bar", "class"]);
                }), 128))
              ]),
              _: 3
            })
          ], 16)
        ], 38),
        isGroup.value && isExpanded.value ? (openBlock(), createElementBlock("div", _hoisted_1$3, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(visibleChildRows.value, (child) => {
            return openBlock(), createBlock(_component_g_gantt_row, mergeProps({
              key: child.id || child.label,
              ref_for: true
            }, child, {
              highlightOnHover: unref(highlightOnHover),
              onRangeSelection: _cache[7] || (_cache[7] = (event) => _ctx.$emit("range-selection", event))
            }), createSlots({ _: 2 }, [
              renderList(_ctx.$slots, (_, name) => {
                return {
                  name,
                  fn: withCtx((slotProps) => [
                    renderSlot(_ctx.$slots, name, mergeProps({ ref_for: true }, slotProps))
                  ])
                };
              })
            ]), 1040, ["highlightOnHover"]);
          }), 128))
        ])) : createCommentVNode("", true)
      ], 64);
    };
  }
});
const _hoisted_1$2 = { style: { "font-weight": "bold" } };
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
  __name: "GGanttPointerMarker",
  setup(__props) {
    const chartAreaEl = inject(CHART_AREA_KEY);
    const chartWrapperEl = inject(CHART_WRAPPER_KEY);
    const hitBars = ref([]);
    const tooltipContainer = useTemplateRef("tooltip");
    const { colors, barStart, barEnd } = provideConfig();
    const { mapPositionToTime } = useTimePositionMapping();
    const rowManager = inject("useRows");
    const { toDayjs } = useDayjsHelper();
    const { elementX } = useMouseInElement(chartAreaEl);
    const { isOutside, x } = useMouseInElement(chartWrapperEl);
    const { width, height } = useElementBounding(tooltipContainer);
    const { top, bottom } = useElementBounding(chartWrapperEl);
    const leftOffset = computed((prev) => isOutside.value ? prev ?? 0 : elementX.value);
    const datetime = computed(() => mapPositionToTime(leftOffset.value));
    const bars = computedWithControl(rowManager.getFlattenedRows, () => rowManager.getFlattenedRows().flatMap((row) => row.bars));
    const tooltipStylePosition = computed(() => {
      if (top.value - height.value > 0) {
        return {
          top: `${top.value}px`,
          transform: `translateY(-100%)`,
          left: `${x.value - width.value / 2}px`
        };
      }
      return {
        top: `${bottom.value}px`,
        left: `${x.value - width.value / 2}px`
      };
    });
    watchThrottled(leftOffset, () => {
      const hitBarsElement = [];
      const cursorTime = toDayjs(datetime.value);
      for (let i = 0; i < bars.value.length; i++) {
        const element = bars.value[i];
        const begin = toDayjs(element[barStart.value]);
        const end = toDayjs(element[barEnd.value]);
        if (cursorTime.isBetween(begin, end)) {
          hitBarsElement.push(element);
        }
      }
      hitBars.value = hitBarsElement;
    }, { throttle: 200 });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        class: "g-grid-pointer-marker-container",
        style: normalizeStyle({
          left: `${leftOffset.value}px`
        })
      }, [
        createElementVNode("div", {
          class: "g-grid-pointer-marker-marker",
          style: normalizeStyle({
            border: `1px dashed ${unref(colors).markerCurrentTime}`
          })
        }, null, 4),
        (openBlock(), createBlock(Teleport, { to: "body" }, [
          createVNode(Transition, {
            name: "g-fade",
            mode: "out-in"
          }, {
            default: withCtx(() => [
              !unref(isOutside) ? (openBlock(), createElementBlock("div", {
                key: 0,
                ref: "tooltip",
                class: "g-grid-pointer-marker-tooltip",
                style: normalizeStyle(tooltipStylePosition.value)
              }, [
                renderSlot(_ctx.$slots, "pointer-marker-tooltips", normalizeProps(guardReactiveProps({ hitBars: hitBars.value, datetime: datetime.value })), () => [
                  createElementVNode("div", {
                    class: "g-grid-pointer-marker-tooltip-content",
                    style: normalizeStyle({ background: unref(colors).primary, color: unref(colors).text })
                  }, [
                    createElementVNode("div", _hoisted_1$2, "Event at " + toDisplayString(datetime.value), 1),
                    createElementVNode("ul", null, [
                      (openBlock(true), createElementBlock(Fragment, null, renderList(hitBars.value, (bar) => {
                        return openBlock(), createElementBlock("li", {
                          key: bar.ganttBarConfig.id
                        }, toDisplayString(bar.ganttBarConfig.label ?? bar.ganttBarConfig.id), 1);
                      }), 128))
                    ])
                  ], 4)
                ])
              ], 4)) : createCommentVNode("", true)
            ]),
            _: 3
          })
        ]))
      ], 4);
    };
  }
});
function getDefaultExportFromCjs(x) {
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
}
var papaparse_min$1 = { exports: {} };
/* @license
Papa Parse
v5.5.2
https://github.com/mholt/PapaParse
License: MIT
*/
var papaparse_min = papaparse_min$1.exports;
var hasRequiredPapaparse_min;
function requirePapaparse_min() {
  if (hasRequiredPapaparse_min) return papaparse_min$1.exports;
  hasRequiredPapaparse_min = 1;
  (function(module, exports) {
    ((e, t) => {
      module.exports = t();
    })(papaparse_min, function r() {
      var n = "undefined" != typeof self ? self : "undefined" != typeof window ? window : void 0 !== n ? n : {};
      var d, s = !n.document && !!n.postMessage, a = n.IS_PAPA_WORKER || false, o = {}, h2 = 0, v = {};
      function u(e) {
        this._handle = null, this._finished = false, this._completed = false, this._halted = false, this._input = null, this._baseIndex = 0, this._partialLine = "", this._rowCount = 0, this._start = 0, this._nextChunk = null, this.isFirstChunk = true, this._completeResults = { data: [], errors: [], meta: {} }, (function(e2) {
          var t = w(e2);
          t.chunkSize = parseInt(t.chunkSize), e2.step || e2.chunk || (t.chunkSize = null);
          this._handle = new i(t), (this._handle.streamer = this)._config = t;
        }).call(this, e), this.parseChunk = function(t, e2) {
          var i2 = parseInt(this._config.skipFirstNLines) || 0;
          if (this.isFirstChunk && 0 < i2) {
            let e3 = this._config.newline;
            e3 || (r2 = this._config.quoteChar || '"', e3 = this._handle.guessLineEndings(t, r2)), t = [...t.split(e3).slice(i2)].join(e3);
          }
          this.isFirstChunk && U(this._config.beforeFirstChunk) && void 0 !== (r2 = this._config.beforeFirstChunk(t)) && (t = r2), this.isFirstChunk = false, this._halted = false;
          var i2 = this._partialLine + t, r2 = (this._partialLine = "", this._handle.parse(i2, this._baseIndex, !this._finished));
          if (!this._handle.paused() && !this._handle.aborted()) {
            t = r2.meta.cursor, i2 = (this._finished || (this._partialLine = i2.substring(t - this._baseIndex), this._baseIndex = t), r2 && r2.data && (this._rowCount += r2.data.length), this._finished || this._config.preview && this._rowCount >= this._config.preview);
            if (a) n.postMessage({ results: r2, workerId: v.WORKER_ID, finished: i2 });
            else if (U(this._config.chunk) && !e2) {
              if (this._config.chunk(r2, this._handle), this._handle.paused() || this._handle.aborted()) return void (this._halted = true);
              this._completeResults = r2 = void 0;
            }
            return this._config.step || this._config.chunk || (this._completeResults.data = this._completeResults.data.concat(r2.data), this._completeResults.errors = this._completeResults.errors.concat(r2.errors), this._completeResults.meta = r2.meta), this._completed || !i2 || !U(this._config.complete) || r2 && r2.meta.aborted || (this._config.complete(this._completeResults, this._input), this._completed = true), i2 || r2 && r2.meta.paused || this._nextChunk(), r2;
          }
          this._halted = true;
        }, this._sendError = function(e2) {
          U(this._config.error) ? this._config.error(e2) : a && this._config.error && n.postMessage({ workerId: v.WORKER_ID, error: e2, finished: false });
        };
      }
      function f(e) {
        var r2;
        (e = e || {}).chunkSize || (e.chunkSize = v.RemoteChunkSize), u.call(this, e), this._nextChunk = s ? function() {
          this._readChunk(), this._chunkLoaded();
        } : function() {
          this._readChunk();
        }, this.stream = function(e2) {
          this._input = e2, this._nextChunk();
        }, this._readChunk = function() {
          if (this._finished) this._chunkLoaded();
          else {
            if (r2 = new XMLHttpRequest(), this._config.withCredentials && (r2.withCredentials = this._config.withCredentials), s || (r2.onload = y(this._chunkLoaded, this), r2.onerror = y(this._chunkError, this)), r2.open(this._config.downloadRequestBody ? "POST" : "GET", this._input, !s), this._config.downloadRequestHeaders) {
              var e2, t = this._config.downloadRequestHeaders;
              for (e2 in t) r2.setRequestHeader(e2, t[e2]);
            }
            var i2;
            this._config.chunkSize && (i2 = this._start + this._config.chunkSize - 1, r2.setRequestHeader("Range", "bytes=" + this._start + "-" + i2));
            try {
              r2.send(this._config.downloadRequestBody);
            } catch (e3) {
              this._chunkError(e3.message);
            }
            s && 0 === r2.status && this._chunkError();
          }
        }, this._chunkLoaded = function() {
          4 === r2.readyState && (r2.status < 200 || 400 <= r2.status ? this._chunkError() : (this._start += this._config.chunkSize || r2.responseText.length, this._finished = !this._config.chunkSize || this._start >= ((e2) => null !== (e2 = e2.getResponseHeader("Content-Range")) ? parseInt(e2.substring(e2.lastIndexOf("/") + 1)) : -1)(r2), this.parseChunk(r2.responseText)));
        }, this._chunkError = function(e2) {
          e2 = r2.statusText || e2;
          this._sendError(new Error(e2));
        };
      }
      function l(e) {
        (e = e || {}).chunkSize || (e.chunkSize = v.LocalChunkSize), u.call(this, e);
        var i2, r2, n2 = "undefined" != typeof FileReader;
        this.stream = function(e2) {
          this._input = e2, r2 = e2.slice || e2.webkitSlice || e2.mozSlice, n2 ? ((i2 = new FileReader()).onload = y(this._chunkLoaded, this), i2.onerror = y(this._chunkError, this)) : i2 = new FileReaderSync(), this._nextChunk();
        }, this._nextChunk = function() {
          this._finished || this._config.preview && !(this._rowCount < this._config.preview) || this._readChunk();
        }, this._readChunk = function() {
          var e2 = this._input, t = (this._config.chunkSize && (t = Math.min(this._start + this._config.chunkSize, this._input.size), e2 = r2.call(e2, this._start, t)), i2.readAsText(e2, this._config.encoding));
          n2 || this._chunkLoaded({ target: { result: t } });
        }, this._chunkLoaded = function(e2) {
          this._start += this._config.chunkSize, this._finished = !this._config.chunkSize || this._start >= this._input.size, this.parseChunk(e2.target.result);
        }, this._chunkError = function() {
          this._sendError(i2.error);
        };
      }
      function c(e) {
        var i2;
        u.call(this, e = e || {}), this.stream = function(e2) {
          return i2 = e2, this._nextChunk();
        }, this._nextChunk = function() {
          var e2, t;
          if (!this._finished) return e2 = this._config.chunkSize, i2 = e2 ? (t = i2.substring(0, e2), i2.substring(e2)) : (t = i2, ""), this._finished = !i2, this.parseChunk(t);
        };
      }
      function p(e) {
        u.call(this, e = e || {});
        var t = [], i2 = true, r2 = false;
        this.pause = function() {
          u.prototype.pause.apply(this, arguments), this._input.pause();
        }, this.resume = function() {
          u.prototype.resume.apply(this, arguments), this._input.resume();
        }, this.stream = function(e2) {
          this._input = e2, this._input.on("data", this._streamData), this._input.on("end", this._streamEnd), this._input.on("error", this._streamError);
        }, this._checkIsFinished = function() {
          r2 && 1 === t.length && (this._finished = true);
        }, this._nextChunk = function() {
          this._checkIsFinished(), t.length ? this.parseChunk(t.shift()) : i2 = true;
        }, this._streamData = y(function(e2) {
          try {
            t.push("string" == typeof e2 ? e2 : e2.toString(this._config.encoding)), i2 && (i2 = false, this._checkIsFinished(), this.parseChunk(t.shift()));
          } catch (e3) {
            this._streamError(e3);
          }
        }, this), this._streamError = y(function(e2) {
          this._streamCleanUp(), this._sendError(e2);
        }, this), this._streamEnd = y(function() {
          this._streamCleanUp(), r2 = true, this._streamData("");
        }, this), this._streamCleanUp = y(function() {
          this._input.removeListener("data", this._streamData), this._input.removeListener("end", this._streamEnd), this._input.removeListener("error", this._streamError);
        }, this);
      }
      function i(m2) {
        var n2, s2, a2, t, o2 = Math.pow(2, 53), h3 = -o2, u2 = /^\s*-?(\d+\.?|\.\d+|\d+\.\d+)([eE][-+]?\d+)?\s*$/, d2 = /^((\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z)))$/, i2 = this, r2 = 0, f2 = 0, l2 = false, e = false, c2 = [], p2 = { data: [], errors: [], meta: {} };
        function y2(e2) {
          return "greedy" === m2.skipEmptyLines ? "" === e2.join("").trim() : 1 === e2.length && 0 === e2[0].length;
        }
        function g2() {
          if (p2 && a2 && (k("Delimiter", "UndetectableDelimiter", "Unable to auto-detect delimiting character; defaulted to '" + v.DefaultDelimiter + "'"), a2 = false), m2.skipEmptyLines && (p2.data = p2.data.filter(function(e3) {
            return !y2(e3);
          })), _2()) {
            let t2 = function(e3, t3) {
              U(m2.transformHeader) && (e3 = m2.transformHeader(e3, t3)), c2.push(e3);
            };
            if (p2) if (Array.isArray(p2.data[0])) {
              for (var e2 = 0; _2() && e2 < p2.data.length; e2++) p2.data[e2].forEach(t2);
              p2.data.splice(0, 1);
            } else p2.data.forEach(t2);
          }
          function i3(e3, t2) {
            for (var i4 = m2.header ? {} : [], r4 = 0; r4 < e3.length; r4++) {
              var n3 = r4, s3 = e3[r4], s3 = ((e4, t3) => ((e5) => (m2.dynamicTypingFunction && void 0 === m2.dynamicTyping[e5] && (m2.dynamicTyping[e5] = m2.dynamicTypingFunction(e5)), true === (m2.dynamicTyping[e5] || m2.dynamicTyping)))(e4) ? "true" === t3 || "TRUE" === t3 || "false" !== t3 && "FALSE" !== t3 && (((e5) => {
                if (u2.test(e5)) {
                  e5 = parseFloat(e5);
                  if (h3 < e5 && e5 < o2) return 1;
                }
              })(t3) ? parseFloat(t3) : d2.test(t3) ? new Date(t3) : "" === t3 ? null : t3) : t3)(n3 = m2.header ? r4 >= c2.length ? "__parsed_extra" : c2[r4] : n3, s3 = m2.transform ? m2.transform(s3, n3) : s3);
              "__parsed_extra" === n3 ? (i4[n3] = i4[n3] || [], i4[n3].push(s3)) : i4[n3] = s3;
            }
            return m2.header && (r4 > c2.length ? k("FieldMismatch", "TooManyFields", "Too many fields: expected " + c2.length + " fields but parsed " + r4, f2 + t2) : r4 < c2.length && k("FieldMismatch", "TooFewFields", "Too few fields: expected " + c2.length + " fields but parsed " + r4, f2 + t2)), i4;
          }
          var r3;
          p2 && (m2.header || m2.dynamicTyping || m2.transform) && (r3 = 1, !p2.data.length || Array.isArray(p2.data[0]) ? (p2.data = p2.data.map(i3), r3 = p2.data.length) : p2.data = i3(p2.data, 0), m2.header && p2.meta && (p2.meta.fields = c2), f2 += r3);
        }
        function _2() {
          return m2.header && 0 === c2.length;
        }
        function k(e2, t2, i3, r3) {
          e2 = { type: e2, code: t2, message: i3 };
          void 0 !== r3 && (e2.row = r3), p2.errors.push(e2);
        }
        U(m2.step) && (t = m2.step, m2.step = function(e2) {
          p2 = e2, _2() ? g2() : (g2(), 0 !== p2.data.length && (r2 += e2.data.length, m2.preview && r2 > m2.preview ? s2.abort() : (p2.data = p2.data[0], t(p2, i2))));
        }), this.parse = function(e2, t2, i3) {
          var r3 = m2.quoteChar || '"', r3 = (m2.newline || (m2.newline = this.guessLineEndings(e2, r3)), a2 = false, m2.delimiter ? U(m2.delimiter) && (m2.delimiter = m2.delimiter(e2), p2.meta.delimiter = m2.delimiter) : ((r3 = ((e3, t3, i4, r4, n3) => {
            var s3, a3, o3, h4;
            n3 = n3 || [",", "	", "|", ";", v.RECORD_SEP, v.UNIT_SEP];
            for (var u3 = 0; u3 < n3.length; u3++) {
              for (var d3, f3 = n3[u3], l3 = 0, c3 = 0, p3 = 0, g3 = (o3 = void 0, new E({ comments: r4, delimiter: f3, newline: t3, preview: 10 }).parse(e3)), _3 = 0; _3 < g3.data.length; _3++) i4 && y2(g3.data[_3]) ? p3++ : (d3 = g3.data[_3].length, c3 += d3, void 0 === o3 ? o3 = d3 : 0 < d3 && (l3 += Math.abs(d3 - o3), o3 = d3));
              0 < g3.data.length && (c3 /= g3.data.length - p3), (void 0 === a3 || l3 <= a3) && (void 0 === h4 || h4 < c3) && 1.99 < c3 && (a3 = l3, s3 = f3, h4 = c3);
            }
            return { successful: !!(m2.delimiter = s3), bestDelimiter: s3 };
          })(e2, m2.newline, m2.skipEmptyLines, m2.comments, m2.delimitersToGuess)).successful ? m2.delimiter = r3.bestDelimiter : (a2 = true, m2.delimiter = v.DefaultDelimiter), p2.meta.delimiter = m2.delimiter), w(m2));
          return m2.preview && m2.header && r3.preview++, n2 = e2, s2 = new E(r3), p2 = s2.parse(n2, t2, i3), g2(), l2 ? { meta: { paused: true } } : p2 || { meta: { paused: false } };
        }, this.paused = function() {
          return l2;
        }, this.pause = function() {
          l2 = true, s2.abort(), n2 = U(m2.chunk) ? "" : n2.substring(s2.getCharIndex());
        }, this.resume = function() {
          i2.streamer._halted ? (l2 = false, i2.streamer.parseChunk(n2, true)) : setTimeout(i2.resume, 3);
        }, this.aborted = function() {
          return e;
        }, this.abort = function() {
          e = true, s2.abort(), p2.meta.aborted = true, U(m2.complete) && m2.complete(p2), n2 = "";
        }, this.guessLineEndings = function(e2, t2) {
          e2 = e2.substring(0, 1048576);
          var t2 = new RegExp(P(t2) + "([^]*?)" + P(t2), "gm"), i3 = (e2 = e2.replace(t2, "")).split("\r"), t2 = e2.split("\n"), e2 = 1 < t2.length && t2[0].length < i3[0].length;
          if (1 === i3.length || e2) return "\n";
          for (var r3 = 0, n3 = 0; n3 < i3.length; n3++) "\n" === i3[n3][0] && r3++;
          return r3 >= i3.length / 2 ? "\r\n" : "\r";
        };
      }
      function P(e) {
        return e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
      }
      function E(C) {
        var S = (C = C || {}).delimiter, O = C.newline, x = C.comments, I = C.step, A = C.preview, T = C.fastMode, D = null, L = false, F = null == C.quoteChar ? '"' : C.quoteChar, j = F;
        if (void 0 !== C.escapeChar && (j = C.escapeChar), ("string" != typeof S || -1 < v.BAD_DELIMITERS.indexOf(S)) && (S = ","), x === S) throw new Error("Comment character same as delimiter");
        true === x ? x = "#" : ("string" != typeof x || -1 < v.BAD_DELIMITERS.indexOf(x)) && (x = false), "\n" !== O && "\r" !== O && "\r\n" !== O && (O = "\n");
        var z = 0, M = false;
        this.parse = function(i2, t, r2) {
          if ("string" != typeof i2) throw new Error("Input must be a string");
          var n2 = i2.length, e = S.length, s2 = O.length, a2 = x.length, o2 = U(I), h3 = [], u2 = [], d2 = [], f2 = z = 0;
          if (!i2) return b();
          if (T || false !== T && -1 === i2.indexOf(F)) {
            for (var l2 = i2.split(O), c2 = 0; c2 < l2.length; c2++) {
              if (d2 = l2[c2], z += d2.length, c2 !== l2.length - 1) z += O.length;
              else if (r2) return b();
              if (!x || d2.substring(0, a2) !== x) {
                if (o2) {
                  if (h3 = [], k(d2.split(S)), R(), M) return b();
                } else k(d2.split(S));
                if (A && A <= c2) return h3 = h3.slice(0, A), b(true);
              }
            }
            return b();
          }
          for (var p2 = i2.indexOf(S, z), g2 = i2.indexOf(O, z), _2 = new RegExp(P(j) + P(F), "g"), m2 = i2.indexOf(F, z); ; ) if (i2[z] === F) for (m2 = z, z++; ; ) {
            if (-1 === (m2 = i2.indexOf(F, m2 + 1))) return r2 || u2.push({ type: "Quotes", code: "MissingQuotes", message: "Quoted field unterminated", row: h3.length, index: z }), E2();
            if (m2 === n2 - 1) return E2(i2.substring(z, m2).replace(_2, F));
            if (F === j && i2[m2 + 1] === j) m2++;
            else if (F === j || 0 === m2 || i2[m2 - 1] !== j) {
              -1 !== p2 && p2 < m2 + 1 && (p2 = i2.indexOf(S, m2 + 1));
              var y2 = v2(-1 === (g2 = -1 !== g2 && g2 < m2 + 1 ? i2.indexOf(O, m2 + 1) : g2) ? p2 : Math.min(p2, g2));
              if (i2.substr(m2 + 1 + y2, e) === S) {
                d2.push(i2.substring(z, m2).replace(_2, F)), i2[z = m2 + 1 + y2 + e] !== F && (m2 = i2.indexOf(F, z)), p2 = i2.indexOf(S, z), g2 = i2.indexOf(O, z);
                break;
              }
              y2 = v2(g2);
              if (i2.substring(m2 + 1 + y2, m2 + 1 + y2 + s2) === O) {
                if (d2.push(i2.substring(z, m2).replace(_2, F)), w2(m2 + 1 + y2 + s2), p2 = i2.indexOf(S, z), m2 = i2.indexOf(F, z), o2 && (R(), M)) return b();
                if (A && h3.length >= A) return b(true);
                break;
              }
              u2.push({ type: "Quotes", code: "InvalidQuotes", message: "Trailing quote on quoted field is malformed", row: h3.length, index: z }), m2++;
            }
          }
          else if (x && 0 === d2.length && i2.substring(z, z + a2) === x) {
            if (-1 === g2) return b();
            z = g2 + s2, g2 = i2.indexOf(O, z), p2 = i2.indexOf(S, z);
          } else if (-1 !== p2 && (p2 < g2 || -1 === g2)) d2.push(i2.substring(z, p2)), z = p2 + e, p2 = i2.indexOf(S, z);
          else {
            if (-1 === g2) break;
            if (d2.push(i2.substring(z, g2)), w2(g2 + s2), o2 && (R(), M)) return b();
            if (A && h3.length >= A) return b(true);
          }
          return E2();
          function k(e2) {
            h3.push(e2), f2 = z;
          }
          function v2(e2) {
            var t2 = 0;
            return t2 = -1 !== e2 && (e2 = i2.substring(m2 + 1, e2)) && "" === e2.trim() ? e2.length : t2;
          }
          function E2(e2) {
            return r2 || (void 0 === e2 && (e2 = i2.substring(z)), d2.push(e2), z = n2, k(d2), o2 && R()), b();
          }
          function w2(e2) {
            z = e2, k(d2), d2 = [], g2 = i2.indexOf(O, z);
          }
          function b(e2) {
            if (C.header && !t && h3.length && !L) {
              var s3 = h3[0], a3 = {}, o3 = new Set(s3);
              let n3 = false;
              for (let r3 = 0; r3 < s3.length; r3++) {
                let i3 = s3[r3];
                if (a3[i3 = U(C.transformHeader) ? C.transformHeader(i3, r3) : i3]) {
                  let e3, t2 = a3[i3];
                  for (; e3 = i3 + "_" + t2, t2++, o3.has(e3); ) ;
                  o3.add(e3), s3[r3] = e3, a3[i3]++, n3 = true, (D = null === D ? {} : D)[e3] = i3;
                } else a3[i3] = 1, s3[r3] = i3;
                o3.add(i3);
              }
              n3 && console.warn("Duplicate headers found and renamed."), L = true;
            }
            return { data: h3, errors: u2, meta: { delimiter: S, linebreak: O, aborted: M, truncated: !!e2, cursor: f2 + (t || 0), renamedHeaders: D } };
          }
          function R() {
            I(b()), h3 = [], u2 = [];
          }
        }, this.abort = function() {
          M = true;
        }, this.getCharIndex = function() {
          return z;
        };
      }
      function g(e) {
        var t = e.data, i2 = o[t.workerId], r2 = false;
        if (t.error) i2.userError(t.error, t.file);
        else if (t.results && t.results.data) {
          var n2 = { abort: function() {
            r2 = true, _(t.workerId, { data: [], errors: [], meta: { aborted: true } });
          }, pause: m, resume: m };
          if (U(i2.userStep)) {
            for (var s2 = 0; s2 < t.results.data.length && (i2.userStep({ data: t.results.data[s2], errors: t.results.errors, meta: t.results.meta }, n2), !r2); s2++) ;
            delete t.results;
          } else U(i2.userChunk) && (i2.userChunk(t.results, n2, t.file), delete t.results);
        }
        t.finished && !r2 && _(t.workerId, t.results);
      }
      function _(e, t) {
        var i2 = o[e];
        U(i2.userComplete) && i2.userComplete(t), i2.terminate(), delete o[e];
      }
      function m() {
        throw new Error("Not implemented.");
      }
      function w(e) {
        if ("object" != typeof e || null === e) return e;
        var t, i2 = Array.isArray(e) ? [] : {};
        for (t in e) i2[t] = w(e[t]);
        return i2;
      }
      function y(e, t) {
        return function() {
          e.apply(t, arguments);
        };
      }
      function U(e) {
        return "function" == typeof e;
      }
      return v.parse = function(e, t) {
        var i2 = (t = t || {}).dynamicTyping || false;
        U(i2) && (t.dynamicTypingFunction = i2, i2 = {});
        if (t.dynamicTyping = i2, t.transform = !!U(t.transform) && t.transform, !t.worker || !v.WORKERS_SUPPORTED) return i2 = null, v.NODE_STREAM_INPUT, "string" == typeof e ? (e = ((e2) => 65279 !== e2.charCodeAt(0) ? e2 : e2.slice(1))(e), i2 = new (t.download ? f : c)(t)) : true === e.readable && U(e.read) && U(e.on) ? i2 = new p(t) : (n.File && e instanceof File || e instanceof Object) && (i2 = new l(t)), i2.stream(e);
        (i2 = (() => {
          var e2;
          return !!v.WORKERS_SUPPORTED && (e2 = (() => {
            var e3 = n.URL || n.webkitURL || null, t2 = r.toString();
            return v.BLOB_URL || (v.BLOB_URL = e3.createObjectURL(new Blob(["var global = (function() { if (typeof self !== 'undefined') { return self; } if (typeof window !== 'undefined') { return window; } if (typeof global !== 'undefined') { return global; } return {}; })(); global.IS_PAPA_WORKER=true; ", "(", t2, ")();"], { type: "text/javascript" })));
          })(), (e2 = new n.Worker(e2)).onmessage = g, e2.id = h2++, o[e2.id] = e2);
        })()).userStep = t.step, i2.userChunk = t.chunk, i2.userComplete = t.complete, i2.userError = t.error, t.step = U(t.step), t.chunk = U(t.chunk), t.complete = U(t.complete), t.error = U(t.error), delete t.worker, i2.postMessage({ input: e, config: t, workerId: i2.id });
      }, v.unparse = function(e, t) {
        var n2 = false, _2 = true, m2 = ",", y2 = "\r\n", s2 = '"', a2 = s2 + s2, i2 = false, r2 = null, o2 = false, h3 = ((() => {
          if ("object" == typeof t) {
            if ("string" != typeof t.delimiter || v.BAD_DELIMITERS.filter(function(e2) {
              return -1 !== t.delimiter.indexOf(e2);
            }).length || (m2 = t.delimiter), "boolean" != typeof t.quotes && "function" != typeof t.quotes && !Array.isArray(t.quotes) || (n2 = t.quotes), "boolean" != typeof t.skipEmptyLines && "string" != typeof t.skipEmptyLines || (i2 = t.skipEmptyLines), "string" == typeof t.newline && (y2 = t.newline), "string" == typeof t.quoteChar && (s2 = t.quoteChar), "boolean" == typeof t.header && (_2 = t.header), Array.isArray(t.columns)) {
              if (0 === t.columns.length) throw new Error("Option columns is empty");
              r2 = t.columns;
            }
            void 0 !== t.escapeChar && (a2 = t.escapeChar + s2), t.escapeFormulae instanceof RegExp ? o2 = t.escapeFormulae : "boolean" == typeof t.escapeFormulae && t.escapeFormulae && (o2 = /^[=+\-@\t\r].*$/);
          }
        })(), new RegExp(P(s2), "g"));
        "string" == typeof e && (e = JSON.parse(e));
        if (Array.isArray(e)) {
          if (!e.length || Array.isArray(e[0])) return u2(null, e, i2);
          if ("object" == typeof e[0]) return u2(r2 || Object.keys(e[0]), e, i2);
        } else if ("object" == typeof e) return "string" == typeof e.data && (e.data = JSON.parse(e.data)), Array.isArray(e.data) && (e.fields || (e.fields = e.meta && e.meta.fields || r2), e.fields || (e.fields = Array.isArray(e.data[0]) ? e.fields : "object" == typeof e.data[0] ? Object.keys(e.data[0]) : []), Array.isArray(e.data[0]) || "object" == typeof e.data[0] || (e.data = [e.data])), u2(e.fields || [], e.data || [], i2);
        throw new Error("Unable to serialize unrecognized input");
        function u2(e2, t2, i3) {
          var r3 = "", n3 = ("string" == typeof e2 && (e2 = JSON.parse(e2)), "string" == typeof t2 && (t2 = JSON.parse(t2)), Array.isArray(e2) && 0 < e2.length), s3 = !Array.isArray(t2[0]);
          if (n3 && _2) {
            for (var a3 = 0; a3 < e2.length; a3++) 0 < a3 && (r3 += m2), r3 += k(e2[a3], a3);
            0 < t2.length && (r3 += y2);
          }
          for (var o3 = 0; o3 < t2.length; o3++) {
            var h4 = (n3 ? e2 : t2[o3]).length, u3 = false, d2 = n3 ? 0 === Object.keys(t2[o3]).length : 0 === t2[o3].length;
            if (i3 && !n3 && (u3 = "greedy" === i3 ? "" === t2[o3].join("").trim() : 1 === t2[o3].length && 0 === t2[o3][0].length), "greedy" === i3 && n3) {
              for (var f2 = [], l2 = 0; l2 < h4; l2++) {
                var c2 = s3 ? e2[l2] : l2;
                f2.push(t2[o3][c2]);
              }
              u3 = "" === f2.join("").trim();
            }
            if (!u3) {
              for (var p2 = 0; p2 < h4; p2++) {
                0 < p2 && !d2 && (r3 += m2);
                var g2 = n3 && s3 ? e2[p2] : p2;
                r3 += k(t2[o3][g2], p2);
              }
              o3 < t2.length - 1 && (!i3 || 0 < h4 && !d2) && (r3 += y2);
            }
          }
          return r3;
        }
        function k(e2, t2) {
          var i3, r3;
          return null == e2 ? "" : e2.constructor === Date ? JSON.stringify(e2).slice(1, 25) : (r3 = false, o2 && "string" == typeof e2 && o2.test(e2) && (e2 = "'" + e2, r3 = true), i3 = e2.toString().replace(h3, a2), (r3 = r3 || true === n2 || "function" == typeof n2 && n2(e2, t2) || Array.isArray(n2) && n2[t2] || ((e3, t3) => {
            for (var i4 = 0; i4 < t3.length; i4++) if (-1 < e3.indexOf(t3[i4])) return true;
            return false;
          })(i3, v.BAD_DELIMITERS) || -1 < i3.indexOf(m2) || " " === i3.charAt(0) || " " === i3.charAt(i3.length - 1)) ? s2 + i3 + s2 : i3);
        }
      }, v.RECORD_SEP = String.fromCharCode(30), v.UNIT_SEP = String.fromCharCode(31), v.BYTE_ORDER_MARK = "\uFEFF", v.BAD_DELIMITERS = ["\r", "\n", '"', v.BYTE_ORDER_MARK], v.WORKERS_SUPPORTED = !s && !!n.Worker, v.NODE_STREAM_INPUT = 1, v.LocalChunkSize = 10485760, v.RemoteChunkSize = 5242880, v.DefaultDelimiter = ",", v.Parser = E, v.ParserHandle = i, v.NetworkStreamer = f, v.FileStreamer = l, v.StringStreamer = c, v.ReadableStreamStreamer = p, n.jQuery && ((d = n.jQuery).fn.parse = function(o2) {
        var i2 = o2.config || {}, h3 = [];
        return this.each(function(e2) {
          if (!("INPUT" === d(this).prop("tagName").toUpperCase() && "file" === d(this).attr("type").toLowerCase() && n.FileReader) || !this.files || 0 === this.files.length) return true;
          for (var t = 0; t < this.files.length; t++) h3.push({ file: this.files[t], inputElem: this, instanceConfig: d.extend({}, i2) });
        }), e(), this;
        function e() {
          if (0 === h3.length) U(o2.complete) && o2.complete();
          else {
            var e2, t, i3, r2, n2 = h3[0];
            if (U(o2.before)) {
              var s2 = o2.before(n2.file, n2.inputElem);
              if ("object" == typeof s2) {
                if ("abort" === s2.action) return e2 = "AbortError", t = n2.file, i3 = n2.inputElem, r2 = s2.reason, void (U(o2.error) && o2.error({ name: e2 }, t, i3, r2));
                if ("skip" === s2.action) return void u2();
                "object" == typeof s2.config && (n2.instanceConfig = d.extend(n2.instanceConfig, s2.config));
              } else if ("skip" === s2) return void u2();
            }
            var a2 = n2.instanceConfig.complete;
            n2.instanceConfig.complete = function(e3) {
              U(a2) && a2(e3, n2.file, n2.inputElem), u2();
            }, v.parse(n2.file, n2.instanceConfig);
          }
        }
        function u2() {
          h3.splice(0, 1), e();
        }
      }), a && (n.onmessage = function(e) {
        e = e.data;
        void 0 === v.WORKER_ID && e && (v.WORKER_ID = e.workerId);
        "string" == typeof e.input ? n.postMessage({ workerId: v.WORKER_ID, results: v.parse(e.input, e.config), finished: true }) : (n.File && e.input instanceof File || e.input instanceof Object) && (e = v.parse(e.input, e.config)) && n.postMessage({ workerId: v.WORKER_ID, results: e, finished: true });
      }), (f.prototype = Object.create(u.prototype)).constructor = f, (l.prototype = Object.create(u.prototype)).constructor = l, (c.prototype = Object.create(c.prototype)).constructor = c, (p.prototype = Object.create(u.prototype)).constructor = p, v;
    });
  })(papaparse_min$1);
  return papaparse_min$1.exports;
}
var papaparse_minExports = requirePapaparse_min();
const Papa = /* @__PURE__ */ getDefaultExportFromCjs(papaparse_minExports);
function useImport() {
  const isImporting = ref(false);
  const lastError = ref(null);
  const importProgress = ref(0);
  const parseFileContent = async (content, format) => {
    try {
      switch (format) {
        case "jira":
          return JSON.parse(content.toString());
        case "csv":
          return parseCsv(content.toString());
        default:
          throw new Error(`Format not supported: ${format}`);
      }
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Unknown error during parsing";
      throw new Error(`Failed to parse file: ${errorMessage}`);
    }
  };
  const parseCsv = (csvContent) => {
    const result = Papa.parse(csvContent, {
      header: true,
      skipEmptyLines: true,
      dynamicTyping: true,
      transformHeader: (header) => {
        return header.trim().toLowerCase().replace(/\s+/g, "_");
      }
    });
    if (result.errors && result.errors.length > 0) {
      const errorMessage = result.errors.map((err) => err.message).join("; ");
      throw new Error(`CSV parsing errors: ${errorMessage}`);
    }
    return result.data;
  };
  const convertJiraToGantt = (data, options) => {
    const warnings = [];
    const issues = data.issues || [];
    const issueMap = /* @__PURE__ */ new Map();
    const barConfigMap = /* @__PURE__ */ new Map();
    const connectionsMap = /* @__PURE__ */ new Map();
    issues.forEach((issue) => {
      issueMap.set(issue.id, issue);
      const barConfig = {
        id: `issue-${issue.key}`,
        label: issue.fields.summary,
        progress: calculateProgress(issue.fields.status),
        connections: []
      };
      if (issue.fields.issuetype) {
        barConfig.class = issue.fields.issuetype.name.toLowerCase().replace(/\s+/g, "-");
      }
      barConfigMap.set(issue.key, barConfig);
    });
    issues.forEach((issue) => {
      if (issue.fields.issuelinks && Array.isArray(issue.fields.issuelinks)) {
        issue.fields.issuelinks.forEach((link) => {
          var _a, _b, _c, _d;
          if (link.outwardIssue) {
            const sourceKey = issue.key;
            const targetKey = link.outwardIssue.key;
            if (!connectionsMap.has(sourceKey)) {
              connectionsMap.set(sourceKey, []);
            }
            const connection = {
              targetId: `issue-${targetKey}`,
              type: mapLinkTypeToConnectionType((_a = link.type) == null ? void 0 : _a.name)
            };
            (_b = connectionsMap.get(sourceKey)) == null ? void 0 : _b.push(connection);
          }
          if (link.inwardIssue) {
            const sourceKey = link.inwardIssue.key;
            const targetKey = issue.key;
            if (!connectionsMap.has(sourceKey)) {
              connectionsMap.set(sourceKey, []);
            }
            const connection = {
              targetId: `issue-${targetKey}`,
              type: mapLinkTypeToConnectionType((_c = link.type) == null ? void 0 : _c.name)
            };
            (_d = connectionsMap.get(sourceKey)) == null ? void 0 : _d.push(connection);
          }
        });
      }
    });
    const childrenMap = /* @__PURE__ */ new Map();
    issues.forEach((issue) => {
      if (issue.fields.subtasks && Array.isArray(issue.fields.subtasks) && issue.fields.subtasks.length > 0) {
        issue.fields.subtasks.forEach((subtask) => {
          var _a;
          const fullSubtask = issues.find((i) => i.id === subtask.id) || subtask;
          if (!childrenMap.has(issue.id)) {
            childrenMap.set(issue.id, []);
          }
          (_a = childrenMap.get(issue.id)) == null ? void 0 : _a.push(fullSubtask);
        });
      }
    });
    issues.forEach((issue) => {
      var _a;
      if (issue.fields.parent && issue.fields.parent.id) {
        const parentId = issue.fields.parent.id;
        const isExplicitSubtask = issues.some(
          (parentIssue) => {
            var _a2;
            return parentIssue.id === parentId && ((_a2 = parentIssue.fields.subtasks) == null ? void 0 : _a2.some((st) => st.id === issue.id));
          }
        );
        if (!isExplicitSubtask) {
          if (!childrenMap.has(parentId)) {
            childrenMap.set(parentId, []);
          }
          (_a = childrenMap.get(parentId)) == null ? void 0 : _a.push(issue);
        }
      }
    });
    const rootIssues = issues.filter(
      (issue) => !issue.fields.parent || !issueMap.has(issue.fields.parent.id)
    );
    const buildRows = (issues2) => {
      return issues2.map((issue) => {
        var _a, _b;
        const { fields } = issue;
        let startDate = fields.created;
        let endDate = fields.duedate || fields.updated;
        if (!endDate || !startDate) {
          warnings.push(`Issue "${fields.summary}" has missing date information`);
          startDate = dayjs().format("YYYY-MM-DD");
          endDate = dayjs().add(7, "day").format("YYYY-MM-DD");
        }
        const barConfig = barConfigMap.get(issue.key) || {
          id: `issue-${issue.key}`,
          label: fields.summary,
          progress: calculateProgress(fields.status),
          connections: []
        };
        const connections = connectionsMap.get(issue.key) || [];
        barConfig.connections = connections;
        const barObject = {
          [((_a = options.mapFields) == null ? void 0 : _a.startDate) || "start"]: startDate,
          [((_b = options.mapFields) == null ? void 0 : _b.endDate) || "end"]: endDate,
          ganttBarConfig: barConfig
        };
        const chartRow = {
          id: issue.id,
          label: fields.summary,
          bars: [barObject]
        };
        const children = childrenMap.get(issue.id) || [];
        if (children.length > 0) {
          chartRow.children = buildRows(children);
        }
        return chartRow;
      });
    };
    return {
      rows: buildRows(rootIssues),
      warnings
    };
  };
  function calculateProgress(status) {
    if (!status) return 0;
    switch (status.name.toLowerCase()) {
      case "to do":
      case "open":
      case "nuovo":
        return 0;
      case "in progress":
      case "in corso":
        return 50;
      case "done":
      case "closed":
      case "resolved":
      case "completato":
        return 100;
      default:
        if (status.name.toLowerCase().includes("progress")) {
          return 50;
        }
        return 0;
    }
  }
  function mapLinkTypeToConnectionType(linkType) {
    if (!linkType) return "straight";
    const lowerType = linkType.toLowerCase();
    if (lowerType.includes("block")) {
      return "squared";
    }
    if (lowerType.includes("depend") || lowerType.includes("relate")) {
      return "bezier";
    }
    return "straight";
  }
  const ensureDateHasTime = (dateStr) => {
    if (!dateStr) return dayjs().format("YYYY-MM-DD HH:mm:ss");
    const date = dayjs(dateStr);
    if (!date.isValid()) {
      return dayjs().format("YYYY-MM-DD HH:mm:ss");
    }
    const hasTimeComponent = date.hour() !== 0 || date.minute() !== 0 || date.second() !== 0 || /\d{1,2}[:hHT]/.test(dateStr);
    return hasTimeComponent ? date.format("YYYY-MM-DD HH:mm:ss") : `${date.format("YYYY-MM-DD")} 00:00:00`;
  };
  const convertSpreadsheetToGantt = (data, options) => {
    const warnings = [];
    const fieldMap = {
      id: ["id", "taskid", "task_id", "key"],
      name: ["name", "task", "taskname", "task_name", "summary", "title"],
      startDate: ["start", "startdate", "start_date", "begins", "begin_date"],
      endDate: [
        "end",
        "enddate",
        "end_date",
        "finish",
        "finishdate",
        "finish_date",
        "due",
        "duedate",
        "due_date"
      ],
      progress: ["progress", "percent", "completion", "complete", "percent_complete"],
      parentId: ["parent", "parentid", "parent_id", "parent_task"],
      dependencies: ["dependencies", "depends", "predecessors", "links"],
      milestone: ["milestone", "is_milestone", "ismilestone"],
      ...options.mapFields
    };
    const normalizeFieldName = (row, fieldOptions) => {
      const keys = Object.keys(row);
      for (const option of fieldOptions) {
        const matchingKey = keys.find((k) => k.toLowerCase() === option.toLowerCase());
        if (matchingKey !== void 0) {
          return matchingKey;
        }
      }
      return void 0;
    };
    const rowsById = /* @__PURE__ */ new Map();
    data.forEach((row) => {
      const idField = normalizeFieldName(row, fieldMap.id);
      const id = idField ? row[idField] : void 0;
      if (!id) {
        warnings.push(`Row is missing an ID field: ${JSON.stringify(row)}`);
        return;
      }
      rowsById.set(id, { ...row, children: [], barConfig: { id: `task-${id}`, connections: [] } });
    });
    data.forEach((row) => {
      const idField = normalizeFieldName(row, fieldMap.id);
      const id = idField ? row[idField] : void 0;
      if (!id) return;
      const parentField = normalizeFieldName(row, fieldMap.parentId);
      const parentId = parentField ? row[parentField] : void 0;
      if (parentId && rowsById.has(parentId)) {
        const parent = rowsById.get(parentId);
        if (parent) {
          parent.children.push(id);
        }
      }
      const dependenciesField = normalizeFieldName(row, fieldMap.dependencies);
      if (dependenciesField && row[dependenciesField]) {
        const dependencies = String(row[dependenciesField]).split(/[,;]\s*/);
        dependencies.forEach((depId) => {
          const depIdAsNumber = Number(depId);
          const depIdAsString = String(depId);
          const dependencyExists = rowsById.has(depIdAsNumber) || rowsById.has(depIdAsString);
          const dependencyRow = rowsById.get(depIdAsNumber) || rowsById.get(depIdAsString);
          if (dependencyExists && dependencyRow) {
            if (dependencyRow.barConfig) {
              dependencyRow.barConfig.connections = dependencyRow.barConfig.connections || [];
              dependencyRow.barConfig.connections.push({
                targetId: `task-${id}`,
                type: "straight"
              });
            }
          } else {
            warnings.push(`Task ${id} refers to a dependency ${depId} that doesn't exist`);
          }
        });
      }
    });
    const rootIds = Array.from(rowsById.keys()).filter((id) => {
      const row = rowsById.get(id);
      if (!row) return false;
      const parentField = normalizeFieldName(row, fieldMap.parentId);
      const parentId = parentField ? row[parentField] : void 0;
      return !parentId || !rowsById.has(parentId);
    });
    const buildRows = (ids) => {
      return ids.map((id) => {
        var _a, _b;
        const row = rowsById.get(id);
        if (!row) {
          warnings.push(`Referenced ID ${id} not found in data`);
          return {
            id: String(id),
            label: `Unknown Task (${id})`,
            bars: []
          };
        }
        const nameField = normalizeFieldName(row, fieldMap.name);
        const name = nameField ? String(row[nameField] || "") : `Task ${id}`;
        let startDateField = normalizeFieldName(row, fieldMap.startDate);
        if (!startDateField && "start_date" in row) {
          startDateField = "start_date";
        }
        let startDate = startDateField ? row[startDateField] : void 0;
        let endDateField = normalizeFieldName(row, fieldMap.endDate);
        if (!endDateField && "end_date" in row) {
          endDateField = "end_date";
        }
        let endDate = endDateField ? row[endDateField] : void 0;
        const progressField = normalizeFieldName(row, fieldMap.progress);
        let progress = progressField ? row[progressField] : void 0;
        if (progress !== void 0) {
          if (typeof progress === "string") {
            progress = parseFloat(progress.replace("%", ""));
          }
          progress = Math.max(0, Math.min(100, Number(progress)));
          if (isNaN(progress)) {
            progress = 0;
          }
        }
        const milestoneField = normalizeFieldName(row, fieldMap.milestone);
        const isMilestone = milestoneField ? row[milestoneField] === true || row[milestoneField] === "true" || row[milestoneField] === 1 : false;
        let start = startDate ? ensureDateHasTime(String(startDate)) : dayjs().format("YYYY-MM-DD HH:mm:ss");
        let end = endDate ? ensureDateHasTime(String(endDate)) : dayjs().add(1, "day").format("YYYY-MM-DD HH:mm:ss");
        if (isMilestone) {
          end = start;
        }
        const barConfig = {
          ...row.barConfig,
          id: `task-${id}`,
          label: name,
          progress,
          immobile: false
        };
        if (isMilestone) {
          barConfig.class = "milestone";
        }
        const barObject = {
          [((_a = options.mapFields) == null ? void 0 : _a.startDate) || "start"]: start,
          [((_b = options.mapFields) == null ? void 0 : _b.endDate) || "end"]: end,
          ganttBarConfig: barConfig
        };
        const chartRow = {
          id,
          label: name,
          bars: [barObject]
        };
        if (row.children.length > 0) {
          chartRow.children = buildRows(row.children);
        }
        return chartRow;
      });
    };
    return {
      rows: buildRows(rootIds),
      warnings
    };
  };
  const importFromFile = async (file, options) => {
    isImporting.value = true;
    importProgress.value = 0;
    lastError.value = null;
    try {
      let format = options.format;
      if (!format) {
        format = detectFormatFromFile(file);
      }
      const content = await readFileContent(file);
      importProgress.value = 20;
      const parsedData = await parseFileContent(content, format);
      importProgress.value = 50;
      const { rows, warnings, chartStart, chartEnd } = await convertToGantt(
        parsedData,
        format,
        options
      );
      importProgress.value = 80;
      if (!options.skipValidation) {
        validateImportedData(rows, warnings);
      }
      importProgress.value = 100;
      if (options.onProgress) {
        options.onProgress(100);
      }
      return {
        success: true,
        data: {
          rows,
          chartStart,
          chartEnd
        },
        warnings
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Unknown error during import";
      lastError.value = errorMessage;
      return {
        success: false,
        error: errorMessage
      };
    } finally {
      isImporting.value = false;
    }
  };
  const detectFormatFromFile = (file) => {
    const fileName = file.name.toLowerCase();
    if (fileName.endsWith(".json")) {
      return "jira";
    } else if (fileName.endsWith(".csv")) {
      return "csv";
    }
    throw new Error(`Could not determine format from file: ${file.name}`);
  };
  const readFileContent = async (file) => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = (e) => {
        var _a;
        if ((_a = e.target) == null ? void 0 : _a.result) {
          resolve(e.target.result);
        } else {
          reject(new Error("Failed to read file"));
        }
      };
      reader.onerror = () => {
        reject(new Error("Error reading file"));
      };
      reader.readAsText(file);
    });
  };
  const convertToGantt = async (data, format, options) => {
    let result;
    switch (format) {
      case "jira":
        result = convertJiraToGantt(data, options);
        break;
      case "csv":
        result = convertSpreadsheetToGantt(data, options);
        break;
      default:
        throw new Error(`Conversion not implemented for format: ${format}`);
    }
    const { chartStart, chartEnd } = calculateChartDateRange(result.rows);
    return {
      ...result,
      chartStart,
      chartEnd
    };
  };
  const calculateChartDateRange = (rows) => {
    let minDate = null;
    let maxDate = null;
    const processRows = (rows2) => {
      rows2.forEach((row) => {
        row.bars.forEach((bar) => {
          const startDate = dayjs(bar.start || bar.begin || bar.startDate);
          const endDate = dayjs(bar.end || bar.finish || bar.endDate);
          if (!minDate || startDate.isBefore(minDate)) {
            minDate = startDate;
          }
          if (!maxDate || endDate.isAfter(maxDate)) {
            maxDate = endDate;
          }
        });
        if (row.children) {
          processRows(row.children);
        }
      });
    };
    processRows(rows);
    if (minDate && maxDate) {
      const rangeDays = maxDate.diff(minDate, "day");
      const buffer = Math.max(1, Math.ceil(rangeDays * 0.1));
      return {
        chartStart: minDate.subtract(buffer, "day").toDate(),
        chartEnd: maxDate.add(buffer, "day").toDate()
      };
    }
    return {};
  };
  const validateImportedData = (rows, warnings) => {
    const validateRow = (row, path) => {
      if (!row.id) {
        warnings.push(`Row at ${path} is missing an ID`);
      }
      if (!row.label) {
        warnings.push(`Row at ${path} is missing a label`);
      }
      if (!row.bars || row.bars.length === 0) {
        warnings.push(`Row at ${path} has no bars`);
      } else {
        row.bars.forEach((bar, i) => {
          if (!bar.ganttBarConfig.id) {
            warnings.push(`Bar ${i} at ${path} is missing an ID`);
          }
          if (bar.ganttBarConfig.connections) {
            bar.ganttBarConfig.connections.forEach((conn, j) => {
              if (!conn.targetId) {
                warnings.push(`Connection ${j} in bar ${i} at ${path} is missing a target ID`);
              }
            });
          }
        });
      }
      if (row.children) {
        row.children.forEach((child, i) => {
          validateRow(child, `${path} > child[${i}]`);
        });
      }
    };
    rows.forEach((row, i) => {
      validateRow(row, `root[${i}]`);
    });
  };
  return {
    importFromFile,
    isImporting,
    importProgress,
    lastError
  };
}
const colorSchemes = {
  default: {
    primary: "#eeeeee",
    secondary: "#E0E0E0",
    ternary: "#F5F5F5",
    quartenary: "#ededed",
    hoverHighlight: "rgba(204, 216, 219, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "#404040",
    background: "white",
    commands: "#eeeeee",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "rgba(0, 0, 0, 0.7)",
    rowContainer: "rgba(255, 255, 255, 1)",
    gridAndBorder: "#eaeaea"
  },
  creamy: {
    primary: "#ffe8d9",
    secondary: "#fcdcc5",
    ternary: "#fff6f0",
    quartenary: "#f7ece6",
    hoverHighlight: "rgba(230, 221, 202, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "#542d05",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#fcdcc5",
    rowContainer: "rgba(255, 255, 255, 1)",
    gridAndBorder: "#eaeaea"
  },
  crimson: {
    primary: "#a82039",
    secondary: "#c41238",
    ternary: "#db4f56",
    quartenary: "#ce5f64",
    hoverHighlight: "rgba(196, 141, 141, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "black",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#c41238",
    rowContainer: "rgba(255, 255, 255, 1)",
    gridAndBorder: "#eaeaea"
  },
  dark: {
    primary: "#404040",
    secondary: "#303030",
    ternary: "#353535",
    quartenary: "#383838",
    hoverHighlight: "rgba(159, 160, 161, 0.5)",
    markerCurrentTime: "#fff",
    markerPointer: "#fff",
    text: "white",
    background: "#525252",
    toast: "#1f1f1f",
    commands: "#525252",
    rangeHighlight: "#000",
    holidayHighlight: "#ff9d3b",
    barContainer: "rgba(0, 0, 0, 1)",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  flare: {
    primary: "#e08a38",
    secondary: "#e67912",
    ternary: "#5e5145",
    quartenary: "#665648",
    hoverHighlight: "rgba(196, 141, 141, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "white",
    background: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "rgba(0, 0, 0, 1)",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  fuchsia: {
    primary: "#de1d5a",
    secondary: "#b50b41",
    ternary: "#ff7da6",
    quartenary: "#f2799f",
    hoverHighlight: "rgba(196, 141, 141, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "white",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#de1d5a",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  grove: {
    primary: "#3d9960",
    secondary: "#288542",
    ternary: "#72b585",
    quartenary: "#65a577",
    hoverHighlight: "rgba(160, 219, 171, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "white",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#3d9960",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  "material-blue": {
    primary: "#0D47A1",
    secondary: "#1565C0",
    ternary: "#42a5f5",
    quartenary: "#409fed",
    hoverHighlight: "rgba(110, 165, 196, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "white",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#0D47A1",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  sky: {
    primary: "#b5e3ff",
    secondary: "#a1d6f7",
    ternary: "#d6f7ff",
    quartenary: "#d0edf4",
    hoverHighlight: "rgba(193, 202, 214, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "#022c47",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "rgb(20,20,20)",
    rowContainer: "#a1d6f7",
    gridAndBorder: "#eaeaea"
  },
  slumber: {
    primary: "#2a2f42",
    secondary: "#2f3447",
    ternary: "#35394d",
    quartenary: "#2c3044",
    hoverHighlight: "rgba(179, 162, 127, 0.5)",
    markerCurrentTime: "#fff",
    markerPointer: "#fff",
    text: "#ffe0b3",
    background: "#38383b",
    toast: "#1f1f1f",
    commands: "#38383b",
    rangeHighlight: "#000",
    holidayHighlight: "rgba(240, 120, 96, 0.8)",
    barContainer: "#2a2f42",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  },
  vue: {
    primary: "#258a5d",
    secondary: "#41B883",
    ternary: "#35495E",
    quartenary: "#2a3d51",
    hoverHighlight: "rgba(160, 219, 171, 0.5)",
    markerCurrentTime: "#000",
    markerPointer: "#000",
    text: "white",
    background: "white",
    commands: "white",
    rangeHighlight: "#000",
    holidayHighlight: "#f7842d",
    barContainer: "#258a5d",
    rowContainer: "rgba(0, 0, 0, 1)",
    gridAndBorder: "#eaeaea"
  }
};
const _hoisted_1$1 = {
  key: 0,
  class: "g-gantt-importer-overlay"
};
const _hoisted_2$1 = { class: "g-gantt-importer-content" };
const _hoisted_3$1 = { class: "g-gantt-importer-stepper" };
const _hoisted_4$1 = { key: 0 };
const _hoisted_5$1 = { key: 0 };
const _hoisted_6$1 = { key: 0 };
const _hoisted_7$1 = {
  key: 0,
  class: "g-gantt-importer-step"
};
const _hoisted_8$1 = { class: "g-gantt-file-upload" };
const _hoisted_9$1 = ["accept"];
const _hoisted_10$1 = {
  key: 1,
  class: "g-gantt-importer-step"
};
const _hoisted_11$1 = {
  key: 0,
  class: "g-gantt-selected-file"
};
const _hoisted_12$1 = { class: "g-gantt-import-options" };
const _hoisted_13$1 = { class: "g-gantt-option-group" };
const _hoisted_14$1 = ["value"];
const _hoisted_15$1 = { class: "g-gantt-option-toggle" };
const _hoisted_16$1 = { class: "g-gantt-option-group" };
const _hoisted_17$1 = { class: "g-gantt-option-group" };
const _hoisted_18$1 = { class: "g-gantt-import-actions" };
const _hoisted_19$1 = ["disabled"];
const _hoisted_20$1 = { key: 1 };
const _hoisted_21$1 = {
  key: 2,
  class: "g-gantt-importer-step"
};
const _hoisted_22$1 = { class: "g-gantt-import-result" };
const _hoisted_23$1 = {
  key: 0,
  class: "g-gantt-result-success"
};
const _hoisted_24$1 = { style: { color: "#aa8700" } };
const _hoisted_25$1 = {
  key: 1,
  class: "g-gantt-result-error"
};
const _hoisted_26$1 = { class: "g-gantt-result-actions" };
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
  __name: "GGanttImporter",
  props: {
    modelValue: { type: Boolean },
    title: {},
    defaultFormat: {},
    allowedFormats: {}
  },
  emits: ["update:modelValue", "import", "close"],
  setup(__props, { emit: __emit }) {
    const props = __props;
    const emit = __emit;
    const config = inject(CONFIG_KEY);
    if (!config) {
      throw Error("GGanttImporter must be used as a child of GGanttChart!");
    }
    const dateFormat = computed(() => config.dateFormat.value);
    const font = computed(() => config.font.value);
    const colorScheme = computed(() => config.colorScheme.value);
    const barStart = computed(() => config.barStart.value);
    const barEnd = computed(() => config.barEnd.value);
    const { importFromFile, isImporting, importProgress, lastError } = useImport();
    const visible = ref(props.modelValue || false);
    const selectedFormat = ref(props.defaultFormat || "csv");
    const selectedFile = ref(null);
    const fileInput = ref(null);
    const mapStartField = ref(barStart.value);
    const mapEndField = ref(barEnd.value);
    const importWarnings = ref([]);
    const importSuccess = ref(null);
    const showOptions = ref(false);
    const activeStep = ref(1);
    const fontStyle = computed(() => font.value || "inherit");
    const colors = computed(() => {
      if (typeof colorScheme.value === "string") {
        return colorSchemes[colorScheme.value] || colorSchemes.default;
      }
      return colorScheme.value || colorSchemes.default;
    });
    const textStyle = computed(() => colors.value.text);
    const backgroundStyle = computed(() => colors.value.background);
    const primaryStyle = computed(() => colors.value.primary);
    const secondaryStyle = computed(() => colors.value.secondary);
    const tertiaryStyle = computed(() => colors.value.ternary);
    const accentColor = computed(() => colors.value.rangeHighlight || "#4a9eff");
    const successColor = computed(() => "#4caf50");
    const errorColor = computed(() => "#f44336");
    const warningColor = computed(() => "#ffc107");
    const availableFormats = computed(() => {
      const formats = [
        { value: "jira", label: "Jira (JSON)" },
        { value: "csv", label: "CSV" }
      ];
      if (props.allowedFormats && props.allowedFormats.length > 0) {
        return formats.filter((f) => props.allowedFormats.includes(f.value));
      }
      return formats;
    });
    watch(
      () => props.modelValue,
      (newVal) => {
        visible.value = newVal || false;
      }
    );
    watch(visible, (newVal) => {
      emit("update:modelValue", newVal);
    });
    watch(barStart, (newVal) => {
      if (newVal) {
        mapStartField.value = newVal;
      }
    });
    watch(barEnd, (newVal) => {
      if (newVal) {
        mapEndField.value = newVal;
      }
    });
    const triggerFileInput = () => {
      var _a;
      (_a = fileInput.value) == null ? void 0 : _a.click();
    };
    const handleFileSelect = (event) => {
      const input = event.target;
      if (input.files && input.files.length > 0) {
        selectedFile.value = input.files[0];
        const fileName = selectedFile.value.name.toLowerCase();
        if (fileName.endsWith(".json")) {
          selectedFormat.value = "jira";
        } else if (fileName.endsWith(".csv")) {
          selectedFormat.value = "csv";
        }
        activeStep.value = 2;
      }
    };
    const startImport = async () => {
      if (!selectedFile.value) return;
      importWarnings.value = [];
      importSuccess.value = null;
      const options = {
        format: selectedFormat.value,
        dateFormat: dateFormat.value,
        mapFields: {
          startDate: mapStartField.value,
          endDate: mapEndField.value
        },
        colorScheme: colors.value,
        onProgress: (progress) => {
          importProgress.value = progress;
        }
      };
      const result = await importFromFile(selectedFile.value, options);
      if (result.success) {
        importSuccess.value = true;
        if (result.warnings) {
          importWarnings.value = result.warnings;
        }
        activeStep.value = 3;
        emit("import", result);
      } else {
        importSuccess.value = false;
      }
    };
    const reset = () => {
      selectedFile.value = null;
      importSuccess.value = null;
      importWarnings.value = [];
      activeStep.value = 1;
      if (fileInput.value) {
        fileInput.value.value = "";
      }
    };
    const close = () => {
      visible.value = false;
      reset();
      emit("close");
    };
    return (_ctx, _cache) => {
      return openBlock(), createBlock(Teleport, { to: "body" }, [
        createVNode(Transition, { name: "g-fade" }, {
          default: withCtx(() => [
            visible.value ? (openBlock(), createElementBlock("div", _hoisted_1$1, [
              createElementVNode("div", {
                class: "g-gantt-importer-modal",
                style: normalizeStyle({
                  fontFamily: fontStyle.value,
                  color: textStyle.value,
                  background: backgroundStyle.value
                })
              }, [
                createElementVNode("div", {
                  class: "g-gantt-importer-header",
                  style: normalizeStyle({ background: primaryStyle.value })
                }, [
                  createElementVNode("h3", null, toDisplayString(_ctx.title || "Import Data"), 1),
                  createElementVNode("button", {
                    class: "g-gantt-importer-close-btn",
                    onClick: close,
                    style: normalizeStyle({ color: textStyle.value })
                  }, [
                    createVNode(unref(FontAwesomeIcon), { icon: unref(faXmark) }, null, 8, ["icon"])
                  ], 4)
                ], 4),
                createElementVNode("div", _hoisted_2$1, [
                  createElementVNode("div", _hoisted_3$1, [
                    createElementVNode("div", {
                      class: normalizeClass(["g-gantt-stepper-step", { active: activeStep.value === 1, completed: activeStep.value > 1 }])
                    }, [
                      createElementVNode("div", {
                        class: "g-gantt-step-number",
                        style: normalizeStyle({
                          backgroundColor: activeStep.value === 1 ? accentColor.value : activeStep.value > 1 ? successColor.value : "#e0e0e0",
                          color: activeStep.value >= 1 ? "white" : textStyle.value
                        })
                      }, [
                        activeStep.value <= 1 ? (openBlock(), createElementBlock("span", _hoisted_4$1, "1")) : (openBlock(), createBlock(unref(FontAwesomeIcon), {
                          key: 1,
                          icon: unref(faCheck)
                        }, null, 8, ["icon"]))
                      ], 4),
                      createElementVNode("div", {
                        class: "g-gantt-step-label",
                        style: normalizeStyle({ color: activeStep.value === 1 ? textStyle.value : secondaryStyle.value })
                      }, " Select File ", 4)
                    ], 2),
                    createElementVNode("div", {
                      class: "g-gantt-step-connector",
                      style: normalizeStyle({ backgroundColor: colors.value.gridAndBorder })
                    }, null, 4),
                    createElementVNode("div", {
                      class: normalizeClass(["g-gantt-stepper-step", { active: activeStep.value === 2, completed: activeStep.value > 2 }])
                    }, [
                      createElementVNode("div", {
                        class: "g-gantt-step-number",
                        style: normalizeStyle({
                          backgroundColor: activeStep.value === 2 ? accentColor.value : activeStep.value > 2 ? successColor.value : "#e0e0e0",
                          color: activeStep.value >= 2 ? "white" : textStyle.value
                        })
                      }, [
                        activeStep.value <= 2 ? (openBlock(), createElementBlock("span", _hoisted_5$1, "2")) : (openBlock(), createBlock(unref(FontAwesomeIcon), {
                          key: 1,
                          icon: unref(faCheck)
                        }, null, 8, ["icon"]))
                      ], 4),
                      createElementVNode("div", {
                        class: "g-gantt-step-label",
                        style: normalizeStyle({ color: activeStep.value === 2 ? textStyle.value : secondaryStyle.value })
                      }, " Configure ", 4)
                    ], 2),
                    createElementVNode("div", {
                      class: "g-gantt-step-connector",
                      style: normalizeStyle({ backgroundColor: colors.value.gridAndBorder })
                    }, null, 4),
                    createElementVNode("div", {
                      class: normalizeClass(["g-gantt-stepper-step", { active: activeStep.value === 3, completed: activeStep.value > 3 }])
                    }, [
                      createElementVNode("div", {
                        class: "g-gantt-step-number",
                        style: normalizeStyle({
                          backgroundColor: activeStep.value === 3 ? accentColor.value : activeStep.value > 3 ? successColor.value : "#e0e0e0",
                          color: activeStep.value >= 3 ? "white" : textStyle.value
                        })
                      }, [
                        activeStep.value <= 3 ? (openBlock(), createElementBlock("span", _hoisted_6$1, "3")) : (openBlock(), createBlock(unref(FontAwesomeIcon), {
                          key: 1,
                          icon: unref(faCheck)
                        }, null, 8, ["icon"]))
                      ], 4),
                      createElementVNode("div", {
                        class: "g-gantt-step-label",
                        style: normalizeStyle({ color: activeStep.value === 3 ? textStyle.value : secondaryStyle.value })
                      }, " Result ", 4)
                    ], 2)
                  ]),
                  activeStep.value === 1 ? (openBlock(), createElementBlock("div", _hoisted_7$1, [
                    createElementVNode("div", _hoisted_8$1, [
                      createElementVNode("div", {
                        class: "g-gantt-file-dropzone",
                        onClick: triggerFileInput,
                        onDragover: _cache[0] || (_cache[0] = withModifiers(() => {
                        }, ["prevent"])),
                        onDrop: _cache[1] || (_cache[1] = withModifiers(
                          (e) => {
                            var _a;
                            const files = (_a = e.dataTransfer) == null ? void 0 : _a.files;
                            if (files && files.length > 0) {
                              selectedFile.value = files[0];
                              activeStep.value = 2;
                            }
                          },
                          ["prevent"]
                        )),
                        style: normalizeStyle({
                          borderColor: colors.value.gridAndBorder
                        })
                      }, [
                        createVNode(unref(FontAwesomeIcon), {
                          icon: unref(faFileImport),
                          class: "file-icon",
                          style: normalizeStyle({ color: accentColor.value })
                        }, null, 8, ["icon", "style"]),
                        _cache[7] || (_cache[7] = createElementVNode("p", null, "Click or drag a file here to import", -1)),
                        createElementVNode("small", null, "Supported formats: " + toDisplayString(availableFormats.value.map((f) => f.label).join(", ")), 1)
                      ], 36),
                      createElementVNode("input", {
                        type: "file",
                        ref_key: "fileInput",
                        ref: fileInput,
                        onChange: handleFileSelect,
                        class: "g-gantt-file-input",
                        accept: availableFormats.value.map((f) => {
                          switch (f.value) {
                            case "jira":
                              return ".json";
                            case "csv":
                              return ".csv";
                            default:
                              return "";
                          }
                        }).filter(Boolean).join(",")
                      }, null, 40, _hoisted_9$1)
                    ])
                  ])) : activeStep.value === 2 ? (openBlock(), createElementBlock("div", _hoisted_10$1, [
                    selectedFile.value ? (openBlock(), createElementBlock("div", _hoisted_11$1, [
                      createElementVNode("div", {
                        class: "g-gantt-file-info",
                        style: normalizeStyle({ backgroundColor: tertiaryStyle.value })
                      }, [
                        createElementVNode("div", null, [
                          _cache[8] || (_cache[8] = createElementVNode("strong", null, "Selected file:", -1)),
                          createTextVNode(" " + toDisplayString(selectedFile.value.name), 1)
                        ]),
                        createElementVNode("div", null, [
                          _cache[9] || (_cache[9] = createElementVNode("strong", null, "Size:", -1)),
                          createTextVNode(" " + toDisplayString((selectedFile.value.size / 1024).toFixed(2)) + " KB", 1)
                        ])
                      ], 4),
                      createElementVNode("div", _hoisted_12$1, [
                        createElementVNode("div", _hoisted_13$1, [
                          _cache[10] || (_cache[10] = createElementVNode("label", null, "Format", -1)),
                          withDirectives(createElementVNode("select", {
                            "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => selectedFormat.value = $event),
                            style: normalizeStyle({ borderColor: colors.value.gridAndBorder })
                          }, [
                            (openBlock(true), createElementBlock(Fragment, null, renderList(availableFormats.value, (format) => {
                              return openBlock(), createElementBlock("option", {
                                key: format.value,
                                value: format.value
                              }, toDisplayString(format.label), 9, _hoisted_14$1);
                            }), 128))
                          ], 4), [
                            [vModelSelect, selectedFormat.value]
                          ])
                        ]),
                        createElementVNode("div", _hoisted_15$1, [
                          createElementVNode("button", {
                            class: "g-gantt-toggle-btn",
                            onClick: _cache[3] || (_cache[3] = ($event) => showOptions.value = !showOptions.value),
                            style: normalizeStyle({ color: accentColor.value })
                          }, toDisplayString(showOptions.value ? "Hide advanced options" : "Show advanced options"), 5)
                        ]),
                        showOptions.value ? (openBlock(), createElementBlock("div", {
                          key: 0,
                          class: "g-gantt-advanced-options",
                          style: normalizeStyle({ borderTopColor: colors.value.gridAndBorder })
                        }, [
                          createElementVNode("div", _hoisted_16$1, [
                            _cache[11] || (_cache[11] = createElementVNode("label", null, "Start date field", -1)),
                            withDirectives(createElementVNode("input", {
                              type: "text",
                              "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => mapStartField.value = $event),
                              style: normalizeStyle({ borderColor: colors.value.gridAndBorder })
                            }, null, 4), [
                              [vModelText, mapStartField.value]
                            ])
                          ]),
                          createElementVNode("div", _hoisted_17$1, [
                            _cache[12] || (_cache[12] = createElementVNode("label", null, "End date field", -1)),
                            withDirectives(createElementVNode("input", {
                              type: "text",
                              "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => mapEndField.value = $event),
                              style: normalizeStyle({ borderColor: colors.value.gridAndBorder })
                            }, null, 4), [
                              [vModelText, mapEndField.value]
                            ])
                          ])
                        ], 4)) : createCommentVNode("", true)
                      ]),
                      createElementVNode("div", _hoisted_18$1, [
                        createElementVNode("button", {
                          class: "g-gantt-button secondary",
                          onClick: _cache[6] || (_cache[6] = ($event) => activeStep.value = 1),
                          style: normalizeStyle({
                            backgroundColor: secondaryStyle.value,
                            color: textStyle.value
                          })
                        }, " Back ", 4),
                        createElementVNode("button", {
                          class: "g-gantt-button primary",
                          onClick: startImport,
                          disabled: unref(isImporting),
                          style: normalizeStyle({
                            backgroundColor: accentColor.value,
                            color: "white"
                          })
                        }, [
                          unref(isImporting) ? (openBlock(), createBlock(unref(FontAwesomeIcon), {
                            key: 0,
                            icon: unref(faSpinner),
                            class: "fa-spin"
                          }, null, 8, ["icon"])) : (openBlock(), createElementBlock("span", _hoisted_20$1, "Import"))
                        ], 12, _hoisted_19$1)
                      ])
                    ])) : createCommentVNode("", true)
                  ])) : activeStep.value === 3 ? (openBlock(), createElementBlock("div", _hoisted_21$1, [
                    createElementVNode("div", _hoisted_22$1, [
                      importSuccess.value ? (openBlock(), createElementBlock("div", _hoisted_23$1, [
                        createVNode(unref(FontAwesomeIcon), {
                          icon: unref(faCheck),
                          class: "result-icon success",
                          style: normalizeStyle({
                            color: successColor.value,
                            backgroundColor: `rgba(${parseInt(successColor.value.slice(1, 3), 16)}, 
                                                    ${parseInt(successColor.value.slice(3, 5), 16)}, 
                                                    ${parseInt(successColor.value.slice(5, 7), 16)}, 0.1)`
                          })
                        }, null, 8, ["icon", "style"]),
                        _cache[13] || (_cache[13] = createElementVNode("h4", null, "Import completed successfully", -1)),
                        importWarnings.value.length > 0 ? (openBlock(), createElementBlock("div", {
                          key: 0,
                          class: "g-gantt-warnings",
                          style: normalizeStyle({
                            backgroundColor: `rgba(${parseInt(warningColor.value.slice(1, 3), 16)}, 
                                         ${parseInt(warningColor.value.slice(3, 5), 16)}, 
                                         ${parseInt(warningColor.value.slice(5, 7), 16)}, 0.1)`,
                            borderLeftColor: warningColor.value
                          })
                        }, [
                          createElementVNode("h5", _hoisted_24$1, [
                            createVNode(unref(FontAwesomeIcon), { icon: unref(faExclamationTriangle) }, null, 8, ["icon"]),
                            createTextVNode(" Warnings (" + toDisplayString(importWarnings.value.length) + ") ", 1)
                          ]),
                          createElementVNode("ul", null, [
                            (openBlock(true), createElementBlock(Fragment, null, renderList(importWarnings.value, (warning, index) => {
                              return openBlock(), createElementBlock("li", {
                                key: index,
                                style: { color: "#aa8700" }
                              }, toDisplayString(warning), 1);
                            }), 128))
                          ])
                        ], 4)) : createCommentVNode("", true)
                      ])) : importSuccess.value === false ? (openBlock(), createElementBlock("div", _hoisted_25$1, [
                        createVNode(unref(FontAwesomeIcon), {
                          icon: unref(faXmark),
                          class: "result-icon error",
                          style: normalizeStyle({
                            color: errorColor.value,
                            backgroundColor: `rgba(${parseInt(errorColor.value.slice(1, 3), 16)}, 
                                                    ${parseInt(errorColor.value.slice(3, 5), 16)}, 
                                                    ${parseInt(errorColor.value.slice(5, 7), 16)}, 0.1)`
                          })
                        }, null, 8, ["icon", "style"]),
                        _cache[14] || (_cache[14] = createElementVNode("h4", null, "Error during import", -1)),
                        createElementVNode("p", null, toDisplayString(unref(lastError)), 1)
                      ])) : createCommentVNode("", true),
                      createElementVNode("div", _hoisted_26$1, [
                        createElementVNode("button", {
                          class: "g-gantt-button secondary",
                          onClick: reset,
                          style: normalizeStyle({
                            backgroundColor: secondaryStyle.value,
                            color: textStyle.value
                          })
                        }, " Import another file ", 4),
                        createElementVNode("button", {
                          class: "g-gantt-button primary",
                          onClick: close,
                          style: normalizeStyle({
                            backgroundColor: accentColor.value,
                            color: "white"
                          })
                        }, " Close ", 4)
                      ])
                    ])
                  ])) : createCommentVNode("", true)
                ])
              ], 4)
            ])) : createCommentVNode("", true)
          ]),
          _: 1
        })
      ]);
    };
  }
});
function useConnections(rowManager, props, id, emit) {
  const connections = ref([]);
  const barPositions = ref(/* @__PURE__ */ new Map());
  const selectedConnection = ref(null);
  const getConnectorProps = computed(() => (conn) => {
    var _a, _b;
    const sourceBar = barPositions.value.get(conn.sourceId);
    const targetBar = barPositions.value.get(conn.targetId);
    if (!sourceBar || !targetBar) {
      return null;
    }
    const connectionProps = {
      type: conn.type ?? props.defaultConnectionType,
      color: conn.color ?? props.defaultConnectionColor,
      pattern: conn.pattern ?? props.defaultConnectionPattern,
      animated: conn.animated ?? props.defaultConnectionAnimated,
      animationSpeed: conn.animationSpeed ?? props.defaultConnectionAnimationSpeed,
      relation: conn.relation ?? props.defaultConnectionRelation,
      label: conn.label ?? props.defaultConnectionLabel,
      labelAlwaysVisible: conn.labelAlwaysVisible ?? props.defaultConnectionLabelAlwaysVisible,
      labelStyle: conn.labelStyle ?? props.defaultConnectionLabelStyle,
      isSelected: ((_a = selectedConnection.value) == null ? void 0 : _a.sourceId) === conn.sourceId && ((_b = selectedConnection.value) == null ? void 0 : _b.targetId) === conn.targetId
    };
    return {
      sourceBar,
      targetBar,
      ...connectionProps
    };
  });
  const handleConnectionClick = (connection) => {
    var _a, _b;
    if (((_a = selectedConnection.value) == null ? void 0 : _a.sourceId) === connection.sourceId && ((_b = selectedConnection.value) == null ? void 0 : _b.targetId) === connection.targetId) {
      selectedConnection.value = null;
    } else {
      selectedConnection.value = connection;
    }
  };
  const deleteSelectedConnection = () => {
    if (!selectedConnection.value) return;
    const allBars = getAllBars(rowManager.rows.value);
    const sourceBar = allBars.find(
      (bar) => {
        var _a;
        return bar.ganttBarConfig.id === ((_a = selectedConnection.value) == null ? void 0 : _a.sourceId);
      }
    );
    if (sourceBar && sourceBar.ganttBarConfig.connections) {
      sourceBar.ganttBarConfig.connections = sourceBar.ganttBarConfig.connections.filter(
        (conn) => {
          var _a;
          return conn.targetId !== ((_a = selectedConnection.value) == null ? void 0 : _a.targetId);
        }
      );
      const targetBar = allBars.find(
        (bar) => {
          var _a;
          return bar.ganttBarConfig.id === ((_a = selectedConnection.value) == null ? void 0 : _a.targetId);
        }
      );
      emit("connection-delete", {
        sourceBar,
        targetBar,
        e: new MouseEvent("mouseup")
      });
      selectedConnection.value = null;
      initializeConnections();
      rowManager.onBarMove();
    }
  };
  const getAllBars = (rows) => {
    return rows.flatMap((row) => {
      var _a;
      const bars = [...row.bars];
      if ((_a = row.children) == null ? void 0 : _a.length) {
        return [...bars, ...getAllBars(row.children)];
      }
      return bars;
    });
  };
  const initializeConnections = () => {
    connections.value = [];
    const allBars = getAllBars(rowManager.rows.value);
    allBars.forEach((el) => {
      var _a;
      if ((_a = el.ganttBarConfig.connections) == null ? void 0 : _a.length) {
        el.ganttBarConfig.connections.forEach((conn) => {
          connections.value.push({
            sourceId: el.ganttBarConfig.id,
            targetId: conn.targetId,
            type: conn.type,
            color: conn.color,
            pattern: conn.pattern,
            animated: conn.animated,
            animationSpeed: conn.animationSpeed,
            relation: conn.relation,
            label: conn.label,
            labelAlwaysVisible: conn.labelAlwaysVisible,
            labelStyle: conn.labelStyle
          });
        });
      }
    });
  };
  watch(
    () => rowManager.rows.value,
    () => {
      initializeConnections();
    },
    { deep: true }
  );
  const updateBarPositions = async () => {
    await new Promise((resolve) => requestAnimationFrame(resolve));
    const parentElement = document.getElementById(id.value);
    const rowsContainer = parentElement.querySelector(".g-gantt-rows-container");
    if (!rowsContainer) return;
    const scrollTop = rowsContainer.scrollTop;
    const scrollLeft = rowsContainer.scrollLeft;
    const containerRect = rowsContainer.getBoundingClientRect();
    const bars = parentElement.querySelectorAll(".g-gantt-bar");
    barPositions.value.clear();
    bars.forEach((bar) => {
      const rect = bar.getBoundingClientRect();
      const barId = bar.getAttribute("id");
      if (barId) {
        const position = {
          id: barId,
          x: rect.left - containerRect.left + scrollLeft,
          y: rect.top - containerRect.top + scrollTop,
          width: rect.width,
          height: rect.height
        };
        barPositions.value.set(barId, position);
      }
    });
  };
  return {
    connections,
    barPositions,
    getConnectorProps,
    initializeConnections,
    updateBarPositions,
    handleConnectionClick,
    selectedConnection,
    deleteSelectedConnection
  };
}
function useTooltip() {
  const showTooltip = ref(false);
  const tooltipBar = ref(void 0);
  let tooltipTimeoutId;
  const initTooltip = (bar) => {
    if (tooltipTimeoutId) {
      clearTimeout(tooltipTimeoutId);
    }
    tooltipTimeoutId = setTimeout(() => {
      showTooltip.value = true;
    }, 800);
    tooltipBar.value = bar;
  };
  const clearTooltip = () => {
    clearTimeout(tooltipTimeoutId);
    showTooltip.value = false;
  };
  return {
    showTooltip,
    tooltipBar,
    initTooltip,
    clearTooltip
  };
}
function useChartNavigation(options, maxRows) {
  const { scrollRefs, updateBarPositions, timeaxisUnits } = options;
  const { adjustZoomAndPrecision } = timeaxisUnits;
  const scrollPosition = ref(0);
  const isAtTop = ref(true);
  const isAtBottom = ref(false);
  const totalWidth = computed(() => {
    return timeaxisUnits.timeaxisUnits.value.result.lowerUnits.reduce((total, unit) => {
      return total + parseInt(unit.width);
    }, 0);
  });
  const handleStep = (newPosition, wrapper) => {
    const maxScroll = totalWidth.value - wrapper.clientWidth;
    const targetScroll = maxScroll * newPosition / 100;
    wrapper.scrollLeft = targetScroll;
    scrollPosition.value = newPosition;
  };
  const handleScroll = (wrapper) => {
    const maxScroll = totalWidth.value - wrapper.clientWidth;
    const targetScroll = maxScroll * scrollPosition.value / 100;
    wrapper.scrollLeft = targetScroll;
  };
  const handleWheel = (e, wrapper) => {
    if (maxRows !== 0) {
      if (e.deltaX !== 0) {
        e.preventDefault();
      }
      return;
    }
    wrapper.scrollLeft += e.deltaX || e.deltaY;
    const maxScroll = totalWidth.value - wrapper.clientWidth;
    scrollPosition.value = wrapper.scrollLeft / maxScroll * 100;
  };
  const handleZoomUpdate = async (increase) => {
    adjustZoomAndPrecision(increase);
    await nextTick();
    updateBarPositions();
  };
  const handleContentScroll = (e) => {
    const target = e.target;
    if (scrollRefs.labelColumn.value) {
      scrollRefs.labelColumn.value.setScroll(target.scrollTop);
    }
    updateVerticalScrollState();
  };
  const handleLabelScroll = (scrollTop) => {
    if (scrollRefs.rowsContainer.value) {
      scrollRefs.rowsContainer.value.scrollTop = scrollTop;
      updateVerticalScrollState();
    }
  };
  const updateVerticalScrollState = () => {
    if (!scrollRefs.rowsContainer.value) return;
    const { scrollTop, scrollHeight, clientHeight } = scrollRefs.rowsContainer.value;
    isAtTop.value = scrollTop === 0;
    isAtBottom.value = Math.ceil(scrollTop + clientHeight) >= scrollHeight;
  };
  const scrollRowUp = () => {
    var _a;
    if (!scrollRefs.rowsContainer.value) return;
    const currentScroll = scrollRefs.rowsContainer.value.scrollTop;
    const rowHeight = ((_a = scrollRefs.rowsContainer.value.firstElementChild) == null ? void 0 : _a.clientHeight) || 0;
    scrollRefs.rowsContainer.value.scrollTop = Math.max(0, currentScroll - rowHeight);
    handleContentScroll(createScrollEvent(scrollRefs.rowsContainer.value));
  };
  const scrollRowDown = () => {
    var _a;
    if (!scrollRefs.rowsContainer.value) return;
    const currentScroll = scrollRefs.rowsContainer.value.scrollTop;
    const rowHeight = ((_a = scrollRefs.rowsContainer.value.firstElementChild) == null ? void 0 : _a.clientHeight) || 0;
    const maxScroll = scrollRefs.rowsContainer.value.scrollHeight - scrollRefs.rowsContainer.value.clientHeight;
    scrollRefs.rowsContainer.value.scrollTop = Math.min(maxScroll, currentScroll + rowHeight);
    handleContentScroll(createScrollEvent(scrollRefs.rowsContainer.value));
  };
  const createScrollEvent = (target) => {
    const event = new Event("scroll", {
      bubbles: true,
      cancelable: true
    });
    Object.defineProperty(event, "target", {
      value: target,
      enumerable: true
    });
    return event;
  };
  return {
    scrollPosition,
    isAtTop,
    isAtBottom,
    handleStep,
    handleScroll,
    handleWheel,
    handleContentScroll,
    handleLabelScroll,
    handleZoomUpdate,
    scrollRowUp,
    scrollRowDown
  };
}
function useKeyboardNavigation(chartNavigation, wrapperRef, ganttContainerRef, connectionControls, enableConnectionDeletion) {
  const { handleStep, handleZoomUpdate, scrollPosition } = chartNavigation;
  const { selectedConnection, deleteSelectedConnection } = connectionControls;
  const handleKeyDown = (event) => {
    const target = event.target;
    if (!ganttContainerRef.value || target !== ganttContainerRef.value) {
      return;
    }
    if (selectedConnection.value && enableConnectionDeletion.value) {
      switch (event.key) {
        case "Delete":
          deleteSelectedConnection();
          return;
        case "Escape":
          selectedConnection.value = null;
          return;
      }
    }
    switch (event.key) {
      case "ArrowLeft":
        if (wrapperRef.value && scrollPosition.value > 0) {
          handleStep(Math.max(0, scrollPosition.value - 10), wrapperRef.value);
        }
        break;
      case "ArrowRight":
        if (wrapperRef.value && scrollPosition.value < 100) {
          handleStep(Math.min(100, scrollPosition.value + 10), wrapperRef.value);
        }
        break;
      case "+":
        handleZoomUpdate(true);
        break;
      case "-":
        handleZoomUpdate(false);
        break;
      case "Home":
        if (wrapperRef.value) {
          handleStep(0, wrapperRef.value);
        }
        break;
      case "End":
        if (wrapperRef.value) {
          handleStep(100, wrapperRef.value);
        }
        break;
      case "PageUp":
        if (wrapperRef.value && scrollPosition.value >= 10) {
          handleStep(scrollPosition.value - 10, wrapperRef.value);
        } else if (wrapperRef.value) {
          handleStep(0, wrapperRef.value);
        }
        break;
      case "PageDown":
        if (wrapperRef.value && scrollPosition.value <= 90) {
          handleStep(scrollPosition.value + 10, wrapperRef.value);
        } else if (wrapperRef.value) {
          handleStep(100, wrapperRef.value);
        }
        break;
    }
  };
  return {
    handleKeyDown
  };
}
function createHistoryState(rows, expandedGroups, customOrder) {
  const prepareRowForCloning = (row) => {
    var _a, _b;
    const cleanRow = {
      id: row.id,
      label: row.label,
      bars: ((_a = row.bars) == null ? void 0 : _a.map((bar) => ({
        ...bar,
        ganttBarConfig: {
          id: bar.ganttBarConfig.id,
          label: bar.ganttBarConfig.label,
          html: bar.ganttBarConfig.html,
          hasHandles: bar.ganttBarConfig.hasHandles,
          immobile: bar.ganttBarConfig.immobile,
          bundle: bar.ganttBarConfig.bundle,
          pushOnOverlap: bar.ganttBarConfig.pushOnOverlap,
          pushOnConnect: bar.ganttBarConfig.pushOnConnect,
          style: bar.ganttBarConfig.style,
          class: bar.ganttBarConfig.class,
          connections: bar.ganttBarConfig.connections,
          milestoneId: bar.ganttBarConfig.milestoneId,
          progress: bar.ganttBarConfig.progress,
          progressStyle: bar.ganttBarConfig.progressStyle,
          progressResizable: bar.ganttBarConfig.progressResizable
        }
      }))) || [],
      connections: row.connections,
      children: (_b = row.children) == null ? void 0 : _b.map(prepareRowForCloning)
    };
    return cleanRow;
  };
  const preparedRows = rows.map(prepareRowForCloning);
  return {
    rows: cloneDeep(preparedRows),
    expandedGroups: new Set(expandedGroups),
    customOrder: new Map(customOrder),
    timestamp: Date.now()
  };
}
function restoreState(state, originalRows) {
  const restoreRow = (historyRow, originalRow) => {
    const restored = cloneDeep(historyRow);
    if (originalRow) {
      restored._originalNode = originalRow._originalNode;
    }
    if (restored.children && (originalRow == null ? void 0 : originalRow.children)) {
      restored.children = restored.children.map(
        (child, index) => restoreRow(child, originalRow.children[index])
      );
    }
    return restored;
  };
  return {
    rows: state.rows.map((historyRow) => {
      const originalRow = originalRows.find((r) => r.id === historyRow.id);
      return restoreRow(historyRow, originalRow);
    }),
    expandedGroups: new Set(state.expandedGroups),
    customOrder: new Map(state.customOrder)
  };
}
function findParentId(rows, path) {
  if (path.length <= 1) return void 0;
  let current = rows[path[0]];
  for (let i = 1; i < path.length - 1; i++) {
    if (!(current == null ? void 0 : current.children)) return void 0;
    current = current.children[path[i]];
  }
  return current == null ? void 0 : current.id;
}
function findBarInRows(rows, barId) {
  for (const row of rows) {
    const found = row.bars.find((bar) => bar.ganttBarConfig.id === barId);
    if (found) return found;
    if (row.children) {
      const foundInChildren = findBarInRows(row.children, barId);
      if (foundInChildren) return foundInChildren;
    }
  }
  return null;
}
function findRowById(rows, id) {
  for (const row of rows) {
    if (row.id === id) return row;
    if (row.children) {
      const found = findRowById(row.children, id);
      if (found) return found;
    }
  }
  return null;
}
function findRowPath(rows, id) {
  for (let i = 0; i < rows.length; i++) {
    if (rows[i].id === id) return [i];
    if (rows[i].children) {
      const childPath = findRowPath(rows[i].children, id);
      if (childPath.length) return [i, ...childPath];
    }
  }
  return [];
}
function findRowIdForBar(barId, rows) {
  function searchInRows(rows2) {
    for (const row of rows2) {
      if (row.bars.some((bar) => bar.ganttBarConfig.id === barId)) {
        return row.id;
      }
      if (row.children) {
        const foundId = searchInRows(row.children);
        if (foundId) return foundId;
      }
    }
    return null;
  }
  return searchInRows(rows) || "";
}
function getAllBarsFromState(state) {
  const barsMap = /* @__PURE__ */ new Map();
  function collectBars(rows) {
    rows.forEach((row) => {
      row.bars.forEach((bar) => {
        barsMap.set(bar.ganttBarConfig.id, bar);
      });
      if (row.children) {
        collectBars(row.children);
      }
    });
  }
  collectBars(state.rows);
  return barsMap;
}
function compareBarStates(oldBar, newBar, barStart, barEnd, rows) {
  if (oldBar[barStart.value] === newBar[barStart.value] && oldBar[barEnd.value] === newBar[barEnd.value]) {
    return null;
  }
  return {
    barId: oldBar.ganttBarConfig.id,
    rowId: findRowIdForBar(oldBar.ganttBarConfig.id, rows.value),
    oldStart: oldBar[barStart.value],
    newStart: newBar[barStart.value],
    oldEnd: oldBar[barEnd.value],
    newEnd: newBar[barEnd.value]
  };
}
function compareAllBars(oldState, newState, barStart, barEnd, rows) {
  const changes = [];
  const oldBars = getAllBarsFromState(oldState);
  const newBars = getAllBarsFromState(newState);
  oldBars.forEach((oldBar, barId) => {
    const newBar = newBars.get(barId);
    if (newBar) {
      const change = compareBarStates(oldBar, newBar, barStart, barEnd, rows);
      if (change) {
        changes.push(change);
      }
    }
  });
  return changes;
}
function calculateHistoryChanges(prevState, newState, barStart, barEnd, rows) {
  const rowChanges = [];
  function compareRows(oldRows) {
    for (const oldRow of oldRows) {
      if (!oldRow.id) continue;
      const oldPath = findRowPath(prevState.rows, oldRow.id);
      const newPath = findRowPath(newState.rows, oldRow.id);
      if (oldPath.length !== newPath.length || !oldPath.every((v, i) => v === newPath[i])) {
        const oldParentId = oldPath.length > 1 ? findParentId(prevState.rows, oldPath) : void 0;
        const newParentId = newPath.length > 1 ? findParentId(newState.rows, newPath) : void 0;
        rowChanges.push({
          type: oldParentId !== newParentId ? "group" : "reorder",
          sourceRow: oldRow,
          oldIndex: oldPath[oldPath.length - 1],
          newIndex: newPath[newPath.length - 1],
          oldParentId,
          newParentId
        });
      }
      if (oldRow.children) {
        const newRow = findRowById(newState.rows, oldRow.id);
        if (newRow == null ? void 0 : newRow.children) {
          compareRows(oldRow.children);
        }
      }
    }
  }
  compareRows(prevState.rows);
  const barChanges = compareAllBars(prevState, newState, barStart, barEnd, rows);
  return {
    rowChanges,
    barChanges
  };
}
const MAX_HISTORY_STATES = 50;
function useRows(slots, {
  barStart,
  barEnd,
  dateFormat,
  multiColumnLabel,
  onSort,
  initialSort,
  onGroupExpansion
}, initialRows) {
  const sortState = ref({
    column: initialSort.column,
    direction: initialSort.direction
  });
  const sortChangeCallbacks = ref(/* @__PURE__ */ new Set());
  const expandedGroups = ref(/* @__PURE__ */ new Set());
  const groupExpansionCallbacks = ref(/* @__PURE__ */ new Set());
  const customOrder = ref(/* @__PURE__ */ new Map());
  const reorderedRows = ref([]);
  const historyStates = ref([]);
  const currentHistoryIndex = ref(-1);
  const initializeHistory = () => {
    historyStates.value = [
      createHistoryState(reorderedRows.value, expandedGroups.value, customOrder.value)
    ];
    currentHistoryIndex.value = 0;
  };
  onMounted(() => {
    initializeHistory();
  });
  const canUndo = computed(() => currentHistoryIndex.value > 0 && historyStates.value.length > 1);
  const canRedo = computed(
    () => historyStates.value.length > 1 && currentHistoryIndex.value < historyStates.value.length - 1
  );
  const addHistoryState = () => {
    if (currentHistoryIndex.value < historyStates.value.length - 1) {
      historyStates.value = historyStates.value.slice(0, currentHistoryIndex.value + 1);
    }
    historyStates.value.push(
      createHistoryState(reorderedRows.value, expandedGroups.value, customOrder.value)
    );
    currentHistoryIndex.value++;
    if (historyStates.value.length > MAX_HISTORY_STATES) {
      const excess = historyStates.value.length - MAX_HISTORY_STATES;
      historyStates.value = historyStates.value.slice(excess);
      currentHistoryIndex.value = Math.max(0, currentHistoryIndex.value - excess);
    }
  };
  const undo = () => {
    const currentState = historyStates.value[currentHistoryIndex.value];
    currentHistoryIndex.value--;
    const previousState = historyStates.value[currentHistoryIndex.value];
    const changes = calculateHistoryChanges(currentState, previousState, barStart, barEnd, rows);
    const restored = restoreState(previousState, reorderedRows.value);
    reorderedRows.value = restored.rows;
    customOrder.value = restored.customOrder;
    return changes;
  };
  const redo = () => {
    const currentState = historyStates.value[currentHistoryIndex.value];
    currentHistoryIndex.value++;
    const nextState = historyStates.value[currentHistoryIndex.value];
    const changes = calculateHistoryChanges(currentState, nextState, barStart, barEnd, rows);
    const restored = restoreState(nextState, reorderedRows.value);
    reorderedRows.value = restored.rows;
    customOrder.value = restored.customOrder;
    return changes;
  };
  const onBarMove = () => {
    addHistoryState();
  };
  const clearHistory = () => {
    initializeHistory();
  };
  const extractRowsFromSlots = () => {
    var _a;
    const defaultSlot = (_a = slots.default) == null ? void 0 : _a.call(slots);
    const rows2 = [];
    if (!defaultSlot) return rows2;
    defaultSlot.forEach((child) => {
      var _a2, _b;
      if (((_a2 = child.props) == null ? void 0 : _a2.bars) || ((_b = child.props) == null ? void 0 : _b.children)) {
        const { label, bars = [], children = [], id, connections = [] } = child.props;
        rows2.push({
          id,
          label,
          bars,
          children,
          connections,
          _originalNode: child
        });
      } else if (Array.isArray(child.children)) {
        child.children.forEach((grandchild) => {
          var _a3, _b2;
          const grandchildNode = grandchild;
          if (((_a3 = grandchildNode == null ? void 0 : grandchildNode.props) == null ? void 0 : _a3.bars) || ((_b2 = grandchildNode == null ? void 0 : grandchildNode.props) == null ? void 0 : _b2.children)) {
            const { label, bars = [], children = [], id, connections = [] } = grandchildNode.props;
            rows2.push({
              id,
              label,
              bars,
              children,
              connections,
              _originalNode: grandchildNode
            });
          }
        });
      }
    });
    return rows2;
  };
  const getSourceRows = () => {
    var _a;
    if ((_a = initialRows == null ? void 0 : initialRows.value) == null ? void 0 : _a.length) {
      return initialRows.value;
    }
    return extractRowsFromSlots();
  };
  reorderedRows.value = getSourceRows();
  watch(
    () => getSourceRows(),
    (newRows) => {
      reorderedRows.value = newRows;
    }
  );
  const calculateGroupBars = (row) => {
    var _a;
    if (!((_a = row.children) == null ? void 0 : _a.length)) return row.bars || [];
    const allChildBars = row.children.flatMap((child) => {
      const childGroupBars = calculateGroupBars(child);
      return [...childGroupBars, ...child.bars || []];
    });
    if (!allChildBars.length) return [];
    const minStart = allChildBars.reduce(
      (min, bar) => {
        const currentStart = toDayjs(bar[barStart.value]);
        return !min || currentStart.isBefore(min) ? currentStart : min;
      },
      null
    );
    const maxEnd = allChildBars.reduce(
      (max, bar) => {
        const currentEnd = toDayjs(bar[barEnd.value]);
        return !max || currentEnd.isAfter(max) ? currentEnd : max;
      },
      null
    );
    if (!minStart || !maxEnd) return [];
    const format = typeof dateFormat.value === "string" ? dateFormat.value : "YYYY-MM-DD HH:mm";
    return [
      {
        [barStart.value]: minStart.format(format),
        [barEnd.value]: maxEnd.format(format),
        ganttBarConfig: {
          id: `group-${row.id || row.label}`,
          immobile: true,
          label: row.label,
          style: {
            background: "transparent"
          },
          connections: row.connections || []
        }
      }
    ];
  };
  const toDayjs = (input) => {
    if (typeof input === "string") {
      return dayjs(input);
    } else if (input instanceof Date) {
      return dayjs(input);
    }
    return dayjs();
  };
  const getStartDate = (row) => {
    var _a;
    if ((_a = row.children) == null ? void 0 : _a.length) {
      const childDates = row.children.map((child) => getStartDate(child)).filter((date) => date !== null);
      if (childDates.length === 0) {
        return getBarsStartDate(row.bars);
      }
      return childDates.reduce((min, date) => !min || date.isBefore(min) ? date : min);
    }
    return getBarsStartDate(row.bars);
  };
  const getBarsStartDate = (bars) => {
    if (bars.length === 0) return null;
    return bars.reduce((min, bar) => {
      const currentStart = toDayjs(bar[barStart.value]);
      return !min || currentStart.isBefore(min) ? currentStart : min;
    }, null);
  };
  const getEndDate = (row) => {
    var _a;
    if ((_a = row.children) == null ? void 0 : _a.length) {
      const childDates = row.children.map((child) => getEndDate(child)).filter((date) => date !== null);
      if (childDates.length === 0) {
        return getBarsEndDate(row.bars);
      }
      return childDates.reduce((max, date) => !max || date.isAfter(max) ? date : max);
    }
    return getBarsEndDate(row.bars);
  };
  const getBarsEndDate = (bars) => {
    if (bars.length === 0) return null;
    return bars.reduce((max, bar) => {
      const currentEnd = toDayjs(bar[barEnd.value]);
      return !max || currentEnd.isAfter(max) ? currentEnd : max;
    }, null);
  };
  const calculateDuration = (row) => {
    const startDate = getStartDate(row);
    const endDate = getEndDate(row);
    if (!startDate || !endDate) return 0;
    return endDate.diff(startDate, "minutes");
  };
  const compareValues = (a, b, column) => {
    var _a, _b, _c, _d, _e;
    if ((((_a = a.children) == null ? void 0 : _a.length) || 0) !== (((_b = b.children) == null ? void 0 : _b.length) || 0)) {
      return (((_c = b.children) == null ? void 0 : _c.length) || 0) - (((_d = a.children) == null ? void 0 : _d.length) || 0);
    }
    const columnConfig = (_e = multiColumnLabel.value) == null ? void 0 : _e.find((conf) => conf.field === column);
    if ((columnConfig == null ? void 0 : columnConfig.sortFn) && !isStandardField(column)) {
      return columnConfig.sortFn(a, b);
    }
    switch (column) {
      case "Id":
        const aId = a.id ?? 0;
        const bId = b.id ?? 0;
        return aId < bId ? -1 : aId > bId ? 1 : 0;
      case "Label":
        return a.label.localeCompare(b.label, void 0, {
          numeric: true,
          sensitivity: "base"
        });
      case "StartDate": {
        const aStartDate = getStartDate(a);
        const bStartDate = getStartDate(b);
        if (!aStartDate && !bStartDate) return 0;
        if (!aStartDate) return 1;
        if (!bStartDate) return -1;
        return aStartDate.valueOf() - bStartDate.valueOf();
      }
      case "EndDate": {
        const aEndDate = getEndDate(a);
        const bEndDate = getEndDate(b);
        if (!aEndDate && !bEndDate) return 0;
        if (!aEndDate) return 1;
        if (!bEndDate) return -1;
        return aEndDate.valueOf() - bEndDate.valueOf();
      }
      case "Duration": {
        const aDuration = calculateDuration(a);
        const bDuration = calculateDuration(b);
        return aDuration - bDuration;
      }
      case "Progress": {
        const getAvgProgress = (row) => {
          const progressValues = row.bars.map((bar) => bar.ganttBarConfig.progress).filter((progress) => progress !== void 0);
          if (progressValues.length === 0) return -1;
          return progressValues.reduce((sum, curr) => sum + curr, 0) / progressValues.length;
        };
        const progressA = getAvgProgress(a);
        const progressB = getAvgProgress(b);
        if (progressA === -1 && progressB === -1) return 0;
        if (progressA === -1) return 1;
        if (progressB === -1) return -1;
        return progressA - progressB;
      }
      default:
        if (columnConfig == null ? void 0 : columnConfig.valueGetter) {
          const aValue = columnConfig.valueGetter(a);
          const bValue = columnConfig.valueGetter(b);
          return String(aValue).localeCompare(String(bValue));
        }
        return 0;
    }
  };
  const isStandardField = (field) => {
    return ["Id", "Label", "StartDate", "EndDate", "Duration"].includes(field);
  };
  const applyCustomOrder = (rowsToSort) => {
    if (customOrder.value.size === 0 || sortState.value.direction !== "none") {
      return rowsToSort;
    }
    return [...rowsToSort].sort((a, b) => {
      const orderA = a.id ? customOrder.value.get(a.id) ?? Number.MAX_VALUE : Number.MAX_VALUE;
      const orderB = b.id ? customOrder.value.get(b.id) ?? Number.MAX_VALUE : Number.MAX_VALUE;
      return orderA - orderB;
    });
  };
  const rows = computed(() => {
    let sourceRows = [...reorderedRows.value];
    if (!sourceRows.length) return sourceRows;
    const processRowsWithGroupBars = (rows2) => {
      return rows2.map((row) => {
        var _a;
        if ((_a = row.children) == null ? void 0 : _a.length) {
          const processedChildren = processRowsWithGroupBars(row.children);
          return {
            ...row,
            children: processedChildren,
            bars: calculateGroupBars(row)
          };
        }
        return row;
      });
    };
    sourceRows = processRowsWithGroupBars(sourceRows);
    if (sortState.value.direction !== "none") {
      return sortRows(sourceRows, sortState.value.column, sortState.value.direction);
    }
    if (customOrder.value.size > 0) {
      return sourceRows.sort((a, b) => {
        const orderA = a.id ? customOrder.value.get(a.id) ?? Number.MAX_VALUE : Number.MAX_VALUE;
        const orderB = b.id ? customOrder.value.get(b.id) ?? Number.MAX_VALUE : Number.MAX_VALUE;
        return orderA - orderB;
      });
    }
    return sourceRows;
  });
  const resetCustomOrder = () => {
    customOrder.value.clear();
  };
  const sortRows = (rows2, column, direction) => {
    return rows2.map((row) => {
      var _a;
      if ((_a = row.children) == null ? void 0 : _a.length) {
        return {
          ...row,
          children: sortRows(row.children, column, direction)
        };
      }
      return row;
    }).sort((a, b) => {
      const comparison = compareValues(a, b, column);
      return direction === "asc" ? comparison : -comparison;
    });
  };
  const toggleSort = (column) => {
    const previousDirection = sortState.value.direction;
    if (sortState.value.column !== column) {
      sortState.value = {
        column,
        direction: "asc"
      };
    } else {
      switch (sortState.value.direction) {
        case "none":
          sortState.value.direction = "asc";
          break;
        case "asc":
          sortState.value.direction = "desc";
          break;
        case "desc":
          sortState.value.direction = "none";
          break;
      }
    }
    onSort(sortState.value);
    sortChangeCallbacks.value.forEach((callback) => callback());
    if (previousDirection !== "none" && sortState.value.direction === "none") {
      applyCustomOrder(rows.value);
    }
  };
  const toggleGroupExpansion = (rowId) => {
    if (expandedGroups.value.has(rowId)) {
      expandedGroups.value.delete(rowId);
    } else {
      expandedGroups.value.add(rowId);
    }
    onGroupExpansion(rowId);
    groupExpansionCallbacks.value.forEach((callback) => callback());
  };
  const isGroupExpanded = (rowId) => {
    return expandedGroups.value.has(rowId);
  };
  const getFlattenedRows = () => {
    const flatten = (rows2) => {
      return rows2.flatMap((row) => {
        var _a;
        if (!((_a = row.children) == null ? void 0 : _a.length) || !isGroupExpanded(row.id)) {
          return [row];
        }
        return [row, ...flatten(row.children)];
      });
    };
    return flatten(rows.value);
  };
  const onSortChange = (callback) => {
    sortChangeCallbacks.value.add(callback);
    return () => {
      sortChangeCallbacks.value.delete(callback);
    };
  };
  const onGroupExpansionChange = (callback) => {
    groupExpansionCallbacks.value.add(callback);
    return () => {
      groupExpansionCallbacks.value.delete(callback);
    };
  };
  const expandAllGroups = () => {
    const addGroupsToExpanded = (rows2) => {
      rows2.forEach((row) => {
        var _a;
        if (((_a = row.children) == null ? void 0 : _a.length) && row.id) {
          expandedGroups.value.add(row.id);
          addGroupsToExpanded(row.children);
        }
      });
    };
    addGroupsToExpanded(getSourceRows());
    groupExpansionCallbacks.value.forEach((callback) => callback());
  };
  const collapseAllGroups = () => {
    expandedGroups.value.clear();
    groupExpansionCallbacks.value.forEach((callback) => callback());
  };
  const hasAnyGroup = computed(() => {
    const checkForGroups = (rows2) => {
      return rows2.some(
        (row) => {
          var _a;
          return ((_a = row.children) == null ? void 0 : _a.length) > 0 || row.children && checkForGroups(row.children);
        }
      );
    };
    return checkForGroups(rows.value);
  });
  const areAllGroupsExpanded = computed(() => {
    if (!hasAnyGroup.value) return false;
    const checkAllExpanded = (rows2) => {
      return rows2.every((row) => {
        var _a;
        if ((_a = row.children) == null ? void 0 : _a.length) {
          const isCurrentExpanded = row.id ? expandedGroups.value.has(row.id) : false;
          return isCurrentExpanded && checkAllExpanded(row.children);
        }
        return true;
      });
    };
    return checkAllExpanded(rows.value);
  });
  const areAllGroupsCollapsed = computed(() => {
    if (!hasAnyGroup.value) return false;
    const checkAllCollapsed = (rows2) => {
      return rows2.every((row) => {
        var _a;
        if ((_a = row.children) == null ? void 0 : _a.length) {
          const isCurrentCollapsed = row.id ? !expandedGroups.value.has(row.id) : true;
          return isCurrentCollapsed && checkAllCollapsed(row.children);
        }
        return true;
      });
    };
    return checkAllCollapsed(rows.value);
  });
  const getChartRows = () => rows.value;
  const updateRows = (newRows) => {
    reorderedRows.value = newRows;
    addHistoryState();
  };
  return {
    rows,
    updateRows,
    sortState,
    toggleSort,
    getChartRows,
    onSortChange,
    toggleGroupExpansion,
    isGroupExpanded,
    getFlattenedRows,
    onGroupExpansionChange,
    customOrder,
    resetCustomOrder,
    expandAllGroups,
    collapseAllGroups,
    canUndo,
    canRedo,
    undo,
    redo,
    clearHistory,
    onBarMove,
    areAllGroupsExpanded,
    areAllGroupsCollapsed
  };
}
const useSectionResize = () => {
  const resizeState = ref({
    isResizing: false,
    startX: 0,
    startWidth: 0
  });
  const resetResizeState = () => {
    resizeState.value = {
      isResizing: false,
      startX: 0,
      startWidth: 0
    };
  };
  const handleResizeStart = (e, currentWidth) => {
    e.preventDefault();
    resizeState.value = {
      isResizing: true,
      startX: e.clientX,
      startWidth: currentWidth
    };
    document.body.style.cursor = "col-resize";
  };
  const handleResizeMove = (e, onResize) => {
    if (!resizeState.value.isResizing) return;
    e.preventDefault();
    const deltaX = e.clientX - resizeState.value.startX;
    const newWidth = Math.max(0, resizeState.value.startWidth + deltaX);
    onResize(newWidth);
  };
  const handleResizeEnd = () => {
    if (resizeState.value.isResizing) {
      document.body.style.cursor = "";
      resetResizeState();
    }
  };
  const handleTouchStart = (e, currentWidth) => {
    const touch = e.touches[0];
    if (!touch) return;
    e.preventDefault();
    resizeState.value = {
      isResizing: true,
      startX: touch.clientX,
      startWidth: currentWidth
    };
  };
  const handleTouchMove = (e, onResize) => {
    if (!resizeState.value.isResizing) return;
    const touch = e.touches[0];
    if (!touch) return;
    e.preventDefault();
    const deltaX = touch.clientX - resizeState.value.startX;
    const newWidth = Math.max(0, resizeState.value.startWidth + deltaX);
    onResize(newWidth);
  };
  return {
    resizeState,
    handleResizeStart,
    handleResizeMove,
    handleResizeEnd,
    handleTouchStart,
    handleTouchMove,
    resetResizeState
  };
};
function useConnectionCreation(config, rowManager, emit, reinitializeConnections) {
  const connectionState = ref({
    isCreating: false,
    sourceBar: null,
    sourcePoint: null,
    mouseX: 0,
    mouseY: 0
  });
  const hoverState = ref({
    isVisible: false,
    barId: null,
    point: null
  });
  const validateConnection = (sourceBar, targetBar) => {
    var _a;
    if (sourceBar.ganttBarConfig.id === targetBar.ganttBarConfig.id) {
      return { isValid: false, message: "Cannot connect a bar to itself" };
    }
    const existingConnection = (_a = sourceBar.ganttBarConfig.connections) == null ? void 0 : _a.find(
      (conn) => conn.targetId === targetBar.ganttBarConfig.id
    );
    if (existingConnection) {
      return { isValid: false, message: "Existing connection" };
    }
    return { isValid: true };
  };
  const determineRelationType = (sourcePoint, targetPoint) => {
    if (sourcePoint === "end" && targetPoint === "start") return "FS";
    if (sourcePoint === "start" && targetPoint === "start") return "SS";
    if (sourcePoint === "end" && targetPoint === "end") return "FF";
    if (sourcePoint === "start" && targetPoint === "end") return "SF";
    return "FS";
  };
  const startConnectionCreation = (bar, point, e) => {
    connectionState.value = {
      isCreating: true,
      sourceBar: bar,
      sourcePoint: point,
      mouseX: e.clientX,
      mouseY: e.clientY
    };
    emit("connection-start", {
      sourceBar: bar,
      connectionPoint: point,
      e
    });
  };
  const updateConnectionDrag = (e) => {
    if (!connectionState.value.isCreating) return;
    connectionState.value.mouseX = e.clientX;
    connectionState.value.mouseY = e.clientY;
    emit("connection-drag", {
      sourceBar: connectionState.value.sourceBar,
      connectionPoint: connectionState.value.sourcePoint,
      currentX: e.clientX,
      currentY: e.clientY,
      e
    });
  };
  const completeConnection = (targetBar, targetPoint, e) => {
    var _a, _b, _c;
    if (!connectionState.value.sourceBar || !connectionState.value.sourcePoint) return;
    const validation = validateConnection(connectionState.value.sourceBar, targetBar);
    if (validation.isValid) {
      const relation = determineRelationType(connectionState.value.sourcePoint, targetPoint);
      const newConnection = {
        targetId: targetBar.ganttBarConfig.id,
        type: config.defaultConnectionType.value,
        color: config.defaultConnectionColor.value,
        pattern: config.defaultConnectionPattern.value,
        animated: config.defaultConnectionAnimated.value,
        animationSpeed: config.defaultConnectionAnimationSpeed.value,
        relation,
        label: (_a = config.defaultConnectionLabel) == null ? void 0 : _a.value,
        labelAlwaysVisible: (_b = config.defaultConnectionLabelAlwaysVisible) == null ? void 0 : _b.value,
        labelStyle: (_c = config.defaultConnectionLabelStyle) == null ? void 0 : _c.value
      };
      if (!connectionState.value.sourceBar.ganttBarConfig.connections) {
        connectionState.value.sourceBar.ganttBarConfig.connections = [];
      }
      connectionState.value.sourceBar.ganttBarConfig.connections.push(newConnection);
      const updatedRows = [...rowManager.rows.value];
      rowManager.updateRows(updatedRows);
      reinitializeConnections();
      emit("connection-complete", {
        sourceBar: connectionState.value.sourceBar,
        targetBar,
        sourcePoint: connectionState.value.sourcePoint,
        targetPoint,
        e
      });
    }
    resetConnectionState();
  };
  const handleConnectionPointHover = (barId, point, isEnter) => {
    hoverState.value = {
      isVisible: isEnter,
      barId: isEnter ? barId : null,
      point: isEnter ? point : null
    };
  };
  const cancelConnectionCreation = (e) => {
    if (connectionState.value.sourceBar && connectionState.value.sourcePoint) {
      emit("connection-cancel", {
        sourceBar: connectionState.value.sourceBar,
        connectionPoint: connectionState.value.sourcePoint,
        e
      });
    }
    resetConnectionState();
  };
  const resetConnectionState = () => {
    connectionState.value = {
      isCreating: false,
      sourceBar: null,
      sourcePoint: null,
      mouseX: 0,
      mouseY: 0
    };
  };
  const canBeConnectionTarget = computed(() => (bar) => {
    if (!connectionState.value.sourceBar) return false;
    return validateConnection(connectionState.value.sourceBar, bar).isValid;
  });
  return {
    connectionState,
    hoverState,
    startConnectionCreation,
    updateConnectionDrag,
    completeConnection,
    cancelConnectionCreation,
    handleConnectionPointHover,
    canBeConnectionTarget
  };
}
function useExport(getChartElement, getWrapperElement, rowManager, config) {
  const isExporting = ref(false);
  const lastError = ref(null);
  const prepareElementForExport = (element, wrapperELement, options) => {
    const clonedElement = wrapperELement.cloneNode(true);
    clonedElement.style.width = element.offsetWidth + "px";
    clonedElement.style.height = element.offsetHeight + "px";
    const textSelectors = [".g-gantt-bar-label > div", ".g-timeunit-min", ".label-unit"];
    const textElements = clonedElement.querySelectorAll(textSelectors.join(", "));
    const commands = clonedElement.querySelector(".g-gantt-command");
    commands.style.display = "none";
    if (!options.exportColumnLabel) {
      const columnLabels = clonedElement.querySelector(".g-gantt-label-section");
      columnLabels.style.display = "none";
    }
    textElements.forEach((el) => {
      const element2 = el;
      element2.style.display = "flex";
      element2.style.alignItems = "center";
      element2.style.justifyContent = "center";
      element2.style.textAlign = "center";
      element2.style.position = "relative";
      element2.style.fontSize = "10px";
      element2.style.transform = "translateY(-25%)";
    });
    const ellipsisElements = clonedElement.querySelectorAll(
      ".cell-content, .text-ellipsis, .text-ellipsis-value"
    );
    ellipsisElements.forEach((el) => {
      const element2 = el;
      element2.style.overflow = "visible";
      element2.style.alignItems = "center";
      element2.style.whiteSpace = "normal";
      element2.style.textOverflow = "ellipsis";
      element2.style.fontSize = "10px";
      element2.style.transform = "translateY(-1%)";
    });
    const rows = clonedElement.querySelectorAll(".g-label-column-row");
    rows.forEach((row) => {
      const rowElement = row;
      rowElement.style.overflow = "visible";
      rowElement.style.flexWrap = "wrap";
    });
    const barLabels = clonedElement.querySelectorAll(".g-gantt-bar-label");
    barLabels.forEach((el) => {
      const element2 = el;
      element2.style.overflow = "hidden";
      element2.style.textOverflow = "ellipsis";
      element2.style.whiteSpace = "nowrap";
      element2.style.transform = "translateY(-15%)";
    });
    const progressBars = clonedElement.querySelectorAll(".g-gantt-progress-bar");
    progressBars.forEach((el) => {
      const element2 = el;
      element2.style.display = "";
      element2.style.alignItems = "";
      element2.style.justifyContent = "";
      element2.style.transform = "";
      element2.style.position = "";
    });
    const minUnitLabels = clonedElement.querySelectorAll(".g-timeunit-min");
    minUnitLabels.forEach((el) => {
      const element2 = el;
      element2.style.transform = "translateY(-35%)";
    });
    const progressTexts = clonedElement.querySelectorAll(".progress-text");
    progressTexts.forEach((el) => {
      const element2 = el;
      element2.style.transform = "translateY(-40%)";
    });
    const timeAxisEventsLabels = clonedElement.querySelectorAll(".g-timeaxis-event-label");
    timeAxisEventsLabels.forEach((el) => {
      const element2 = el;
      element2.style.fontSize = "8px";
      element2.style.transform = "translateY(-45%)";
    });
    const milestoneLabels = clonedElement.querySelectorAll(".g-gantt-milestone-label");
    milestoneLabels.forEach((el) => {
      const element2 = el;
      element2.style.transform = "translateY(-15%)";
    });
    const milestoneMarkers = clonedElement.querySelectorAll(".g-gantt-milestone-marker");
    milestoneMarkers.forEach((el) => {
      const element2 = el;
      element2.style.transform = "translateY(-0.2%)";
    });
    const rowLabels = clonedElement.querySelectorAll(".g-gantt-row-label");
    rowLabels.forEach((el) => {
      const element2 = el;
      element2.style.transform = "translateY(-15%)";
    });
    return clonedElement;
  };
  const exportChart = async (options) => {
    isExporting.value = true;
    lastError.value = null;
    try {
      const element = getChartElement();
      const wrapper = getWrapperElement();
      if (!element || !wrapper) {
        throw new Error("Gantt chart element not found");
      }
      const filename = options.filename || `gantt-export-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
      switch (options.format) {
        case "pdf":
          return await exportToPdf(element, wrapper, {
            ...options,
            filename: filename + ".pdf"
          });
        case "png":
          return await exportToPng(element, wrapper, {
            ...options,
            filename: filename + ".png"
          });
        case "svg":
          return await exportToSvg(element, wrapper, {
            ...options,
            filename: filename + ".svg"
          });
        case "excel":
          return await exportToExcel({
            ...options,
            filename: filename + ".xlsx"
          });
        default:
          throw new Error(`Format file export not supported: ${options.format}`);
      }
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Unknown Error";
      lastError.value = errorMessage;
      return {
        success: false,
        data: null,
        error: errorMessage,
        filename: options.filename || "export-error"
      };
    } finally {
      isExporting.value = false;
    }
  };
  const exportToPdf = async (element, wrapper, options) => {
    try {
      const processedElement = prepareElementForExport(element, wrapper, options);
      const tempContainer = document.createElement("div");
      tempContainer.style.position = "absolute";
      tempContainer.style.left = "-9999px";
      tempContainer.style.width = element.offsetWidth + "px";
      tempContainer.style.height = element.offsetHeight + "px";
      tempContainer.style.overflow = "hidden";
      tempContainer.appendChild(processedElement);
      document.body.appendChild(tempContainer);
      await new Promise((resolve) => setTimeout(resolve, 100));
      const paperSize = options.paperSize || "a4";
      const orientation = options.orientation || "landscape";
      const scale = options.scale || 1;
      const margin = options.margin !== void 0 ? options.margin : 10;
      const pdf = new jsPDF({
        orientation,
        unit: "mm",
        format: paperSize
      });
      const canvas = await html2canvas(processedElement, {
        scale,
        logging: false,
        allowTaint: true,
        useCORS: true,
        backgroundColor: "#ffffff",
        imageTimeout: 0,
        removeContainer: false,
        foreignObjectRendering: false
      });
      document.body.removeChild(tempContainer);
      const pageWidth = orientation === "landscape" ? pdf.internal.pageSize.getHeight() : pdf.internal.pageSize.getWidth();
      const pageHeight = orientation === "landscape" ? pdf.internal.pageSize.getWidth() : pdf.internal.pageSize.getHeight();
      const pdfWidth = pageWidth - margin * 2;
      const imgWidth = canvas.width;
      const imgHeight = canvas.height;
      const ratio = imgWidth / imgHeight;
      const pdfHeight = pdfWidth / ratio;
      if (pdfHeight > pageHeight - margin * 2) {
        let currentHeight = 0;
        while (currentHeight < imgHeight) {
          if (currentHeight > 0) {
            pdf.addPage();
          }
          const canvasSection = Math.min(
            imgHeight - currentHeight,
            imgWidth / pdfWidth * (pageHeight - margin * 2)
          );
          const sectionHeight = canvasSection / imgHeight * imgHeight;
          pdf.addImage(
            canvas.toDataURL("image/jpeg", options.quality || 0.95),
            "JPEG",
            margin,
            margin,
            pdfWidth,
            pdfWidth * (sectionHeight / imgWidth),
            "",
            "FAST",
            currentHeight / imgHeight
          );
          currentHeight += canvasSection;
        }
      } else {
        pdf.addImage(
          canvas.toDataURL("image/jpeg", options.quality || 0.95),
          "JPEG",
          margin,
          margin,
          pdfWidth,
          pdfHeight,
          "",
          "FAST"
        );
      }
      const blob = pdf.output("blob");
      return {
        success: true,
        data: blob,
        filename: options.filename || "gantt-chart.pdf"
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Error during PDF export";
      return {
        success: false,
        data: null,
        error: errorMessage,
        filename: options.filename || "gantt-chart.pdf"
      };
    }
  };
  const exportToPng = async (element, wrapper, options) => {
    try {
      const processedElement = prepareElementForExport(element, wrapper, options);
      const tempContainer = document.createElement("div");
      tempContainer.style.position = "absolute";
      tempContainer.style.left = "-9999px";
      tempContainer.style.width = element.offsetWidth + "px";
      tempContainer.style.height = element.offsetHeight + "px";
      tempContainer.style.overflow = "hidden";
      tempContainer.appendChild(processedElement);
      document.body.appendChild(tempContainer);
      await new Promise((resolve) => setTimeout(resolve, 100));
      const scale = options.scale || 2;
      const canvas = await html2canvas(processedElement, {
        scale,
        logging: false,
        allowTaint: true,
        useCORS: true,
        backgroundColor: "#ffffff",
        imageTimeout: 0,
        removeContainer: false,
        foreignObjectRendering: false
      });
      document.body.removeChild(tempContainer);
      const blob = await new Promise((resolve, reject) => {
        canvas.toBlob(
          (blob2) => {
            if (blob2) {
              resolve(blob2);
            } else {
              reject(new Error("Error creating blob PNG"));
            }
          },
          "image/png",
          options.quality || 0.95
        );
      });
      return {
        success: true,
        data: blob,
        filename: options.filename || "gantt-chart.png"
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Error exporting PNG";
      return {
        success: false,
        data: null,
        error: errorMessage,
        filename: options.filename || "gantt-chart.png"
      };
    }
  };
  const exportToSvg = async (element, wrapper, options) => {
    try {
      const processedElement = prepareElementForExport(element, wrapper, options);
      const tempContainer = document.createElement("div");
      tempContainer.style.position = "absolute";
      tempContainer.style.left = "-9999px";
      tempContainer.style.width = element.offsetWidth + "px";
      tempContainer.style.height = element.offsetHeight + "px";
      tempContainer.style.overflow = "hidden";
      tempContainer.appendChild(processedElement);
      document.body.appendChild(tempContainer);
      await new Promise((resolve) => setTimeout(resolve, 100));
      const canvas = await html2canvas(processedElement, {
        scale: options.scale || 2,
        logging: false,
        allowTaint: true,
        useCORS: true,
        backgroundColor: "#ffffff",
        imageTimeout: 0,
        removeContainer: false,
        foreignObjectRendering: false
      });
      document.body.removeChild(tempContainer);
      const width = canvas.width;
      const height = canvas.height;
      const svgNS = "http://www.w3.org/2000/svg";
      const svgRoot = document.createElementNS(svgNS, "svg");
      svgRoot.setAttribute("width", width.toString());
      svgRoot.setAttribute("height", height.toString());
      svgRoot.setAttribute("viewBox", `0 0 ${width} ${height}`);
      svgRoot.setAttribute("xmlns", svgNS);
      svgRoot.setAttribute("version", "1.1");
      const img = document.createElementNS(svgNS, "image");
      img.setAttribute("width", width.toString());
      img.setAttribute("height", height.toString());
      img.setAttribute("x", "0");
      img.setAttribute("y", "0");
      img.setAttribute("href", canvas.toDataURL("image/png", options.quality || 0.95));
      svgRoot.appendChild(img);
      const serializer = new XMLSerializer();
      const svgString = serializer.serializeToString(svgRoot);
      const finalSvgString = '<?xml version="1.0" standalone="no"?>\n' + svgString;
      const blob = new Blob([finalSvgString], { type: "image/svg+xml;charset=utf-8" });
      return {
        success: true,
        data: blob,
        filename: options.filename || "gantt-chart.svg"
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Error exporting in SVG";
      return {
        success: false,
        data: null,
        error: errorMessage,
        filename: options.filename || "gantt-chart.svg"
      };
    }
  };
  const exportToExcel = async (options) => {
    try {
      const workbook = XLSX.utils.book_new();
      const getAllRows = (rows) => {
        return rows.flatMap((row) => {
          var _a;
          if (!((_a = row.children) == null ? void 0 : _a.length)) {
            return [row];
          }
          return [row, ...getAllRows(row.children)];
        });
      };
      const allRows = getAllRows(rowManager.rows.value);
      const firstSheetData = [];
      firstSheetData.push(["ID", "Task", "Start Date", "End Date", "Duration", "Progress (%)"]);
      allRows.forEach((row, index) => {
        let startDate = "-";
        let endDate = "-";
        let duration = "-";
        let progress = "-";
        if (row.bars && row.bars.length > 0) {
          const minStartDate = row.bars.reduce(
            (min, bar) => {
              const currentStart = dayjs(bar[config.barStart.value]);
              return !min || currentStart.isBefore(min) ? currentStart : min;
            },
            null
          );
          const maxEndDate = row.bars.reduce(
            (max, bar) => {
              const currentEnd = dayjs(bar[config.barEnd.value]);
              return !max || currentEnd.isAfter(max) ? currentEnd : max;
            },
            null
          );
          if (minStartDate) {
            startDate = minStartDate.format(config.dateFormat.value || "YYYY-MM-DD HH:mm");
          }
          if (maxEndDate) {
            endDate = maxEndDate.format(config.dateFormat.value || "YYYY-MM-DD HH:mm");
          }
          if (minStartDate && maxEndDate) {
            const durationValue = maxEndDate.diff(minStartDate, config.precision.value);
            duration = `${durationValue}${config.precision.value.charAt(0)}`;
          }
          const progressValues = row.bars.map((bar) => bar.ganttBarConfig.progress).filter((progress2) => progress2 !== void 0);
          if (progressValues.length > 0) {
            const avgProgress = progressValues.reduce((sum, curr) => sum + curr, 0) / progressValues.length;
            progress = `${Math.round(avgProgress)}%`;
          }
        }
        firstSheetData.push([
          row.id || index + 1,
          row.label,
          startDate,
          endDate,
          duration,
          progress
        ]);
      });
      const worksheet1 = XLSX.utils.aoa_to_sheet(firstSheetData);
      XLSX.utils.book_append_sheet(workbook, worksheet1, "Gantt Rows");
      const secondSheetData = [];
      secondSheetData.push([
        "Bar ID",
        "Label",
        "Parent Row",
        "Row ID",
        "Start Date",
        "End Date",
        "Duration",
        "Progress (%)",
        "Connections",
        "Milestone"
      ]);
      const processedBarIds = /* @__PURE__ */ new Set();
      const allBars = [];
      const collectBars = (rows) => {
        rows.forEach((row) => {
          row.bars.forEach((bar) => {
            if (!processedBarIds.has(bar.ganttBarConfig.id)) {
              processedBarIds.add(bar.ganttBarConfig.id);
              allBars.push({
                bar,
                rowLabel: row.label,
                rowId: row.id || ""
              });
            }
          });
          if (row.children && row.children.length > 0) {
            collectBars(row.children);
          }
        });
      };
      collectBars(rowManager.rows.value);
      allBars.forEach((item) => {
        const { bar, rowLabel, rowId } = item;
        const barConfig = bar.ganttBarConfig;
        const startDate = dayjs(bar[config.barStart.value]).format(
          config.dateFormat.value || "YYYY-MM-DD HH:mm"
        );
        const endDate = dayjs(bar[config.barEnd.value]).format(
          config.dateFormat.value || "YYYY-MM-DD HH:mm"
        );
        const durationValue = dayjs(bar[config.barEnd.value]).diff(
          dayjs(bar[config.barStart.value]),
          config.precision.value
        );
        const duration = `${durationValue}${config.precision.value.charAt(0)}`;
        const progress = barConfig.progress !== void 0 ? `${Math.round(barConfig.progress)}%` : "-";
        const connections = barConfig.connections && barConfig.connections.length > 0 ? barConfig.connections.map((conn) => conn.targetId).join(", ") : "-";
        const milestone = barConfig.milestoneId ? barConfig.milestoneId : "-";
        secondSheetData.push([
          barConfig.id,
          barConfig.label || "",
          rowLabel,
          rowId,
          startDate,
          endDate,
          duration,
          progress,
          connections,
          milestone
        ]);
      });
      const worksheet2 = XLSX.utils.aoa_to_sheet(secondSheetData);
      XLSX.utils.book_append_sheet(workbook, worksheet2, "Bars Detail");
      [worksheet1, worksheet2].forEach((worksheet) => {
        const headerRange = XLSX.utils.decode_range(worksheet["!ref"] || "A1");
        for (let col = headerRange.s.c; col <= headerRange.e.c; col++) {
          const cellRef = XLSX.utils.encode_cell({ r: 0, c: col });
          if (!worksheet[cellRef]) worksheet[cellRef] = {};
          worksheet[cellRef].s = { font: { bold: true } };
        }
      });
      const colWidths1 = [
        { wch: 10 },
        { wch: 40 },
        { wch: 20 },
        { wch: 20 },
        { wch: 10 },
        { wch: 15 }
      ];
      worksheet1["!cols"] = colWidths1;
      const colWidths2 = [
        { wch: 15 },
        { wch: 30 },
        { wch: 30 },
        { wch: 10 },
        { wch: 20 },
        { wch: 20 },
        { wch: 10 },
        { wch: 15 },
        { wch: 30 },
        { wch: 20 }
      ];
      worksheet2["!cols"] = colWidths2;
      const excelBuffer = XLSX.write(workbook, { bookType: "xlsx", type: "array" });
      const blob = new Blob([excelBuffer], {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
      });
      return {
        success: true,
        data: blob,
        filename: options.filename || "gantt-chart.xlsx"
      };
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Error exporting to Excel";
      console.error("Error during Excel export:", error);
      return {
        success: false,
        data: null,
        error: errorMessage,
        filename: options.filename || "gantt-chart.xlsx"
      };
    }
  };
  const downloadExport = (result) => {
    if (result.success && result.data) {
      const url = URL.createObjectURL(result.data);
      const link = document.createElement("a");
      link.href = url;
      link.download = result.filename;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
    }
  };
  return {
    exportChart,
    downloadExport,
    isExporting,
    lastError
  };
}
const _hoisted_1 = ["id"];
const _hoisted_2 = {
  class: "g-gantt-main-layout",
  "aria-controls": "gantt-controls"
};
const _hoisted_3 = {
  key: 0,
  class: "connection-preview",
  style: {
    position: "absolute",
    top: 0,
    left: 0,
    width: "100%",
    height: "100%",
    pointerEvents: "none",
    zIndex: 2e3,
    overflow: "visible"
  }
};
const _hoisted_4 = { class: "g-gantt-command-block" };
const _hoisted_5 = {
  key: 0,
  class: "g-gantt-command-vertical"
};
const _hoisted_6 = ["disabled"];
const _hoisted_7 = ["disabled"];
const _hoisted_8 = {
  key: 1,
  class: "g-gantt-command-groups"
};
const _hoisted_9 = ["disabled"];
const _hoisted_10 = ["disabled"];
const _hoisted_11 = { class: "g-gantt-command-fixed" };
const _hoisted_12 = { class: "g-gantt-command-slider" };
const _hoisted_13 = ["disabled"];
const _hoisted_14 = ["disabled"];
const _hoisted_15 = ["aria-valuenow"];
const _hoisted_16 = ["disabled"];
const _hoisted_17 = ["disabled"];
const _hoisted_18 = { class: "g-gantt-command-block" };
const _hoisted_19 = { class: "g-gantt-command-zoom" };
const _hoisted_20 = ["disabled"];
const _hoisted_21 = ["disabled"];
const _hoisted_22 = { class: "g-gantt-command-history" };
const _hoisted_23 = ["disabled"];
const _hoisted_24 = ["disabled"];
const _hoisted_25 = { class: "g-gantt-command-block" };
const _hoisted_26 = {
  key: 0,
  class: "g-gantt-command-export"
};
const _hoisted_27 = { class: "g-gantt-export-container" };
const _hoisted_28 = ["disabled"];
const _hoisted_29 = ["disabled"];
const _hoisted_30 = {
  key: 0,
  class: "g-gantt-export-loading"
};
const _sfc_main = /* @__PURE__ */ defineComponent({
  __name: "GGanttChart",
  props: {
    chartStart: {},
    chartEnd: {},
    precision: { default: "day" },
    barStart: {},
    barEnd: {},
    currentTime: { type: Boolean },
    currentTimeLabel: { default: "" },
    pointerMarker: { type: Boolean },
    dateFormat: { type: [String, Boolean], default: DEFAULT_DATE_FORMAT },
    width: { default: "100%" },
    hideTimeaxis: { type: Boolean, default: false },
    colorScheme: { default: "default" },
    grid: { type: Boolean, default: false },
    pushOnOverlap: { type: Boolean, default: false },
    pushOnConnect: { type: Boolean, default: false },
    noOverlap: { type: Boolean, default: false },
    rowHeight: { default: 40 },
    font: { default: "inherit" },
    labelColumnTitle: { default: "" },
    labelColumnWidth: { default: 120 },
    multiColumnLabel: { default: () => [] },
    commands: { type: Boolean, default: true },
    enableMinutes: { type: Boolean, default: false },
    enableConnections: { type: Boolean, default: true },
    enableConnectionCreation: { type: Boolean, default: false },
    enableConnectionDeletion: { type: Boolean, default: false },
    defaultConnectionType: { default: "straight" },
    defaultConnectionColor: { default: "#ff0000" },
    defaultConnectionPattern: { default: "solid" },
    defaultConnectionAnimated: { type: Boolean, default: false },
    defaultConnectionAnimationSpeed: { default: "normal" },
    defaultConnectionRelation: { default: "FS" },
    defaultConnectionLabel: { default: "" },
    defaultConnectionLabelAlwaysVisible: { type: Boolean, default: false },
    defaultConnectionLabelStyle: { default: () => ({}) },
    maxRows: { default: 0 },
    initialSort: { default: () => ({
      column: "Label",
      direction: "none"
    }) },
    initialRows: { default: () => [] },
    sortable: { type: Boolean, default: true },
    labelResizable: { type: Boolean, default: true },
    milestones: { default: () => [] },
    timeaxisEvents: { default: () => [] },
    showEventsAxis: { type: Boolean, default: false },
    eventsAxisHeight: { default: 25 },
    holidayHighlight: { default: "" },
    rowClass: { type: Function, default: () => "" },
    rowLabelClass: { type: Function, default: () => "" },
    dayOptionLabel: { default: () => ["day"] },
    highlightedHours: { default: () => [] },
    highlightedDaysInWeek: { default: () => [] },
    highlightedDaysInMonth: { default: () => [] },
    highlightedMonths: { default: () => [] },
    highlightedWeek: { default: () => [] },
    locale: { default: "en" },
    enableRowDragAndDrop: { type: Boolean, default: false },
    markerConnection: { default: "forward" },
    showLabel: { type: Boolean, default: true },
    showProgress: { type: Boolean, default: true },
    defaultProgressResizable: { type: Boolean, default: true },
    utc: { type: Boolean, default: false },
    barLabelEditable: { type: Boolean, default: false },
    exportEnabled: { type: Boolean, default: true },
    exportOptions: { default: () => ({
      format: "pdf",
      quality: 0.95,
      paperSize: "a4",
      orientation: "landscape",
      scale: 1.5,
      margin: 10,
      exportColumnLabel: true
    }) },
    showImporter: { type: Boolean, default: false },
    importerTitle: { default: "Import data" },
    importerDefaultFormat: { default: "csv" },
    importerAllowedFormats: { default: () => ["jira", "csv"] },
    importerBarStartField: { default: "start" },
    importerBarEndField: { default: "end" },
    baseUnitWidth: { default: 24 },
    defaultZoom: { default: 3 }
  },
  emits: ["click-bar", "mousedown-bar", "mouseup-bar", "dblclick-bar", "mouseenter-bar", "mouseleave-bar", "dragstart-bar", "drag-bar", "dragend-bar", "contextmenu-bar", "sort", "group-expansion", "row-drop", "progress-change", "progress-drag-start", "progress-drag-end", "connection-start", "connection-drag", "connection-complete", "connection-cancel", "connection-delete", "label-edit", "export-start", "export-success", "export-error", "import-data", "range-selection"],
  setup(__props, { expose: __expose, emit: __emit }) {
    useCssVars((_ctx) => ({
      "1fed23a5": colors.value.rangeHighlight,
      "787ffb4a": colors.value.text,
      "31d9cbd8": colors.value.primary
    }));
    const props = __props;
    const emit = __emit;
    const id = ref(v4());
    const slots = useSlots();
    const isDragging = ref(false);
    const isDraggingTimeaxis = ref(false);
    const lastMouseX = ref(0);
    const isImporterVisible = ref(props.showImporter);
    const gGantt = ref(null);
    const ganttChart = ref(null);
    const ganttWrapper = ref(null);
    const timeaxisComponent = ref(null);
    const ganttContainer = ref(null);
    const rowsContainer = ref(null);
    const labelColumn = ref(null);
    const validatedBaseUnitWidth = ref(Math.min(50, Math.max(20, props.baseUnitWidth)));
    const validatedDefaultZoom = ref(Math.min(10, Math.max(1, props.defaultZoom)));
    const setLabelWidth = () => {
      return props.labelColumnWidth * (props.multiColumnLabel.length === 0 ? 1 : props.multiColumnLabel.length + (props.multiColumnLabel.some((el) => el.field === "Label") ? 0 : 1));
    };
    const labelSectionWidth = ref(setLabelWidth());
    watch(
      () => props.multiColumnLabel,
      () => {
        labelSectionWidth.value = setLabelWidth();
      }
    );
    const chartSize = useElementSize(ganttChart);
    const handleTimeaxisTouch = {
      startX: 0,
      isDragging: false
    };
    const rowManager = useRows(
      slots,
      {
        barStart: toRef(props, "barStart"),
        barEnd: toRef(props, "barEnd"),
        dateFormat: toRef(props, "dateFormat"),
        multiColumnLabel: toRef(props, "multiColumnLabel"),
        onSort: (sortState) => emit("sort", { sortState }),
        initialSort: props.initialSort,
        onGroupExpansion: (rowId) => emit("group-expansion", { rowId })
      },
      props.initialRows ? toRef(props, "initialRows") : void 0
    );
    provide("useRows", rowManager);
    const {
      connections,
      barPositions,
      getConnectorProps,
      initializeConnections,
      updateBarPositions,
      handleConnectionClick,
      selectedConnection,
      deleteSelectedConnection
    } = useConnections(rowManager, props, id, emit);
    const { showTooltip, tooltipBar, initTooltip, clearTooltip } = useTooltip();
    const { font, colorScheme } = toRefs(props);
    const colors = computed(() => getColorScheme(colorScheme.value));
    const { timeaxisUnits, internalPrecision, zoomLevel, adjustZoomAndPrecision } = useTimeaxisUnits({
      ...toRefs(props),
      baseUnitWidth: validatedBaseUnitWidth,
      defaultZoom: validatedDefaultZoom
    });
    const {
      scrollPosition,
      handleStep,
      handleScroll,
      handleWheel,
      handleContentScroll,
      handleLabelScroll,
      handleZoomUpdate,
      scrollRowUp,
      scrollRowDown,
      isAtTop,
      isAtBottom
    } = useChartNavigation(
      {
        scrollRefs: {
          rowsContainer,
          labelColumn
        },
        updateBarPositions,
        timeaxisUnits: { timeaxisUnits, internalPrecision, zoomLevel, adjustZoomAndPrecision }
      },
      props.maxRows
    );
    const { handleKeyDown } = useKeyboardNavigation(
      {
        scrollPosition,
        handleStep,
        handleZoomUpdate
      },
      ganttWrapper,
      ganttContainer,
      {
        selectedConnection,
        deleteSelectedConnection
      },
      toRef(props.enableConnectionDeletion)
    );
    const {
      handleResizeStart,
      handleResizeMove,
      handleResizeEnd,
      handleTouchStart,
      handleTouchMove,
      resetResizeState
    } = useSectionResize();
    const {
      connectionState,
      hoverState,
      startConnectionCreation,
      updateConnectionDrag,
      completeConnection,
      cancelConnectionCreation,
      handleConnectionPointHover,
      canBeConnectionTarget
    } = useConnectionCreation(
      {
        ...toRefs(props)
      },
      rowManager,
      emit,
      initializeConnections
    );
    provide("connectionCreation", {
      connectionState,
      hoverState,
      startConnectionCreation,
      updateConnectionDrag,
      completeConnection,
      cancelConnectionCreation,
      handleConnectionPointHover,
      canBeConnectionTarget
    });
    const handleChartMouseMove = (e) => {
      if (connectionState.value.isCreating) {
        updateConnectionDrag(e);
      }
    };
    const handleChartMouseUp = (e) => {
      if (connectionState.value.isCreating) {
        cancelConnectionCreation(e);
      }
    };
    const { findBarElement } = useBarSelector();
    const previewLinePoints = computed(() => {
      if (!connectionState.value.isCreating || !connectionState.value.sourceBar) return null;
      const sourceBarElement = findBarElement(
        id.value,
        connectionState.value.sourceBar.ganttBarConfig.id
      );
      if (!sourceBarElement) return null;
      const sourceRect = sourceBarElement.getBoundingClientRect();
      const containerElement = ganttContainer.value;
      const rowsContainer2 = containerElement == null ? void 0 : containerElement.querySelector(".g-gantt-rows-container");
      if (!rowsContainer2) return null;
      const containerRect = rowsContainer2.getBoundingClientRect();
      const scrollLeft = rowsContainer2.scrollLeft;
      const scrollTop = rowsContainer2.scrollTop;
      const sourceX = connectionState.value.sourcePoint === "start" ? sourceRect.left - containerRect.left + scrollLeft : sourceRect.right - containerRect.left + scrollLeft;
      const sourceY = sourceRect.top - containerRect.top + scrollTop + sourceRect.height / 2;
      const mouseX = connectionState.value.mouseX - containerRect.left + scrollLeft;
      const mouseY = connectionState.value.mouseY - containerRect.top + scrollTop;
      return {
        x1: sourceX,
        y1: sourceY,
        x2: mouseX,
        y2: mouseY
      };
    });
    watch(
      () => scrollPosition.value,
      () => {
        var _a;
        if (connectionState.value.isCreating) {
          const container = (_a = ganttContainer.value) == null ? void 0 : _a.querySelector(".g-gantt-rows-container");
          if (container) {
            connectionState.value.mouseX = connectionState.value.mouseX;
          }
        }
      }
    );
    const { exportChart, downloadExport, isExporting } = useExport(
      () => ganttChart.value,
      () => gGantt.value,
      rowManager,
      {
        barStart: toRef(props, "barStart"),
        barEnd: toRef(props, "barEnd"),
        dateFormat: toRef(props, "dateFormat"),
        precision: toRef(props, "precision")
      }
    );
    const handleExport = async (options) => {
      const mergedOptions = {
        format: props.exportOptions.format || "pdf",
        quality: props.exportOptions.quality,
        filename: props.exportOptions.filename,
        paperSize: props.exportOptions.paperSize,
        orientation: props.exportOptions.orientation,
        scale: props.exportOptions.scale,
        margin: props.exportOptions.margin,
        ...options
      };
      emit("export-start", mergedOptions.format);
      try {
        const result = await exportChart(mergedOptions);
        if (result.success) {
          emit("export-success", result);
        } else {
          emit("export-error", result.error || "Unknown error");
        }
        return result;
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : "Unknown error";
        emit("export-error", errorMessage);
        return {
          success: false,
          data: null,
          error: errorMessage,
          filename: mergedOptions.filename || "export-error"
        };
      }
    };
    const selectedExportFormat = ref("");
    const triggerExport = async () => {
      if (!selectedExportFormat.value || isExporting.value) return;
      const options = {
        ...props.exportOptions,
        format: selectedExportFormat.value
      };
      try {
        const result = await handleExport(options);
        downloadExport(result);
        selectedExportFormat.value = "";
      } catch (error) {
        console.error("Error during export:", error);
      }
    };
    const handleImport = (result) => {
      if (result.success && result.data) {
        if (result.data.rows && result.data.rows.length > 0) {
          rowManager.updateRows(result.data.rows);
        }
        emit("import-data", result);
      }
    };
    const closeImporter = () => {
      isImporterVisible.value = false;
    };
    const rows = computed(() => rowManager.rows.value);
    const rowsContainerStyle = computed(() => {
      if (props.maxRows === 0) return {};
      return {
        "max-height": `${props.maxRows * props.rowHeight}px`,
        "overflow-y": "auto"
      };
    });
    const totalWidth = computed(() => {
      const lowerUnits = timeaxisUnits.value.result.lowerUnits;
      return lowerUnits.reduce((total, unit) => {
        return total + parseInt(unit.width);
      }, 0);
    });
    const hasGroupRows = computed(() => {
      const checkForGroups = (rows2) => {
        return rows2.some(
          (row) => row.children && row.children.length > 0 || row.children && checkForGroups(row.children)
        );
      };
      return checkForGroups(rows.value);
    });
    const labelSectionStyle = computed(() => ({
      width: `${labelSectionWidth.value}px`,
      maxWidth: `${labelSectionWidth.value}px`,
      position: "relative",
      flexShrink: 0,
      flexGrow: 0
    }));
    const handleTimeaxisMouseDown = (e) => {
      isDraggingTimeaxis.value = true;
      lastMouseX.value = e.clientX;
    };
    const handleTimeaxisMouseMove = (e) => {
      if (!isDraggingTimeaxis.value || !ganttWrapper.value) return;
      const deltaX = e.clientX - lastMouseX.value;
      lastMouseX.value = e.clientX;
      ganttWrapper.value.scrollLeft -= deltaX;
      const maxScroll = ganttWrapper.value.scrollWidth - ganttWrapper.value.clientWidth;
      scrollPosition.value = ganttWrapper.value.scrollLeft / maxScroll * 100;
    };
    const handleTimeaxisMouseUp = () => {
      isDraggingTimeaxis.value = false;
    };
    const handleTimeaxisTouchStart = (e) => {
      const touch = e.touches[0];
      if (!touch) return;
      handleTimeaxisTouch.isDragging = true;
      handleTimeaxisTouch.startX = touch.clientX;
      e.preventDefault();
    };
    const handleTimeaxisTouchMove = (e) => {
      if (!handleTimeaxisTouch.isDragging || !ganttWrapper.value) return;
      const touch = e.touches[0];
      if (!touch) return;
      const deltaX = touch.clientX - handleTimeaxisTouch.startX;
      handleTimeaxisTouch.startX = touch.clientX;
      ganttWrapper.value.scrollLeft -= deltaX;
      const maxScroll = ganttWrapper.value.scrollWidth - ganttWrapper.value.clientWidth;
      scrollPosition.value = ganttWrapper.value.scrollLeft / maxScroll * 100;
      e.preventDefault();
    };
    const handleTimeaxisTouchEnd = () => {
      handleTimeaxisTouch.isDragging = false;
    };
    const handleSectionResize = (newWidth) => {
      labelSectionWidth.value = newWidth;
    };
    const emitBarEvent = (e, bar, datetime, movedBars) => {
      switch (e.type) {
        case "click":
          emit("click-bar", { bar, e, datetime });
          break;
        case "mousedown":
          emit("mousedown-bar", { bar, e, datetime });
          break;
        case "mouseup":
          emit("mouseup-bar", { bar, e, datetime });
          break;
        case "dblclick":
          emit("dblclick-bar", { bar, e, datetime });
          break;
        case "mouseenter":
          initTooltip(bar);
          emit("mouseenter-bar", { bar, e });
          break;
        case "mouseleave":
          clearTooltip();
          emit("mouseleave-bar", { bar, e });
          break;
        case "dragstart":
          isDragging.value = true;
          emit("dragstart-bar", { bar, e });
          updateBarPositions();
          break;
        case "drag":
          emit("drag-bar", { bar, e });
          updateBarPositions();
          break;
        case "dragend":
          isDragging.value = false;
          emit("dragend-bar", { bar, e, movedBars });
          updateBarPositions();
          rowManager.onBarMove();
          break;
        case "contextmenu":
          emit("contextmenu-bar", { bar, e, datetime });
          break;
        case "progress-drag-start":
          initTooltip(bar);
          emit("progress-drag-start", { bar, e });
          break;
        case "progress-change":
          initTooltip(bar);
          emit("progress-change", { bar, e });
          break;
        case "progress-drag-end":
          initTooltip(bar);
          emit("progress-drag-end", { bar, e });
          rowManager.onBarMove();
          break;
        case "label-edit":
          emit("label-edit", {
            bar,
            e,
            oldValue: bar.ganttBarConfig._previousLabel || "",
            newValue: bar.ganttBarConfig.label || ""
          });
          rowManager.onBarMove();
          break;
      }
    };
    const dropRow = (event) => {
      emit("row-drop", event);
      updateBarPositions();
    };
    const handleRangeSelection = (event) => {
      emit("range-selection", event);
    };
    const getColorScheme = (scheme) => typeof scheme !== "string" ? scheme : colorSchemes[scheme] || colorSchemes.default;
    watch(
      () => totalWidth.value,
      () => {
        ganttWidth.value = totalWidth.value;
      },
      { immediate: true }
    );
    const renderRow = (row) => {
      if (row._originalNode) {
        return h(
          _sfc_main$3,
          {
            ...row._originalNode.props,
            label: row.label,
            bars: row.bars,
            children: row.children,
            id: row.id,
            key: row.id || row.label,
            onRangeSelection: handleRangeSelection
          },
          row._originalNode.children || {}
        );
      }
      return h(_sfc_main$3, {
        label: row.label,
        bars: row.bars,
        id: row.id,
        key: row.id || row.label,
        children: row.children,
        connections: row.connections,
        onRangeSelection: handleRangeSelection
      });
    };
    const updateRangeBackground = () => {
      const parentElement = document.getElementById(id.value);
      const slider = parentElement.querySelector(".g-gantt-scroller");
      if (slider) {
        slider.style.setProperty("--value", `${scrollPosition.value}%`);
      }
    };
    const undo = () => {
      const changes = rowManager.undo();
      if (!changes) return;
      changes.rowChanges.forEach((rowChange) => {
        emit("row-drop", {
          sourceRow: rowChange.sourceRow,
          targetRow: void 0,
          newIndex: rowChange.newIndex,
          parentId: rowChange.newParentId
        });
      });
      changes.barChanges.forEach((barChange) => {
        const bar = findBarInRows(rowManager.rows.value, barChange.barId);
        if (!bar) return;
        emit("dragend-bar", {
          bar,
          e: new MouseEvent("mouseup"),
          movedBars: /* @__PURE__ */ new Map([
            [
              bar,
              {
                oldStart: barChange.newStart,
                oldEnd: barChange.newEnd
              }
            ]
          ])
        });
      });
      updateBarPositions();
    };
    const redo = () => {
      const changes = rowManager.redo();
      if (!changes) return;
      changes.rowChanges.forEach((rowChange) => {
        emit("row-drop", {
          sourceRow: rowChange.sourceRow,
          targetRow: void 0,
          newIndex: rowChange.newIndex,
          parentId: rowChange.newParentId
        });
      });
      changes.barChanges.forEach((barChange) => {
        const bar = findBarInRows(rowManager.rows.value, barChange.barId);
        if (!bar) return;
        emit("dragend-bar", {
          bar,
          e: new MouseEvent("mouseup"),
          movedBars: /* @__PURE__ */ new Map([
            [
              bar,
              {
                oldStart: barChange.oldStart,
                oldEnd: barChange.oldEnd
              }
            ]
          ])
        });
      });
      updateBarPositions();
    };
    const handleKeyboardShortcuts = (e) => {
      const isCtrlPressed = e.ctrlKey || e.metaKey;
      if (isCtrlPressed && e.code === "KeyZ") {
        e.preventDefault();
        if (e.shiftKey) {
          if (rowManager.canRedo.value) {
            redo();
          }
        } else {
          if (rowManager.canUndo.value) {
            undo();
          }
        }
      }
    };
    let resizeObserver;
    onMounted(() => {
      const cleanup = rowManager.onSortChange(updateBarPositions);
      const cleanupGroup = rowManager.onGroupExpansionChange(updateBarPositions);
      onUnmounted(cleanup);
      onUnmounted(cleanupGroup);
      if (ganttWrapper.value) {
        ganttWrapper.value.addEventListener("wheel", (e) => handleWheel(e, ganttWrapper.value));
      }
      window.addEventListener("mousemove", handleTimeaxisMouseMove);
      window.addEventListener("mouseup", handleTimeaxisMouseUp);
      window.addEventListener("mousemove", (e) => handleResizeMove(e, handleSectionResize));
      window.addEventListener("mouseup", handleResizeEnd);
      window.addEventListener("keydown", handleKeyboardShortcuts);
      resizeObserver = new ResizeObserver(updateBarPositions);
      const container = document.querySelector(".g-gantt-chart");
      if (container) {
        resizeObserver.observe(container);
      }
      window.addEventListener("resize", updateBarPositions);
      initializeConnections();
      nextTick(() => {
        updateBarPositions();
      });
      watch(scrollPosition, updateRangeBackground, { immediate: true });
    });
    onUnmounted(() => {
      if (ganttWrapper.value) {
        ganttWrapper.value.removeEventListener("wheel", (e) => handleWheel(e, ganttWrapper.value));
      }
      window.removeEventListener("mousemove", handleTimeaxisMouseMove);
      window.removeEventListener("mouseup", handleTimeaxisMouseUp);
      window.removeEventListener("mousemove", (e) => handleResizeMove(e, handleSectionResize));
      window.removeEventListener("mouseup", handleResizeEnd);
      window.removeEventListener("keydown", handleKeyboardShortcuts);
      if (resizeObserver) {
        resizeObserver.disconnect();
      }
      window.removeEventListener("resize", updateBarPositions);
    });
    watch([() => props.chartStart, () => props.chartEnd], () => {
      updateBarPositions();
    });
    watch(
      () => props.showImporter,
      (newValue) => {
        isImporterVisible.value = newValue;
      }
    );
    watch(
      () => props.baseUnitWidth,
      (newValue) => {
        validatedBaseUnitWidth.value = Math.max(20, newValue);
      }
    );
    watch(
      () => props.defaultZoom,
      (newValue) => {
        validatedDefaultZoom.value = Math.min(10, Math.max(1, newValue));
      }
    );
    provide(CONFIG_KEY, {
      ...toRefs(props),
      baseUnitWidth: validatedBaseUnitWidth,
      defaultZoom: validatedDefaultZoom,
      colors,
      chartSize
    });
    provide(EMIT_BAR_EVENT_KEY, emitBarEvent);
    provide(BOOLEAN_KEY, { ...props });
    provide(GANTT_ID_KEY, id.value);
    provide(CHART_AREA_KEY, ganttChart);
    provide(CHART_WRAPPER_KEY, ganttWrapper);
    __expose({
      exportChart,
      isExporting
    });
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", {
        class: "g-gantt-container",
        role: "application",
        "aria-label": "Interactive Gantt",
        tabindex: "0",
        onKeydown: _cache[20] || (_cache[20] = //@ts-ignore
        (...args) => unref(handleKeyDown) && unref(handleKeyDown)(...args)),
        onMousemove: handleChartMouseMove,
        onMouseup: handleChartMouseUp,
        ref_key: "ganttContainer",
        ref: ganttContainer,
        id: id.value
      }, [
        createElementVNode("div", {
          class: "g-gantt-rounded-wrapper",
          ref_key: "gGantt",
          ref: gGantt
        }, [
          createElementVNode("div", _hoisted_2, [
            _ctx.labelColumnTitle ? (openBlock(), createElementBlock("div", {
              key: 0,
              class: "g-gantt-label-section",
              style: normalizeStyle(labelSectionStyle.value)
            }, [
              createVNode(_sfc_main$a, {
                ref_key: "labelColumn",
                ref: labelColumn,
                onScroll: unref(handleLabelScroll),
                onRowDrop: dropRow
              }, createSlots({ _: 2 }, [
                renderList(_ctx.$slots, (_, name) => {
                  return {
                    name,
                    fn: withCtx((slotData) => [
                      renderSlot(_ctx.$slots, name, normalizeProps(guardReactiveProps(slotData)))
                    ])
                  };
                })
              ]), 1032, ["onScroll"]),
              createElementVNode("div", {
                class: "g-gantt-section-resizer",
                onMousedown: _cache[0] || (_cache[0] = (e) => unref(handleResizeStart)(e, labelSectionWidth.value)),
                onTouchstart: _cache[1] || (_cache[1] = (e) => unref(handleTouchStart)(e, labelSectionWidth.value)),
                onTouchmove: _cache[2] || (_cache[2] = (e) => unref(handleTouchMove)(e, handleSectionResize)),
                onTouchend: _cache[3] || (_cache[3] = //@ts-ignore
                (...args) => unref(resetResizeState) && unref(resetResizeState)(...args)),
                onTouchcancel: _cache[4] || (_cache[4] = //@ts-ignore
                (...args) => unref(resetResizeState) && unref(resetResizeState)(...args))
              }, null, 32)
            ], 4)) : createCommentVNode("", true),
            createElementVNode("div", {
              ref_key: "ganttWrapper",
              ref: ganttWrapper,
              class: "gantt-wrapper",
              style: normalizeStyle({
                width: "100%",
                "overflow-x": _ctx.commands ? "hidden" : "auto"
              })
            }, [
              createElementVNode("div", {
                ref_key: "ganttChart",
                ref: ganttChart,
                class: "g-gantt-chart",
                style: normalizeStyle({
                  width: `${totalWidth.value}px`,
                  background: colors.value.background,
                  fontFamily: unref(font)
                })
              }, [
                !_ctx.hideTimeaxis ? (openBlock(), createBlock(_sfc_main$8, {
                  key: 0,
                  ref_key: "timeaxisComponent",
                  ref: timeaxisComponent,
                  onDragStart: handleTimeaxisMouseDown,
                  onTouchstart: handleTimeaxisTouchStart,
                  onTouchmove: handleTimeaxisTouchMove,
                  onTouchend: handleTimeaxisTouchEnd,
                  onTouchcancel: handleTimeaxisTouchEnd,
                  timeaxisUnits: unref(timeaxisUnits),
                  internalPrecision: unref(internalPrecision)
                }, {
                  "upper-timeunit": withCtx((slotProps) => [
                    renderSlot(_ctx.$slots, "upper-timeunit", normalizeProps(guardReactiveProps(slotProps)))
                  ]),
                  timeunit: withCtx((slotProps) => [
                    renderSlot(_ctx.$slots, "timeunit", normalizeProps(guardReactiveProps(slotProps)))
                  ]),
                  "holiday-tooltip": withCtx((slotProps) => [
                    renderSlot(_ctx.$slots, "holiday-tooltip", normalizeProps(guardReactiveProps(slotProps)))
                  ]),
                  "event-tooltip": withCtx((slotProps) => [
                    renderSlot(_ctx.$slots, "event-tooltip", normalizeProps(guardReactiveProps(slotProps)))
                  ]),
                  "timeaxis-event": withCtx((slotProps) => [
                    renderSlot(_ctx.$slots, "timeaxis-event", normalizeProps(guardReactiveProps(slotProps)))
                  ]),
                  _: 3
                }, 8, ["timeaxisUnits", "internalPrecision"])) : createCommentVNode("", true),
                _ctx.grid ? (openBlock(), createBlock(_sfc_main$b, {
                  key: 1,
                  timeaxisUnits: unref(timeaxisUnits),
                  internalPrecision: unref(internalPrecision)
                }, null, 8, ["timeaxisUnits", "internalPrecision"])) : createCommentVNode("", true),
                _ctx.currentTime ? (openBlock(), createBlock(_sfc_main$7, { key: 2 }, {
                  "current-time-label": withCtx(() => [
                    renderSlot(_ctx.$slots, "current-time-label")
                  ]),
                  _: 3
                })) : createCommentVNode("", true),
                _ctx.pointerMarker ? (openBlock(), createBlock(_sfc_main$2, { key: 3 }, {
                  "pointer-marker-tooltips": withCtx(({ hitBars, datetime }) => [
                    renderSlot(_ctx.$slots, "pointer-marker-tooltips", normalizeProps(guardReactiveProps({ hitBars, datetime })))
                  ]),
                  _: 3
                })) : createCommentVNode("", true),
                (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.milestones, (milestone) => {
                  return openBlock(), createBlock(_sfc_main$5, {
                    key: milestone.date.toString(),
                    milestone
                  }, createSlots({ _: 2 }, [
                    renderList(_ctx.$slots, (_, name) => {
                      return {
                        name,
                        fn: withCtx((slotData) => [
                          name.startsWith("milestone-") || name === "milestone" ? renderSlot(_ctx.$slots, name, mergeProps({
                            key: 0,
                            ref_for: true
                          }, slotData)) : createCommentVNode("", true)
                        ])
                      };
                    })
                  ]), 1032, ["milestone"]);
                }), 128)),
                createElementVNode("div", {
                  class: "g-gantt-rows-container",
                  style: normalizeStyle(rowsContainerStyle.value),
                  ref_key: "rowsContainer",
                  ref: rowsContainer,
                  onScroll: _cache[5] || (_cache[5] = //@ts-ignore
                  (...args) => unref(handleContentScroll) && unref(handleContentScroll)(...args))
                }, [
                  (openBlock(true), createElementBlock(Fragment, null, renderList(rows.value, (row) => {
                    return openBlock(), createBlock(resolveDynamicComponent(renderRow(row)), {
                      key: row.id || row.label
                    });
                  }), 128)),
                  unref(connectionState).isCreating && previewLinePoints.value ? (openBlock(), createElementBlock("svg", _hoisted_3, [
                    previewLinePoints.value ? (openBlock(), createBlock(GGanttConnector, {
                      key: 0,
                      "source-bar": {
                        id: unref(connectionState).sourceBar.ganttBarConfig.id,
                        x: previewLinePoints.value.x1,
                        y: previewLinePoints.value.y1,
                        width: 0,
                        height: 0
                      },
                      "target-bar": {
                        id: "preview",
                        x: previewLinePoints.value.x2,
                        y: previewLinePoints.value.y2,
                        width: 0,
                        height: 0
                      },
                      type: "straight",
                      color: _ctx.defaultConnectionColor,
                      pattern: _ctx.defaultConnectionPattern,
                      animated: _ctx.defaultConnectionAnimated,
                      "animation-speed": _ctx.defaultConnectionAnimationSpeed,
                      relation: _ctx.defaultConnectionRelation,
                      style: { opacity: 0.6 },
                      marker: _ctx.markerConnection
                    }, null, 8, ["source-bar", "target-bar", "color", "pattern", "animated", "animation-speed", "relation", "marker"])) : createCommentVNode("", true)
                  ])) : createCommentVNode("", true),
                  _ctx.enableConnections ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(unref(connections), (conn) => {
                    return openBlock(), createElementBlock(Fragment, {
                      key: `${conn.sourceId}-${conn.targetId}`
                    }, [
                      unref(barPositions).get(conn.sourceId) && unref(barPositions).get(conn.targetId) ? (openBlock(), createBlock(GGanttConnector, mergeProps({
                        key: 0,
                        ref_for: true
                      }, unref(getConnectorProps)(conn), {
                        marker: _ctx.markerConnection,
                        onClick: ($event) => unref(handleConnectionClick)(conn)
                      }), null, 16, ["marker", "onClick"])) : createCommentVNode("", true)
                    ], 64);
                  }), 128)) : createCommentVNode("", true)
                ], 36)
              ], 4)
            ], 4)
          ]),
          _ctx.commands ? (openBlock(), createElementBlock("div", {
            key: 0,
            class: "g-gantt-command",
            style: normalizeStyle({ background: colors.value.commands, fontFamily: unref(font) }),
            "aria-label": "Gantt Commands"
          }, [
            renderSlot(_ctx.$slots, "commands", {
              zoomIn: () => unref(handleZoomUpdate)(true),
              zoomOut: () => unref(handleZoomUpdate)(false),
              scrollRowUp: () => unref(scrollRowUp)(),
              scrollRowDown: () => unref(scrollRowDown)(),
              expandAllGroups: () => unref(rowManager).expandAllGroups(),
              collapseAllGroups: () => unref(rowManager).collapseAllGroups(),
              handleToStart: () => unref(handleStep)(0, ganttWrapper.value),
              handleBack: () => unref(handleStep)(unref(scrollPosition) - 10, ganttWrapper.value),
              handleScroll: () => unref(handleScroll)(ganttWrapper.value),
              handleForward: () => unref(handleStep)(unref(scrollPosition) + 10, ganttWrapper.value),
              handleToEnd: () => unref(handleStep)(100, ganttWrapper.value),
              undo: () => undo(),
              redo: () => redo(),
              canUndo: unref(rowManager).canUndo,
              canRedo: unref(rowManager).canRedo,
              isAtTop: unref(isAtTop),
              isAtBottom: unref(isAtBottom),
              zoomLevel: unref(zoomLevel),
              export: () => triggerExport()
            }, () => [
              createElementVNode("div", _hoisted_4, [
                _ctx.maxRows > 0 ? (openBlock(), createElementBlock("div", _hoisted_5, [
                  createElementVNode("button", {
                    onClick: _cache[6] || (_cache[6] = //@ts-ignore
                    (...args) => unref(scrollRowUp) && unref(scrollRowUp)(...args)),
                    "aria-label": "Scroll row up",
                    disabled: unref(isAtTop)
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAngleUp),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_6),
                  createElementVNode("button", {
                    onClick: _cache[7] || (_cache[7] = //@ts-ignore
                    (...args) => unref(scrollRowDown) && unref(scrollRowDown)(...args)),
                    "aria-label": "Scroll row down",
                    disabled: unref(isAtBottom)
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAngleDown),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_7)
                ])) : createCommentVNode("", true),
                hasGroupRows.value ? (openBlock(), createElementBlock("div", _hoisted_8, [
                  createElementVNode("button", {
                    onClick: _cache[8] || (_cache[8] = ($event) => unref(rowManager).expandAllGroups()),
                    "aria-label": "Expand all groups",
                    disabled: unref(rowManager).areAllGroupsExpanded.value
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faExpandAlt),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_9),
                  createElementVNode("button", {
                    onClick: _cache[9] || (_cache[9] = ($event) => unref(rowManager).collapseAllGroups()),
                    "aria-label": "Collapse all groups",
                    disabled: unref(rowManager).areAllGroupsCollapsed.value
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faCompressAlt),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_10)
                ])) : createCommentVNode("", true)
              ]),
              createElementVNode("div", _hoisted_11, [
                createElementVNode("div", _hoisted_12, [
                  createElementVNode("button", {
                    disabled: unref(scrollPosition) === 0,
                    onClick: _cache[10] || (_cache[10] = ($event) => unref(handleStep)(0, ganttWrapper.value)),
                    "aria-label": "Scroll to start"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAnglesLeft),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_13),
                  createElementVNode("button", {
                    disabled: unref(scrollPosition) === 0,
                    onClick: _cache[11] || (_cache[11] = ($event) => unref(handleStep)(unref(scrollPosition) - 10, ganttWrapper.value)),
                    "aria-label": "Scroll back"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAngleLeft),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_14),
                  withDirectives(createElementVNode("input", {
                    "onUpdate:modelValue": _cache[12] || (_cache[12] = ($event) => isRef(scrollPosition) ? scrollPosition.value = $event : null),
                    type: "range",
                    min: "0",
                    max: "100",
                    class: "g-gantt-scroller",
                    style: normalizeStyle({ "--value": `${unref(scrollPosition)}%` }),
                    onInput: _cache[13] || (_cache[13] = ($event) => unref(handleScroll)(ganttWrapper.value)),
                    "aria-valuemin": 0,
                    "aria-valuemax": 100,
                    "aria-valuenow": unref(scrollPosition),
                    "aria-label": "Gantt scroll position"
                  }, null, 44, _hoisted_15), [
                    [vModelText, unref(scrollPosition)]
                  ]),
                  createElementVNode("button", {
                    disabled: unref(scrollPosition) === 100,
                    onClick: _cache[14] || (_cache[14] = ($event) => unref(handleStep)(unref(scrollPosition) + 10, ganttWrapper.value)),
                    "aria-label": "Scroll up"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAngleRight),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_16),
                  createElementVNode("button", {
                    disabled: unref(scrollPosition) === 100,
                    onClick: _cache[15] || (_cache[15] = ($event) => unref(handleStep)(100, ganttWrapper.value)),
                    "aria-label": "Scroll to end"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faAnglesRight),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_17)
                ])
              ]),
              createElementVNode("div", _hoisted_18, [
                createElementVNode("div", _hoisted_19, [
                  createElementVNode("button", {
                    onClick: _cache[16] || (_cache[16] = () => unref(handleZoomUpdate)(false)),
                    "aria-label": "Zoom-out Gantt",
                    disabled: unref(zoomLevel) === 1 && unref(internalPrecision) === "month"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faMagnifyingGlassMinus),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_20),
                  createElementVNode("button", {
                    onClick: _cache[17] || (_cache[17] = () => unref(handleZoomUpdate)(true)),
                    "aria-label": "Zoom-out Gantt",
                    disabled: unref(zoomLevel) === 10 && unref(internalPrecision) === _ctx.precision
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faMagnifyingGlassPlus),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_21)
                ]),
                createElementVNode("div", _hoisted_22, [
                  createElementVNode("button", {
                    onClick: undo,
                    disabled: !unref(rowManager).canUndo.value,
                    "aria-label": "Undo last action"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faUndo),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_23),
                  createElementVNode("button", {
                    onClick: redo,
                    disabled: !unref(rowManager).canRedo.value,
                    "aria-label": "Redo action"
                  }, [
                    createVNode(unref(FontAwesomeIcon), {
                      icon: unref(faRedo),
                      class: "command-icon"
                    }, null, 8, ["icon"])
                  ], 8, _hoisted_24)
                ])
              ]),
              createElementVNode("div", _hoisted_25, [
                _ctx.exportEnabled ? (openBlock(), createElementBlock("div", _hoisted_26, [
                  createElementVNode("div", _hoisted_27, [
                    withDirectives(createElementVNode("select", {
                      "onUpdate:modelValue": _cache[18] || (_cache[18] = ($event) => selectedExportFormat.value = $event),
                      class: "g-gantt-export-select",
                      disabled: unref(isExporting)
                    }, _cache[21] || (_cache[21] = [
                      createStaticVNode('<option value="" disabled>Export</option><option value="pdf">PDF</option><option value="png">PNG</option><option value="svg">SVG</option><option value="excel">Excel</option>', 5)
                    ]), 8, _hoisted_28), [
                      [vModelSelect, selectedExportFormat.value]
                    ]),
                    createElementVNode("button", {
                      onClick: triggerExport,
                      disabled: !selectedExportFormat.value || unref(isExporting)
                    }, [
                      createVNode(unref(FontAwesomeIcon), {
                        icon: unref(faFileExport),
                        class: "command-icon"
                      }, null, 8, ["icon"]),
                      unref(isExporting) ? (openBlock(), createElementBlock("span", _hoisted_30, [
                        createVNode(unref(FontAwesomeIcon), {
                          icon: unref(faSpinner),
                          class: "fa-spin"
                        }, null, 8, ["icon"])
                      ])) : createCommentVNode("", true)
                    ], 8, _hoisted_29)
                  ])
                ])) : createCommentVNode("", true)
              ])
            ])
          ], 4)) : createCommentVNode("", true)
        ], 512),
        createVNode(_sfc_main$9, {
          type: "bar",
          "model-value": unref(showTooltip) || isDragging.value,
          bar: unref(tooltipBar)
        }, {
          default: withCtx((slotProps) => [
            renderSlot(_ctx.$slots, "bar-tooltip", normalizeProps(guardReactiveProps(slotProps)))
          ]),
          _: 3
        }, 8, ["model-value", "bar"]),
        createVNode(_sfc_main$1, {
          modelValue: isImporterVisible.value,
          "onUpdate:modelValue": _cache[19] || (_cache[19] = ($event) => isImporterVisible.value = $event),
          title: props.importerTitle,
          "default-format": props.importerDefaultFormat,
          "allowed-formats": props.importerAllowedFormats,
          onImport: handleImport,
          onClose: closeImporter
        }, null, 8, ["modelValue", "title", "default-format", "allowed-formats"])
      ], 40, _hoisted_1);
    };
  }
});
function extendDayjs() {
  dayjs.extend(isSameOrBefore);
  dayjs.extend(isSameOrAfter);
  dayjs.extend(isBetween);
  dayjs.extend(customParseFormat);
  dayjs.extend(weekOfYear);
  dayjs.extend(isoWeek);
  dayjs.extend(advancedFormat);
  dayjs.extend(dayOfYear);
  dayjs.extend(localizedFormat);
  dayjs.extend(utc);
}
const hyvuegantt = {
  install(app) {
    extendDayjs();
    app.component("GGanttChart", _sfc_main);
    app.component("GGanttRow", _sfc_main$3);
  }
};
function injectStyle(css, insertAt = "top") {
  if (!css || typeof document === "undefined") return;
  const head = document.head || document.querySelector("head");
  const firstChild = head.querySelector(":first-child");
  const style = document.createElement("style");
  style.appendChild(document.createTextNode(css));
  if (insertAt === "top" && firstChild) {
    head.insertBefore(style, firstChild);
  } else {
    head.appendChild(style);
  }
}
injectStyle('\n.g-gantt-container {\n  display: flex;\n  flex-direction: column;\n  width: 100%;\n}\n/* Layout */\n.g-gantt-chart {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  overflow-x: hidden;\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n          user-select: none;\n  font-feature-settings: "tnum";\n  font-variant-numeric: tabular-nums;\n}\n\n/* Container Styles */\n.g-gantt-rows-container {\n  position: relative;\n  width: 100%;\n  height: 100%;\n  overflow: visible;\n  scrollbar-width: none;\n  -ms-overflow-style: none;\n}\n.labels-in-column {\n  display: flex;\n  flex-direction: row;\n}\n\n/* Command Section Styles */\n.g-gantt-command {\n  display: flex;\n  align-items: center;\n  height: 40px;\n  border-top: 1px solid #eaeaea;\n  padding: 0px 6px;\n  gap: 8px;\n}\n.g-gantt-command-block {\n  display: flex;\n  gap: 8px;\n}\n.g-gantt-command-fixed,\n.g-gantt-command-slider,\n.g-gantt-command-vertical,\n.g-gantt-command-zoom,\n.g-gantt-command-history,\n.g-gantt-command-groups,\n.g-gantt-export-container {\n  display: flex;\n  align-items: center;\n  gap: 2px;\n}\n.g-gantt-command-custom {\n  flex-grow: 1;\n}\n.g-gantt-command-vertical button:disabled,\n.g-gantt-command-slider button:disabled,\n.g-gantt-command-zoom button:disabled,\n.g-gantt-command-groups button:disabled,\n.g-gantt-command-history button:disabled,\n.g-gantt-export-container button:disabled {\n  opacity: 0.5;\n  cursor: not-allowed;\n}\n.g-gantt-export-select {\n  border-radius: 4px;\n  font-size: 0.75rem;\n  padding-left: 2px;\n  padding-right: 2px;\n  padding-top: 0;\n  padding-bottom: 0;\n  height: 22px;\n}\n.g-gantt-export-loading {\n  margin-left: 4px;\n}\n.g-gantt-export-menu button:hover {\n  background: #f5f5f5;\n}\n@media screen and (max-width: 768px) {\n.g-gantt-command {\n    height: auto;\n    min-height: 0;\n    min-height: initial;\n    flex-direction: column;\n    align-items: stretch;\n    padding: 12px 6px;\n    gap: 12px;\n}\n.g-gantt-command > * {\n    width: 100%;\n}\n.g-gantt-command-block {\n    display: flex;\n    justify-content: center;\n    gap: 20px;\n}\n.g-gantt-command-fixed {\n    flex-direction: column;\n    gap: 8px;\n}\n.g-gantt-command-groups {\n    justify-content: center;\n    margin-right: 0;\n}\n.g-gantt-command-slider {\n    width: 100%;\n    justify-content: center;\n}\n.g-gantt-command-vertical {\n    flex-direction: row;\n    justify-content: center;\n}\n.g-gantt-command-zoom,\n  .g-gantt-command-history {\n    justify-content: center;\n}\n.g-gantt-command-export {\n    display: flex;\n    align-items: center;\n}\n.command-icon {\n    padding: 8px;\n    width: 16px;\n    height: 16px;\n}\n.g-gantt-scroller {\n    height: 12px;\n}\n.g-gantt-scroller::-webkit-slider-thumb {\n    width: 24px;\n    height: 24px;\n}\n.g-gantt-scroller::-moz-range-thumb {\n    width: 24px;\n    height: 24px;\n}\n}\n\n/* Scroller Styles */\n.g-gantt-scroller {\n  -webkit-appearance: none;\n  height: 8px;\n  border-radius: 4px;\n  outline: none;\n  background: linear-gradient(\n    to right,\n    var(--1fed23a5) var(--value),\n    #ddd var(--value)\n  );\n}\n\n/* Scroller Thumb Styles */\n.g-gantt-scroller::-webkit-slider-thumb {\n  -webkit-appearance: none;\n  appearance: none;\n  width: 16px;\n  height: 16px;\n  background: var(--1fed23a5);\n  border-radius: 50%;\n  cursor: pointer;\n  border: none;\n}\n.g-gantt-scroller::-moz-range-thumb {\n  width: 16px;\n  height: 16px;\n  background: var(--1fed23a5);\n  border-radius: 50%;\n  cursor: pointer;\n  border: none;\n}\n\n/* Track Styles */\n.g-gantt-scroller::-moz-range-track {\n  height: 8px;\n  background: #ddd;\n  border-radius: 4px;\n  border: none;\n}\n\n/* Hover States */\n.g-gantt-scroller::-webkit-slider-thumb:hover {\n  background: var(--1fed23a5);\n}\n.g-gantt-scroller::-moz-range-thumb:hover {\n  background: var(--1fed23a5);\n}\n\n/* Icon Styles */\n.command-icon {\n  background: var(--1fed23a5);\n  padding: 4px;\n  margin: 2px;\n  width: 14px;\n  height: 14px;\n  border-radius: 4px;\n}\nbutton {\n  display: flex;\n  padding: 0;\n  background-color: transparent;\n  background-image: none;\n  border: 0;\n  color: var(--787ffb4a);\n}\n.g-gantt-chart:focus-within {\n  outline: 2px solid var(--31d9cbd8);\n  outline-offset: 2px;\n}\n.g-gantt-rounded-wrapper {\n  border-radius: 5px;\n  overflow: hidden;\n  border: 1px solid #eaeaea;\n  background: white;\n  display: flex;\n  flex-direction: column;\n}\n.g-gantt-rows-container::-webkit-scrollbar {\n  display: none;\n}\n.g-gantt-main-layout {\n  display: flex;\n  width: 100%;\n  position: relative;\n}\n.g-gantt-label-section {\n  position: relative;\n  display: flex;\n}\n.g-gantt-section-resizer {\n  position: absolute;\n  right: -4px;\n  top: 0;\n  width: 8px;\n  height: 100%;\n  cursor: col-resize;\n  background: transparent;\n  z-index: 10;\n  transition: background 0.2s ease;\n}\n.g-gantt-section-resizer:hover {\n  background: rgba(0, 0, 0, 0.1);\n}\n.g-gantt-section-resizer:active {\n  background: rgba(0, 0, 0, 0.2);\n}\n@media (max-width: 768px) {\n.g-gantt-section-resizer {\n    width: 16px;\n    right: -8px;\n}\n}\n.connection-preview {\n  pointer-events: none;\n}\n\n.g-gantt-row {\n  width: 100%;\n  transition: background 0.4s;\n  position: relative;\n}\n\n/*.g-gantt-row:last-child {\n  border-bottom: 0px !important;\n}*/\n.g-gantt-row > .g-gantt-row-bars-container {\n  position: relative;\n  width: 100%;\n}\n.g-gantt-row-label {\n  position: absolute;\n  top: 0;\n  left: 0px;\n  padding: 0px 8px;\n  display: flex;\n  align-items: center;\n  height: 60%;\n  min-height: 20px;\n  font-size: 0.8em;\n  font-weight: bold;\n  border-bottom-right-radius: 6px;\n  background: #f2f2f2;\n  z-index: 3;\n  box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.6);\n}\n.g-gantt-row-group-label {\n  font-weight: bold;\n  background: #e0e0e0 !important;\n}\n.g-gantt-row-children {\n  transition: max-height 0.3s ease-in-out;\n}\n.bar-transition-leave-active,\n.bar-transition-enter-active {\n  transition: all 0.2s;\n}\n.bar-transition-enter-from,\n.bar-transition-leave-to {\n  transform: scale(0.8);\n  opacity: 0;\n}\n.g-gantt-range-selection {\n  border-radius: 2px;\n  box-sizing: border-box;\n}\n.g-gantt-row-bars-container {\n  cursor: crosshair;\n}\n.g-gantt-row-bars-container:has(.g-gantt-bar) {\n  cursor: default;\n}\n\n.g-gantt-bar {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  background: cadetblue;\n  overflow: visible;\n  position: relative;\n}\n.g-gantt-bar-label {\n  width: 100%;\n  height: 100%;\n  box-sizing: border-box;\n  padding: 0 14px 0 14px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  position: relative;\n  z-index: 2;\n  pointer-events: none;\n}\n.g-gantt-bar-label > * {\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n.g-gantt-bar-handle-left,\n.g-gantt-bar-handle-right {\n  position: absolute;\n  width: 10px;\n  height: 100%;\n  background: white;\n  opacity: 0.7;\n  border-radius: 0px;\n  cursor: ew-resize;\n  top: 0;\n}\n.g-gantt-bar-handle-left {\n  left: 0;\n}\n.g-gantt-bar-handle-right {\n  right: 0;\n}\n.g-gantt-bar-label img {\n  pointer-events: none;\n}\n.g-gantt-bar-label-edit {\n  width: 100%;\n  height: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  pointer-events: all;\n}\n.g-gantt-bar-label-input {\n  background: rgba(255, 255, 255, 0.2);\n  border-radius: 4px;\n  width: 100%;\n  height: 100%;\n  background: white;\n  color: black;\n  outline: none;\n  font: inherit;\n  padding: 2px;\n  text-align: center;\n}\n.is-group-bar {\n  background: transparent !important;\n}\n.group-bar-decoration {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n.g-gantt-progress-bar {\n  position: absolute;\n  pointer-events: none;\n  overflow: hidden;\n  min-width: 8px;\n  display: flex;\n  align-items: center;\n  justify-content: flex-end;\n  /*padding-right: 10px;*/\n  color: #fff;\n  font-size: 0.8em;\n  font-weight: 500;\n  z-index: 1;\n}\n.progress-text {\n  padding-right: 10px;\n}\n.g-gantt-progress-handle {\n  position: absolute;\n  top: 0;\n  width: 8px;\n  height: 100%;\n  background-color: rgba(0, 0, 0, 0.3);\n  cursor: ew-resize;\n  pointer-events: all;\n  transition: background-color 0.2s ease;\n  z-index: 3;\n}\n.g-gantt-progress-handle:hover {\n  background-color: rgba(0, 0, 0, 0.5);\n}\n.g-gantt-progress-handle:active {\n  background-color: rgba(0, 0, 0, 0.7);\n}\n.connection-point {\n  z-index: 10;\n}\n.connection-point:hover {\n  transform: translate(-50%, -50%) scale(1.2);\n}\n.connection-point.end:hover {\n  transform: translate(50%, -50%) scale(1.2);\n}\n\n.g-timeaxis {\n  position: sticky;\n  top: 0;\n  width: 100%;\n  height: 80px;\n  background: white;\n  z-index: 4;\n  display: flex;\n  flex-direction: column;\n  cursor: grab;\n}\n.g-timeaxis:active {\n  cursor: grabbing;\n}\n.g-timeunits-container {\n  display: flex;\n  width: 100%;\n  height: 50%;\n}\n.g-timeunit {\n  height: 100%;\n  font-size: 65%;\n  display: flex;\n  justify-content: center;\n}\n.g-upper-timeunit {\n  display: flex;\n  height: 100%;\n  justify-content: center;\n  align-items: center;\n}\n.g-timeaxis-hour-pin {\n  width: 1px;\n  height: 10px;\n}\n.label-unit {\n  flex-grow: 1;\n  text-align: center;\n  line-height: normal;\n}\n.g-timeunit-min {\n  display: flex;\n  flex-direction: row-reverse;\n  align-items: center;\n  width: 100%;\n  line-height: 20px;\n}\n.g-timeunit-step {\n  display: flex;\n  width: 100%;\n  line-height: 20px;\n}\n.g-events-container {\n  display: flex;\n  width: 100%;\n  position: relative;\n  overflow: hidden;\n  height: 100%;\n}\n.g-timeaxis-event {\n  height: 100%;\n  position: absolute;\n  font-size: 65%;\n  padding: 0 6px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  border: 1px solid;\n  box-sizing: border-box;\n  cursor: pointer;\n  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n  transition: box-shadow 0.2s ease;\n}\n.g-timeaxis-event:hover {\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n  z-index: 5;\n}\n\n.g-grid-container {\n  position: absolute;\n  top: 0;\n  left: 0%;\n  width: 100%;\n  height: 100%;\n  display: flex;\n  justify-content: space-between;\n}\n.g-grid-line {\n  width: 1px;\n  height: 100%;\n}\n.g-grid-line:first-child {\n  border-left: 0px !important;\n}\n\n/* Bar Tooltip Styles */\n.g-gantt-tooltip {\n  position: fixed;\n  background: black;\n  color: white;\n  z-index: 4;\n  font-size: 0.85em;\n  padding: 5px;\n  border-radius: 3px;\n  transition: opacity 0.2s;\n  display: flex;\n  align-items: center;\n  font-feature-settings: "tnum";\n  font-variant-numeric: tabular-nums;\n}\n.g-gantt-tooltip:before {\n  content: "";\n  position: absolute;\n  top: 0;\n  left: 10%;\n  width: 0;\n  height: 0;\n  border: 10px solid transparent;\n  border-bottom-color: black;\n  border-top: 0;\n  margin-left: -5px;\n  margin-top: -5px;\n}\n.g-gantt-tooltip-color-dot {\n  width: 8px;\n  height: 8px;\n  border-radius: 100%;\n  margin-right: 4px;\n}\n\n/* Event Tooltip Styles */\n.g-gantt-event-tooltip {\n  position: fixed;\n  z-index: 1000;\n  min-width: 180px;\n  max-width: 280px;\n  border-radius: 4px;\n  padding: 8px 12px;\n  font-size: 12px;\n  transform: translateX(-50%);\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n  pointer-events: none;\n}\n.g-gantt-event-tooltip:after {\n  content: "";\n  position: absolute;\n  bottom: -6px;\n  left: 50%;\n  transform: translateX(-50%);\n  width: 0;\n  height: 0;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-top: 6px solid #2a2f42;\n  border-top: 6px solid var(--tooltip-background, #2a2f42);\n}\n.g-gantt-event-tooltip-title {\n  font-weight: bold;\n  margin-bottom: 4px;\n}\n.g-gantt-event-tooltip-time {\n  font-size: 11px;\n  opacity: 0.9;\n  margin-bottom: 4px;\n}\n.g-gantt-event-tooltip-description {\n  font-size: 11px;\n  line-height: 1.4;\n  opacity: 0.9;\n  margin-top: 4px;\n  white-space: normal;\n  word-break: break-word;\n}\n\n/* Holiday Tooltip Styles */\n.g-gantt-holiday-tooltip {\n  position: fixed;\n  background: rgba(0, 0, 0, 0.8);\n  color: white;\n  padding: 4px 8px;\n  border-radius: 4px;\n  font-size: 12px;\n  z-index: 1000;\n  transform: translateX(-50%);\n  white-space: nowrap;\n}\n.g-gantt-holiday-tooltip:after {\n  content: "";\n  position: absolute;\n  bottom: -5px;\n  left: 50%;\n  transform: translateX(-50%);\n  width: 0;\n  height: 0;\n  border-left: 5px solid transparent;\n  border-right: 5px solid transparent;\n  border-top: 5px solid rgba(0, 0, 0, 0.8);\n}\n\n/* Transition Animations */\n.g-fade-enter-active,\n.g-fade-leave-active {\n  transition: opacity 0.3s ease;\n}\n.g-fade-enter-from,\n.g-fade-leave-to {\n  opacity: 0;\n}\n\n.g-grid-current-time {\n  position: absolute;\n  height: 100%;\n  display: flex;\n  z-index: 5;\n  pointer-events: none;\n}\n.g-grid-current-time-marker {\n  width: 0px;\n  height: calc(100% - 2px);\n  display: flex;\n}\n.g-grid-current-time-text {\n  font-size: x-small;\n}\n\n.g-label-column {\n  display: flex;\n  flex-direction: column;\n  color: rgb(64, 64, 64);\n  font-feature-settings: "tnum";\n  font-variant-numeric: tabular-nums;\n  font-size: 0.9em;\n  background: white;\n  box-sizing: border-box;\n  flex-shrink: 0;\n}\n.g-label-column-header {\n  width: 100%;\n  height: 80px;\n  min-height: 80px;\n  overflow: visible;\n  display: flex;\n  align-items: center;\n  overflow: visible;\n}\n.g-label-column-row-inner {\n  display: flex;\n  width: 100%;\n  min-width: 100%;\n  flex-wrap: nowrap;\n  align-items: center;\n}\n.g-label-column-header-cell {\n  flex: none;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 0 0.5rem;\n  height: 100%;\n  gap: 0.5rem;\n  box-sizing: border-box;\n  position: relative;\n  overflow: visible;\n  text-align: center;\n}\n.g-label-column-cell {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 0.1rem 0.3rem;\n  box-sizing: border-box;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  flex: none;\n}\n.header-content {\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  gap: 0.5rem;\n  padding: 0 4px;\n}\n.cell-content {\n  display: flex;\n  align-items: center;\n  width: 100%;\n  gap: 4px;\n}\n.text-ellipsis {\n  flex: 1;\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n.text-ellipsis-value {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n.g-label-column-header-cell.sortable {\n  cursor: pointer;\n  transition: background-color 0.2s ease;\n}\n.g-label-column-header-cell.sortable:hover {\n  background-color: rgba(0, 0, 0, 0.1);\n}\n.g-label-column-rows {\n  width: 100%;\n  overflow-y: auto;\n  overflow-x: hidden;\n}\n.g-label-column-rows::-webkit-scrollbar {\n  display: none;\n}\n.g-label-column-row {\n  width: 100%;\n  display: flex;\n  box-sizing: border-box;\n  align-items: center;\n  flex-wrap: nowrap;\n}\n\n/*.g-label-column-row:last-child {\n  border-bottom: 0px !important;\n}*/\n.sort-icon {\n  display: inline-flex;\n  align-items: center;\n  opacity: 0.6;\n  font-size: 0.8em;\n  transition: opacity 0.2s ease;\n}\n.sortable:hover .sort-icon {\n  opacity: 1;\n}\n.column-resizer {\n  position: absolute;\n  right: -1px;\n  top: 0;\n  width: 8px;\n  height: 100%;\n  cursor: col-resize;\n  z-index: 1;\n  background: transparent;\n}\n.column-resizer:hover,\n.column-resizer.is-dragging,\n.column-resizer.is-touch-resizing {\n  background: rgba(0, 0, 0, 0.1);\n}\n.g-label-column-header-cell:has(.column-resizer.is-touch-resizing) {\n  background-color: rgba(0, 0, 0, 0.05);\n}\n@media (max-width: 768px) {\n.column-resizer {\n    width: 16px;\n}\n}\n.g-label-column {\n  -webkit-user-select: none;\n     -moz-user-select: none;\n          user-select: none;\n}\n.g-label-column.dragging {\n  cursor: col-resize;\n}\n.g-label-column-group {\n  font-weight: 600;\n  background-color: rgba(0, 0, 0, 0.03);\n}\n.group-toggle-button {\n  flex: 0 0 20px;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 20px;\n  height: 20px;\n  padding: 0;\n  border: none;\n  background: transparent;\n  cursor: pointer;\n  transition: transform 0.2s ease;\n}\n.group-toggle-button:hover {\n  background-color: rgba(0, 0, 0, 0.05);\n  border-radius: 4px;\n}\n.group-icon {\n  width: 12px;\n  height: 12px;\n  transition: transform 0.2s ease;\n}\n.group-label {\n  font-weight: 600;\n}\n.g-label-column-row-draggable {\n  cursor: move;\n}\n.g-label-column-row-dragging {\n  opacity: 0.5;\n  background: #f0f0f0 !important;\n  background: var(--dragging-background, #f0f0f0) !important;\n}\n.g-label-column-row-drop-target {\n  position: relative;\n}\n.g-label-column-row-drop-before::before,\n.g-label-column-row-drop-after::after {\n  content: "";\n  position: absolute;\n  left: 0;\n  right: 0;\n  height: 2px;\n  background: #4a9eff;\n  background: var(--drop-indicator-color, #4a9eff);\n  z-index: 1;\n}\n.g-label-column-row-drop-before::before {\n  top: 0;\n}\n.g-label-column-row-drop-after::after {\n  bottom: 0;\n}\n.g-label-column-row-drop-child {\n  background: rgba(74, 158, 255, 0.1) !important;\n  background: var(--drop-child-background, rgba(74, 158, 255, 0.1)) !important;\n}\n.is-touch-dragging {\n  opacity: 0.8;\n  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n  pointer-events: none;\n}\n@media (max-width: 768px) {\n.group-toggle-button {\n    padding: 12px;\n}\n}\n.g-label-column-header-cell-ex {\n  position: relative;\n  flex-grow: 1;\n}\n\n.g-gantt-milestone {\n  position: absolute;\n  height: 100%;\n  display: flex;\n  z-index: 5;\n  pointer-events: auto;\n  flex-direction: column;\n  align-items: center;\n}\n.g-gantt-milestone-marker {\n  width: 0px;\n  height: calc(100% - 30px);\n  display: flex;\n  margin-top: 25px;\n}\n.g-gantt-milestone-label {\n  padding: 2px 8px;\n  border-radius: 4px;\n  font-size: 0.8em;\n  white-space: nowrap;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n  position: absolute;\n  top: 4px;\n  transform: translateY(0);\n}\n.g-gantt-milestone-tooltip {\n  position: fixed;\n  padding: 8px;\n  border-radius: 4px;\n  font-size: 0.75em;\n  z-index: 1000;\n  min-width: 200px;\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n  transform: translateY(-100%);\n}\n.g-gantt-milestone-tooltip-title {\n  font-weight: bold;\n}\n.g-gantt-milestone-tooltip-date {\n  font-size: 0.9em;\n  opacity: 0.8;\n}\n.g-gantt-milestone-tooltip-description {\n  font-size: 0.9em;\n  line-height: 1.4;\n}\n.g-fade-enter-active,\n.g-fade-leave-active {\n  transition: opacity 0.3s ease;\n}\n.g-fade-enter-from,\n.g-fade-leave-to {\n  opacity: 0;\n}\n\n.g-grid-pointer-marker-container {\n  position: absolute;\n  height: 100%;\n  display: flex;\n  z-index: 5;\n  pointer-events: none;\n}\n.g-grid-pointer-marker-tooltip {\n  position: fixed;\n  padding: 8px;\n  border-radius: 4px;\n  font-size: 0.75em;\n  z-index: 1000;\n  min-width: 200px;\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n}\n.g-grid-pointer-marker-tooltip-content {\n  padding: 8px;\n}\n.g-grid-pointer-marker-marker {\n  width: 0px;\n  height: calc(100% - 2px);\n  display: flex;\n}\n.g-grid-pointer-marker-text {\n  font-size: x-small;\n}\n\n.g-gantt-importer-overlay {\n  position: fixed;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background: rgba(0, 0, 0, 0.5);\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  z-index: 1000;\n}\n.g-gantt-importer-modal {\n  width: 650px;\n  max-width: 95%;\n  max-height: 90vh;\n  border-radius: 8px;\n  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n}\n.g-gantt-importer-header {\n  padding: 10px 14px;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n}\n.g-gantt-importer-header h3 {\n  margin: 0;\n  font-size: 18px;\n  font-weight: 500;\n}\n.g-gantt-importer-close-btn {\n  background: none;\n  border: none;\n  font-size: 18px;\n  cursor: pointer;\n  padding: 4px 8px;\n  border-radius: 4px;\n  transition: background-color 0.2s;\n}\n.g-gantt-importer-close-btn:hover {\n  background-color: rgba(0, 0, 0, 0.1);\n}\n.g-gantt-importer-content {\n  padding: 20px;\n  overflow-y: auto;\n}\n\n/* Stepper styles */\n.g-gantt-importer-stepper {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin-bottom: 14px;\n}\n.g-gantt-stepper-step {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  position: relative;\n}\n.g-gantt-step-number {\n  width: 30px;\n  height: 30px;\n  border-radius: 50%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  margin-bottom: 8px;\n  font-weight: 500;\n  transition: all 0.3s;\n}\n.g-gantt-step-label {\n  font-size: 14px;\n  transition: color 0.3s;\n}\n.g-gantt-step-connector {\n  flex-grow: 1;\n  height: 2px;\n  margin: 0 10px;\n  margin-bottom: 30px;\n}\n\n/* File upload styles */\n.g-gantt-file-upload {\n  width: 100%;\n}\n.g-gantt-file-dropzone {\n  border: 2px dashed;\n  border-radius: 8px;\n  padding: 40px;\n  text-align: center;\n  cursor: pointer;\n  transition: all 0.3s;\n}\n.g-gantt-file-dropzone:hover {\n  border-color: currentColor;\n  background-color: rgba(0, 0, 0, 0.03);\n}\n.g-gantt-file-dropzone .file-icon {\n  font-size: 48px;\n  margin-bottom: 16px;\n}\n.g-gantt-file-dropzone p {\n  margin: 0 0 8px;\n  font-size: 16px;\n}\n.g-gantt-file-dropzone small {\n  color: #666;\n}\n.g-gantt-file-input {\n  display: none;\n}\n\n/* Configuration styles */\n.g-gantt-selected-file {\n  display: flex;\n  flex-direction: column;\n  gap: 6px;\n}\n.g-gantt-file-info {\n  padding: 12px;\n  border-radius: 8px;\n  display: flex;\n  flex-direction: column;\n  gap: 6px;\n}\n.g-gantt-import-options {\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n}\n.g-gantt-option-group {\n  display: flex;\n  flex-direction: column;\n  gap: 6px;\n}\n.g-gantt-option-group label {\n  font-weight: 500;\n  font-size: 14px;\n}\n.g-gantt-option-group select,\n.g-gantt-option-group input {\n  padding: 8px 12px;\n  border: 1px solid;\n  border-radius: 4px;\n  font-size: 14px;\n}\n.g-gantt-toggle-btn {\n  background: none;\n  border: none;\n  cursor: pointer;\n  padding: 0;\n  font-size: 14px;\n  -webkit-text-decoration: underline;\n  text-decoration: underline;\n}\n.g-gantt-advanced-options {\n  border-top: 1px solid;\n  padding-top: 16px;\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n}\n.g-gantt-import-actions {\n  display: flex;\n  justify-content: flex-end;\n  gap: 12px;\n  margin-top: 10px;\n}\n\n/* Result styles */\n.g-gantt-import-result {\n  display: flex;\n  flex-direction: column;\n  gap: 24px;\n  align-items: center;\n  text-align: center;\n}\n.g-gantt-result-success,\n.g-gantt-result-error {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 12px;\n}\n.result-icon {\n  font-size: 48px;\n  border-radius: 50%;\n  padding: 16px;\n  margin-bottom: 8px;\n}\n.g-gantt-warnings {\n  margin-top: 16px;\n  text-align: left;\n  padding: 16px;\n  border-radius: 8px;\n  border-left: 4px solid;\n  width: 100%;\n}\n.g-gantt-warnings h5 {\n  margin-top: 0;\n  margin-bottom: 6px;\n  display: flex;\n  align-items: center;\n  gap: 8px;\n}\n.g-gantt-warnings ul {\n  margin: 0;\n  padding-left: 14px;\n  max-height: 150px;\n  overflow-y: overlay;\n}\n\n/* Button styles */\n.g-gantt-button {\n  padding: 8px 16px;\n  border-radius: 4px;\n  font-size: 14px;\n  cursor: pointer;\n  transition: all 0.2s;\n  border: none;\n  font-weight: 500;\n}\n.g-gantt-result-actions {\n  display: flex;\n  gap: 4px;\n}\n.g-gantt-button:hover {\n  filter: brightness(0.95);\n}\n.g-gantt-button:disabled {\n  opacity: 0.6;\n  cursor: not-allowed;\n}\n\n/* Animations */\n.g-fade-enter-active,\n.g-fade-leave-active {\n  transition: opacity 0.3s ease;\n}\n.g-fade-enter-from,\n.g-fade-leave-to {\n  opacity: 0;\n}\n\n.gantt-connector[data-v-652d5ef8] {\n  overflow: visible;\n  pointer-events: none;\n}\n.connector-path[data-v-652d5ef8] {\n  transition: d 0.3s ease;\n}\n.connector-path.selected[data-v-652d5ef8] {\n  filter: drop-shadow(0 0 5px rgba(33, 150, 243, 0.6));\n}\n.relation-indicator[data-v-652d5ef8] {\n  font-weight: bold;\n  pointer-events: none;\n}\n\n/* Animation for dash pattern */\n.connector-animated-dash-slow[data-v-652d5ef8] {\n  animation: dashFlow-652d5ef8 4s linear infinite;\n}\n.connector-animated-dash-normal[data-v-652d5ef8] {\n  animation: dashFlow-652d5ef8 2s linear infinite;\n}\n.connector-animated-dash-fast[data-v-652d5ef8] {\n  animation: dashFlow-652d5ef8 1s linear infinite;\n}\n\n/* Animation for dot pattern */\n.connector-animated-dot-slow[data-v-652d5ef8] {\n  animation: dotFlow-652d5ef8 4s linear infinite;\n}\n.connector-animated-dot-normal[data-v-652d5ef8] {\n  animation: dotFlow-652d5ef8 2s linear infinite;\n}\n.connector-animated-dot-fast[data-v-652d5ef8] {\n  animation: dotFlow-652d5ef8 1s linear infinite;\n}\n\n/* Animation for dashdot pattern */\n.connector-animated-dashdot-slow[data-v-652d5ef8] {\n  animation: dashdotFlow-652d5ef8 4s linear infinite;\n}\n.connector-animated-dashdot-normal[data-v-652d5ef8] {\n  animation: dashdotFlow-652d5ef8 2s linear infinite;\n}\n.connector-animated-dashdot-fast[data-v-652d5ef8] {\n  animation: dashdotFlow-652d5ef8 1s linear infinite;\n}\n.connector-path[data-v-652d5ef8] {\n  marker-start: none;\n  transition:\n    d 0.3s ease, marker-start 0.3s ease;\n}\n.connection-endpoint[data-v-652d5ef8] {\n  filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.3));\n  transition: all 0.3s ease;\n  border: 1px solid black;\n  border-radius: 100%;\n}\n.connection-endpoint[data-v-652d5ef8]:hover {\n  r: 8;\n}\n@keyframes dashFlow-652d5ef8 {\n0% {\n    stroke-dasharray: 10, 10;\n    stroke-dashoffset: 0;\n}\n100% {\n    stroke-dasharray: 10, 10;\n    stroke-dashoffset: -20;\n}\n}\n@keyframes dotFlow-652d5ef8 {\n0% {\n    stroke-dasharray: 2, 8;\n    stroke-dashoffset: 0;\n}\n100% {\n    stroke-dasharray: 2, 8;\n    stroke-dashoffset: -10;\n}\n}\n@keyframes dashdotFlow-652d5ef8 {\n0% {\n    stroke-dasharray: 12, 6, 3, 6;\n    stroke-dashoffset: 0;\n}\n100% {\n    stroke-dasharray: 12, 6, 3, 6;\n    stroke-dashoffset: -27;\n}\n}\n', "top");
export {
  _sfc_main as GGanttChart,
  _sfc_main$3 as GGanttRow,
  hyvuegantt as default,
  extendDayjs,
  hyvuegantt
};