"use strict";
(self["webpackChunk"] = self["webpackChunk"] || []).push([[792],{

/***/ 170
(__unused_webpack_module, __unused_webpack___webpack_exports__, __webpack_require__) {


;// ../assets/scripts/utils/dom.js
/**
 * Adminator DOM Utility Functions
 * Provides jQuery-like functionality using vanilla JavaScript
 *
 * @module utils/dom
 * @example
 * import { DOM } from './utils/dom';
 *
 * // Select elements
 * const button = DOM.select('.my-button');
 * const items = DOM.selectAll('.list-item');
 *
 * // Add event listeners
 * DOM.on(button, 'click', () => console.log('Clicked!'));
 *
 * // Manipulate classes
 * DOM.addClass(button, 'active');
 * DOM.toggleClass(button, 'loading');
 */

/**
 * DOM utility object providing jQuery-like methods
 * @namespace
 */
const DOM = {
  /**
   * Select a single element matching the selector
   * Replaces jQuery's $('selector').first()
   *
   * @param {string} selector - CSS selector
   * @param {Document|Element} [context=document] - Context to search within
   * @returns {Element|null} The matched element or null
   *
   * @example
   * const header = DOM.select('.header');
   * const navItem = DOM.select('.nav-item', sidebar);
   */
  select: function (selector) {
    let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
    return context.querySelector(selector);
  },
  /**
   * Select all elements matching the selector
   * Replaces jQuery's $('selector')
   *
   * @param {string} selector - CSS selector
   * @param {Document|Element} [context=document] - Context to search within
   * @returns {Element[]} Array of matched elements
   *
   * @example
   * const buttons = DOM.selectAll('.btn');
   * buttons.forEach(btn => DOM.addClass(btn, 'initialized'));
   */
  selectAll: function (selector) {
    let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
    return Array.from(context.querySelectorAll(selector));
  },
  /**
   * Check if an element matching the selector exists
   *
   * @param {string} selector - CSS selector
   * @returns {boolean} True if element exists
   *
   * @example
   * if (DOM.exists('.sidebar')) {
   *   initSidebar();
   * }
   */
  exists: selector => {
    return document.querySelector(selector) !== null;
  },
  /**
   * Add an event listener to an element
   * Replaces jQuery's $.on()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} event - Event name (e.g., 'click', 'change')
   * @param {Function} handler - Event handler function
   * @param {Object} [options={}] - addEventListener options
   *
   * @example
   * DOM.on('.btn', 'click', handleClick);
   * DOM.on(button, 'click', handleClick, { once: true });
   */
  on: function (element, event, handler) {
    let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (element) {
      element.addEventListener(event, handler, options);
    }
  },
  /**
   * Remove an event listener from an element
   * Replaces jQuery's $.off()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} event - Event name
   * @param {Function} handler - Event handler to remove
   *
   * @example
   * DOM.off(button, 'click', handleClick);
   */
  off: (element, event, handler) => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (element) {
      element.removeEventListener(event, handler);
    }
  },
  /**
   * Add a class to an element
   * Replaces jQuery's $.addClass()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} className - Class name to add
   *
   * @example
   * DOM.addClass('.menu', 'open');
   */
  addClass: (element, className) => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (element) {
      element.classList.add(className);
    }
  },
  /**
   * Remove a class from an element
   * Replaces jQuery's $.removeClass()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} className - Class name to remove
   *
   * @example
   * DOM.removeClass('.menu', 'open');
   */
  removeClass: (element, className) => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (element) {
      element.classList.remove(className);
    }
  },
  /**
   * Toggle a class on an element
   * Replaces jQuery's $.toggleClass()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} className - Class name to toggle
   *
   * @example
   * DOM.toggleClass('.dropdown', 'show');
   */
  toggleClass: (element, className) => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (element) {
      element.classList.toggle(className);
    }
  },
  /**
   * Check if an element has a class
   * Replaces jQuery's $.hasClass()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} className - Class name to check
   * @returns {boolean} True if element has the class
   *
   * @example
   * if (DOM.hasClass('.menu', 'open')) {
   *   closeMenu();
   * }
   */
  hasClass: (element, className) => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    return element ? element.classList.contains(className) : false;
  },
  /**
   * Get or set an attribute on an element
   * Replaces jQuery's $.attr()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} name - Attribute name
   * @param {string} [value] - Value to set (omit to get)
   * @returns {string|Element|null} Attribute value when getting, element when setting
   *
   * @example
   * // Get attribute
   * const href = DOM.attr(link, 'href');
   *
   * // Set attribute
   * DOM.attr(link, 'href', '/new-page');
   */
  attr: (element, name, value) => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (!element) return null;
    if (value === undefined) {
      return element.getAttribute(name);
    } else {
      element.setAttribute(name, value);
      return element;
    }
  },
  /**
   * Get or set a data attribute on an element
   * Replaces jQuery's $.data()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} name - Data attribute name (without 'data-' prefix)
   * @param {string} [value] - Value to set (omit to get)
   * @returns {string|Element|null} Data value when getting, element when setting
   *
   * @example
   * // Get data attribute
   * const id = DOM.data(row, 'id'); // Gets data-id
   *
   * // Set data attribute
   * DOM.data(row, 'id', '123');
   */
  data: (element, name, value) => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (!element) return null;
    const dataName = `data-${name}`;
    if (value === undefined) {
      return element.getAttribute(dataName);
    } else {
      element.setAttribute(dataName, value);
      return element;
    }
  },
  /**
   * Get or set text content of an element
   * Replaces jQuery's $.text()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} [content] - Text to set (omit to get)
   * @returns {string|Element|null} Text content when getting, element when setting
   *
   * @example
   * const text = DOM.text('.title');
   * DOM.text('.title', 'New Title');
   */
  text: (element, content) => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (!element) return null;
    if (content === undefined) {
      return element.textContent;
    } else {
      element.textContent = content;
      return element;
    }
  },
  /**
   * Get or set HTML content of an element
   * Replaces jQuery's $.html()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} [content] - HTML to set (omit to get)
   * @returns {string|Element|null} HTML content when getting, element when setting
   *
   * @example
   * const html = DOM.html('.container');
   * DOM.html('.container', '<p>New content</p>');
   */
  html: (element, content) => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (!element) return null;
    if (content === undefined) {
      return element.innerHTML;
    } else {
      element.innerHTML = content;
      return element;
    }
  },
  /**
   * Hide an element
   * Replaces jQuery's $.hide()
   *
   * @param {Element|string} element - Element or selector
   *
   * @example
   * DOM.hide('.modal');
   */
  hide: element => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (element) {
      element.style.display = 'none';
    }
  },
  /**
   * Show an element
   * Replaces jQuery's $.show()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} [display='block'] - Display value to use
   *
   * @example
   * DOM.show('.modal');
   * DOM.show('.flex-item', 'flex');
   */
  show: function (element) {
    let display = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'block';
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (element) {
      element.style.display = display;
    }
  },
  /**
   * Toggle element visibility
   * Replaces jQuery's $.toggle()
   *
   * @param {Element|string} element - Element or selector
   * @param {string} [display='block'] - Display value when showing
   *
   * @example
   * DOM.toggle('.menu');
   */
  toggle: function (element) {
    let display = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'block';
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (element) {
      if (element.style.display === 'none') {
        element.style.display = display;
      } else {
        element.style.display = 'none';
      }
    }
  },
  /**
   * Animate element sliding up (collapsing)
   * Replaces jQuery's $.slideUp()
   *
   * @param {Element|string} element - Element or selector
   * @param {number} [duration=300] - Animation duration in ms
   * @returns {Promise<void>} Resolves when animation completes
   *
   * @example
   * await DOM.slideUp('.panel');
   */
  slideUp: function (element) {
    let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 300;
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (!element) return Promise.resolve();
    return new Promise(resolve => {
      const height = element.scrollHeight;
      element.style.height = `${height}px`;
      element.style.overflow = 'hidden';
      element.animate([{
        height: `${height}px`
      }, {
        height: '0px'
      }], {
        duration,
        easing: 'ease-in-out'
      }).onfinish = () => {
        element.style.display = 'none';
        element.style.height = '';
        element.style.overflow = '';
        resolve();
      };
    });
  },
  /**
   * Animate element sliding down (expanding)
   * Replaces jQuery's $.slideDown()
   *
   * @param {Element|string} element - Element or selector
   * @param {number} [duration=300] - Animation duration in ms
   * @returns {Promise<void>} Resolves when animation completes
   *
   * @example
   * await DOM.slideDown('.panel');
   */
  slideDown: function (element) {
    let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 300;
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (!element) return Promise.resolve();
    return new Promise(resolve => {
      element.style.display = 'block';
      element.style.height = '0px';
      element.style.overflow = 'hidden';
      const height = element.scrollHeight;
      element.animate([{
        height: '0px'
      }, {
        height: `${height}px`
      }], {
        duration,
        easing: 'ease-in-out'
      }).onfinish = () => {
        element.style.height = 'auto';
        element.style.overflow = 'visible';
        resolve();
      };
    });
  },
  /**
   * Animate element fading in
   * Replaces jQuery's $.fadeIn()
   *
   * @param {Element|string} element - Element or selector
   * @param {number} [duration=300] - Animation duration in ms
   * @returns {Promise<void>} Resolves when animation completes
   *
   * @example
   * await DOM.fadeIn('.modal');
   */
  fadeIn: function (element) {
    let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 300;
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (!element) return Promise.resolve();
    return new Promise(resolve => {
      element.style.opacity = '0';
      element.style.display = 'block';
      element.animate([{
        opacity: 0
      }, {
        opacity: 1
      }], {
        duration,
        easing: 'ease-in-out'
      }).onfinish = () => {
        element.style.opacity = '';
        resolve();
      };
    });
  },
  /**
   * Animate element fading out
   * Replaces jQuery's $.fadeOut()
   *
   * @param {Element|string} element - Element or selector
   * @param {number} [duration=300] - Animation duration in ms
   * @returns {Promise<void>} Resolves when animation completes
   *
   * @example
   * await DOM.fadeOut('.modal');
   */
  fadeOut: function (element) {
    let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 300;
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (!element) return Promise.resolve();
    return new Promise(resolve => {
      element.animate([{
        opacity: 1
      }, {
        opacity: 0
      }], {
        duration,
        easing: 'ease-in-out'
      }).onfinish = () => {
        element.style.display = 'none';
        element.style.opacity = '';
        resolve();
      };
    });
  },
  /**
   * Get element dimensions and position relative to viewport
   *
   * @param {Element|string} element - Element or selector
   * @returns {Object|null} Dimensions object or null
   * @property {number} width - Element width
   * @property {number} height - Element height
   * @property {number} top - Distance from viewport top
   * @property {number} left - Distance from viewport left
   * @property {number} bottom - Distance from viewport bottom
   * @property {number} right - Distance from viewport right
   *
   * @example
   * const { width, height, top, left } = DOM.dimensions('.card');
   */
  dimensions: element => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    if (!element) return null;
    const rect = element.getBoundingClientRect();
    return {
      width: rect.width,
      height: rect.height,
      top: rect.top,
      left: rect.left,
      bottom: rect.bottom,
      right: rect.right
    };
  },
  /**
   * Execute callback when DOM is ready
   * Replaces jQuery's $(document).ready()
   *
   * @param {Function} callback - Function to execute when DOM is ready
   *
   * @example
   * DOM.ready(() => {
   *   initApp();
   * });
   */
  ready: callback => {
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', callback);
    } else {
      callback();
    }
  },
  /**
   * Create an element with optional attributes and children
   *
   * @param {string} tag - HTML tag name
   * @param {Object} [attrs={}] - Attributes to set
   * @param {Array<Element|string>} [children=[]] - Child elements or text
   * @returns {Element} The created element
   *
   * @example
   * const button = DOM.create('button', { class: 'btn', type: 'submit' }, ['Submit']);
   */
  create: function (tag) {
    let attrs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    let children = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
    const el = document.createElement(tag);
    Object.entries(attrs).forEach(_ref => {
      let [key, value] = _ref;
      if (key === 'class') {
        el.className = value;
      } else if (key.startsWith('data-')) {
        el.setAttribute(key, value);
      } else {
        el[key] = value;
      }
    });
    children.forEach(child => {
      if (typeof child === 'string') {
        el.appendChild(document.createTextNode(child));
      } else if (child instanceof Element) {
        el.appendChild(child);
      }
    });
    return el;
  },
  /**
   * Find the closest ancestor matching a selector
   *
   * @param {Element|string} element - Element or selector
   * @param {string} selector - Selector to match
   * @returns {Element|null} Closest matching ancestor or null
   *
   * @example
   * const form = DOM.closest(input, 'form');
   */
  closest: (element, selector) => {
    if (typeof element === 'string') {
      element = document.querySelector(element);
    }
    return element ? element.closest(selector) : null;
  }
};
/* harmony default export */ const dom = ((/* unused pure expression or super */ null && (DOM)));
// EXTERNAL MODULE: ../../node_modules/dayjs/dayjs.min.js
var dayjs_min = __webpack_require__(464);
var dayjs_min_default = /*#__PURE__*/__webpack_require__.n(dayjs_min);
// EXTERNAL MODULE: ../../node_modules/dayjs/plugin/utc.js
var utc = __webpack_require__(657);
var utc_default = /*#__PURE__*/__webpack_require__.n(utc);
// EXTERNAL MODULE: ../../node_modules/dayjs/plugin/timezone.js
var timezone = __webpack_require__(168);
var timezone_default = /*#__PURE__*/__webpack_require__.n(timezone);
// EXTERNAL MODULE: ../../node_modules/dayjs/plugin/relativeTime.js
var relativeTime = __webpack_require__(562);
var relativeTime_default = /*#__PURE__*/__webpack_require__.n(relativeTime);
// EXTERNAL MODULE: ../../node_modules/dayjs/plugin/customParseFormat.js
var customParseFormat = __webpack_require__(630);
var customParseFormat_default = /*#__PURE__*/__webpack_require__.n(customParseFormat);
// EXTERNAL MODULE: ../../node_modules/dayjs/plugin/advancedFormat.js
var advancedFormat = __webpack_require__(258);
var advancedFormat_default = /*#__PURE__*/__webpack_require__.n(advancedFormat);
;// ../assets/scripts/utils/date.js
/**
 * Modern Date Utilities
 * Using Day.js (2KB) instead of Moment.js (67KB) - 97% size reduction
 * Provides consistent date formatting and manipulation across the application
 */








// Enable Day.js plugins
dayjs_min_default().extend((utc_default()));
dayjs_min_default().extend((timezone_default()));
dayjs_min_default().extend((relativeTime_default()));
dayjs_min_default().extend((customParseFormat_default()));
dayjs_min_default().extend((advancedFormat_default()));
const DateUtils = {
  /**
   * Get current date/time
   */
  now: () => dayjs_min_default()(),
  /**
   * Parse date from string or Date object
   */
  parse: function (input) {
    let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
    return format ? dayjs_min_default()(input, format) : dayjs_min_default()(input);
  },
  /**
   * Format date for display
   */
  format: function (date) {
    let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'YYYY-MM-DD';
    return dayjs_min_default()(date).format(format);
  },
  /**
   * Common date formatting presets
   */
  formatters: {
    // Dashboard display formats
    shortDate: date => dayjs_min_default()(date).format('MMM DD, YYYY'),
    longDate: date => dayjs_min_default()(date).format('MMMM DD, YYYY'),
    dateTime: date => dayjs_min_default()(date).format('MMM DD, YYYY h:mm A'),
    // Calendar formats
    calendarDate: date => dayjs_min_default()(date).format('YYYY-MM-DD'),
    calendarDateTime: date => dayjs_min_default()(date).format('YYYY-MM-DD HH:mm:ss'),
    // Form input formats
    inputDate: date => dayjs_min_default()(date).format('YYYY-MM-DD'),
    inputDateTime: date => dayjs_min_default()(date).format('YYYY-MM-DDTHH:mm'),
    // Display formats
    timeOnly: date => dayjs_min_default()(date).format('h:mm A'),
    monthYear: date => dayjs_min_default()(date).format('MMMM YYYY'),
    dayMonth: date => dayjs_min_default()(date).format('DD MMM'),
    // Relative time
    relative: date => dayjs_min_default()(date).fromNow(),
    relativeCalendar: date => {
      const now = dayjs_min_default()();
      const target = dayjs_min_default()(date);
      const diffDays = now.diff(target, 'day');
      if (diffDays === 0) return 'Today';
      if (diffDays === 1) return 'Yesterday';
      if (diffDays === -1) return 'Tomorrow';
      if (diffDays > 1 && diffDays < 7) return `${diffDays} days ago`;
      if (diffDays < -1 && diffDays > -7) return `In ${Math.abs(diffDays)} days`;
      return target.format('MMM DD, YYYY');
    }
  },
  /**
   * Date manipulation
   */
  add: (date, amount, unit) => dayjs_min_default()(date).add(amount, unit),
  subtract: (date, amount, unit) => dayjs_min_default()(date).subtract(amount, unit),
  startOf: (date, unit) => dayjs_min_default()(date).startOf(unit),
  endOf: (date, unit) => dayjs_min_default()(date).endOf(unit),
  /**
   * Date comparison
   */
  isBefore: (date1, date2) => dayjs_min_default()(date1).isBefore(dayjs_min_default()(date2)),
  isAfter: (date1, date2) => dayjs_min_default()(date1).isAfter(dayjs_min_default()(date2)),
  isSame: function (date1, date2) {
    let unit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'day';
    return dayjs_min_default()(date1).isSame(dayjs_min_default()(date2), unit);
  },
  isBetween: (date, start, end) => dayjs_min_default()(date).isBetween(dayjs_min_default()(start), dayjs_min_default()(end)),
  /**
   * Date validation
   */
  isValid: date => dayjs_min_default()(date).isValid(),
  /**
   * Timezone utilities
   */
  timezone: {
    convert: (date, tz) => dayjs_min_default()(date).tz(tz),
    utc: date => dayjs_min_default()(date).utc(),
    local: date => dayjs_min_default()(date).local(),
    guess: () => dayjs_min_default().tz.guess()
  },
  /**
   * Calendar utilities
   */
  calendar: {
    // Get calendar month data for building calendar views
    getMonthData: function () {
      let date = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
      const target = date ? dayjs_min_default()(date) : dayjs_min_default()();
      const startOfMonth = target.startOf('month');
      const endOfMonth = target.endOf('month');
      const startOfCalendar = startOfMonth.startOf('week');
      const endOfCalendar = endOfMonth.endOf('week');
      const days = [];
      let current = startOfCalendar;
      while (current.isBefore(endOfCalendar) || current.isSame(endOfCalendar, 'day')) {
        days.push({
          date: current.format('YYYY-MM-DD'),
          day: current.date(),
          isCurrentMonth: current.isSame(target, 'month'),
          isToday: current.isSame(dayjs_min_default()(), 'day'),
          dayjs: current.clone()
        });
        current = current.add(1, 'day');
      }
      return {
        month: target.format('MMMM YYYY'),
        year: target.year(),
        monthIndex: target.month(),
        days
      };
    },
    // Get week data
    getWeekData: function () {
      let date = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
      const target = date ? dayjs_min_default()(date) : dayjs_min_default()();
      const startOfWeek = target.startOf('week');
      const endOfWeek = target.endOf('week');
      const days = [];
      let current = startOfWeek;
      while (current.isBefore(endOfWeek) || current.isSame(endOfWeek, 'day')) {
        days.push({
          date: current.format('YYYY-MM-DD'),
          day: current.date(),
          dayName: current.format('dddd'),
          shortDayName: current.format('ddd'),
          isToday: current.isSame(dayjs_min_default()(), 'day'),
          dayjs: current.clone()
        });
        current = current.add(1, 'day');
      }
      return {
        weekStart: startOfWeek.format('MMM DD'),
        weekEnd: endOfWeek.format('MMM DD, YYYY'),
        days
      };
    }
  },
  /**
   * Form utilities
   */
  form: {
    // Convert date to HTML5 input format
    toInputValue: date => dayjs_min_default()(date).format('YYYY-MM-DD'),
    toDateTimeInputValue: date => dayjs_min_default()(date).format('YYYY-MM-DDTHH:mm'),
    // Parse from HTML5 input
    fromInputValue: value => dayjs_min_default()(value),
    // Validate date input
    validateDateInput: value => {
      const parsed = dayjs_min_default()(value);
      return parsed.isValid() && value.length >= 8; // Basic validation
    }
  },
  /**
   * Chart/Data utilities
   */
  charts: {
    // Generate date ranges for charts
    generateDateRange: function (start, end) {
      let interval = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'day';
      const dates = [];
      let current = dayjs_min_default()(start);
      const endDate = dayjs_min_default()(end);
      while (current.isBefore(endDate) || current.isSame(endDate, interval)) {
        dates.push({
          date: current.format('YYYY-MM-DD'),
          label: current.format('MMM DD'),
          value: current.toISOString(),
          dayjs: current.clone()
        });
        current = current.add(1, interval);
      }
      return dates;
    },
    // Get common chart date labels
    getChartLabels: function () {
      let period = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'week';
      const now = dayjs_min_default()();
      switch (period) {
        case 'week':
          return Array.from({
            length: 7
          }, (_, i) => now.subtract(6 - i, 'day').format('ddd'));
        case 'month':
          return Array.from({
            length: 30
          }, (_, i) => now.subtract(29 - i, 'day').format('DD'));
        case 'year':
          return Array.from({
            length: 12
          }, (_, i) => now.subtract(11 - i, 'month').format('MMM'));
        default:
          return [];
      }
    }
  }
};

// Export dayjs instance for direct use when needed


// Default export
/* harmony default export */ const date = (DateUtils);
;// ../assets/scripts/utils/theme.js
/**
 * Adminator Theme Manager
 * Handles light/dark mode switching with localStorage persistence
 *
 * @module utils/theme
 * @example
 * // Get current theme
 * const current = Theme.current(); // 'light' or 'dark'
 *
 * // Toggle theme
 * Theme.toggle();
 *
 * // Apply specific theme
 * Theme.apply('dark');
 *
 * // Listen for theme changes
 * window.addEventListener('adminator:themeChanged', (e) => {
 *   console.log('New theme:', e.detail.theme);
 * });
 */

/* global Chart */

/** @constant {string} Storage key for theme preference */
const THEME_KEY = 'adminator-theme';

/** @constant {string[]} Valid theme values */
const VALID_THEMES = ['light', 'dark'];

/**
 * Safe localStorage wrapper
 * Handles cases where localStorage is unavailable (private browsing, etc.)
 * @private
 */
const Storage = {
  /**
   * Get item from localStorage
   * @param {string} key - Storage key
   * @returns {string|null} Stored value or null
   */
  get(key) {
    try {
      return localStorage.getItem(key);
    } catch {
      return null;
    }
  },
  /**
   * Set item in localStorage
   * @param {string} key - Storage key
   * @param {string} value - Value to store
   * @returns {boolean} Success status
   */
  set(key, value) {
    try {
      localStorage.setItem(key, value);
      return true;
    } catch {
      return false;
    }
  }
};

/**
 * Theme Manager
 * @namespace
 */
const Theme = {
  /**
   * Apply a theme to the document
   * Updates Chart.js defaults if available
   *
   * @param {('light'|'dark')} theme - Theme to apply
   * @fires adminator:themeChanged
   * @returns {boolean} Success status
   *
   * @example
   * Theme.apply('dark');
   */
  apply(theme) {
    // Validate theme
    if (!VALID_THEMES.includes(theme)) {
      console.warn(`[Adminator] Invalid theme "${theme}". Using "light".`);
      theme = 'light';
    }

    // Apply to document
    document.documentElement.setAttribute('data-theme', theme);

    // Update Chart.js defaults if available
    if (window.Chart && Chart.defaults) {
      const isDark = theme === 'dark';
      const textColor = isDark ? '#FFFFFF' : '#212529';
      const mutedColor = isDark ? '#D1D5DB' : '#6C757D';
      const borderColor = isDark ? '#374151' : '#E2E5E8';
      const gridColor = isDark ? 'rgba(209, 213, 219, 0.15)' : 'rgba(0, 0, 0, 0.05)';
      const tooltipBg = isDark ? '#1F2937' : 'rgba(255, 255, 255, 0.95)';

      // Set global defaults
      Chart.defaults.color = textColor;
      Chart.defaults.borderColor = borderColor;
      Chart.defaults.backgroundColor = tooltipBg;

      // Set plugin defaults
      Chart.defaults.plugins.legend.labels.color = textColor;
      Chart.defaults.plugins.tooltip.backgroundColor = tooltipBg;
      Chart.defaults.plugins.tooltip.titleColor = textColor;
      Chart.defaults.plugins.tooltip.bodyColor = textColor;
      Chart.defaults.plugins.tooltip.borderColor = borderColor;

      // Set scale defaults
      const scales = ['category', 'linear', 'logarithmic', 'time', 'radialLinear'];
      scales.forEach(scale => {
        if (Chart.defaults.scales[scale]) {
          Chart.defaults.scales[scale].ticks.color = mutedColor;
          Chart.defaults.scales[scale].grid.color = gridColor;
        }
      });

      // RadialLinear specific
      if (Chart.defaults.scales.radialLinear) {
        Chart.defaults.scales.radialLinear.pointLabels.color = mutedColor;
        Chart.defaults.scales.radialLinear.angleLines.color = gridColor;
      }
    }

    // Persist to storage
    Storage.set(THEME_KEY, theme);

    // Update toggle accessibility state if exists
    const toggle = document.getElementById('theme-toggle');
    if (toggle) {
      toggle.setAttribute('aria-checked', theme === 'dark' ? 'true' : 'false');
    }

    // Dispatch event for other components
    window.dispatchEvent(new CustomEvent('adminator:themeChanged', {
      detail: {
        theme
      }
    }));
    return true;
  },
  /**
   * Toggle between light and dark themes
   *
   * @returns {('light'|'dark')} The new theme
   *
   * @example
   * const newTheme = Theme.toggle();
   * console.log('Switched to:', newTheme);
   */
  toggle() {
    const next = this.current() === 'dark' ? 'light' : 'dark';
    this.apply(next);
    return next;
  },
  /**
   * Get the current theme
   *
   * @returns {('light'|'dark')} Current theme
   *
   * @example
   * if (Theme.current() === 'dark') {
   *   // Dark mode specific logic
   * }
   */
  current() {
    const stored = Storage.get(THEME_KEY);
    return VALID_THEMES.includes(stored) ? stored : 'light';
  },
  /**
   * Initialize the theme system
   * Detects OS preference on first visit, otherwise uses stored preference
   *
   * @returns {('light'|'dark')} The applied theme
   *
   * @example
   * // Call once on app initialization
   * Theme.init();
   */
  init() {
    const stored = Storage.get(THEME_KEY);
    if (!stored) {
      // First visit - detect OS preference
      const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
      const theme = prefersDark ? 'dark' : 'light';
      this.apply(theme);
      return theme;
    }

    // Use stored preference
    this.apply(this.current());
    return this.current();
  },
  /**
   * Get a CSS variable value from the document
   *
   * @param {string} varName - CSS variable name (with or without --)
   * @returns {string} The CSS variable value
   *
   * @example
   * const bgColor = Theme.getCSSVar('--c-bkg-body');
   */
  getCSSVar(varName) {
    const name = varName.startsWith('--') ? varName : `--${varName}`;
    return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
  },
  /**
   * Get theme-aware colors for vector maps
   *
   * @returns {Object} Vector map color configuration
   * @property {string} backgroundColor - Map background color
   * @property {string} borderColor - Border color
   * @property {string} regionColor - Default region fill color
   * @property {string} markerFill - Marker fill color
   * @property {string} markerStroke - Marker stroke color
   * @property {string} hoverColor - Region hover color
   * @property {string} selectedColor - Selected region color
   * @property {string} scaleStart - Scale gradient start
   * @property {string} scaleEnd - Scale gradient end
   */
  getVectorMapColors() {
    return {
      backgroundColor: this.getCSSVar('--vmap-bg-color'),
      borderColor: this.getCSSVar('--vmap-border-color'),
      regionColor: this.getCSSVar('--vmap-region-color'),
      markerFill: this.getCSSVar('--vmap-marker-fill'),
      markerStroke: this.getCSSVar('--vmap-marker-stroke'),
      hoverColor: this.getCSSVar('--vmap-hover-color'),
      selectedColor: this.getCSSVar('--vmap-selected-color'),
      scaleStart: this.getCSSVar('--vmap-scale-start'),
      scaleEnd: this.getCSSVar('--vmap-scale-end'),
      scaleLight: this.getCSSVar('--vmap-scale-light'),
      scaleDark: this.getCSSVar('--vmap-scale-dark')
    };
  },
  /**
   * Get theme-aware colors for sparkline charts
   *
   * @returns {Object} Sparkline color configuration
   */
  getSparklineColors() {
    return {
      success: this.getCSSVar('--sparkline-success'),
      purple: this.getCSSVar('--sparkline-purple'),
      info: this.getCSSVar('--sparkline-info'),
      danger: this.getCSSVar('--sparkline-danger'),
      light: this.getCSSVar('--sparkline-light')
    };
  },
  /**
   * Get theme-aware colors for Chart.js charts
   *
   * @returns {Object} Chart color configuration
   * @property {string} textColor - Main text color
   * @property {string} mutedColor - Muted/secondary text color
   * @property {string} borderColor - Border color
   * @property {string} gridColor - Grid line color
   * @property {string} tooltipBg - Tooltip background color
   */
  getChartColors() {
    const isDark = this.current() === 'dark';
    return {
      textColor: isDark ? '#FFFFFF' : '#212529',
      mutedColor: isDark ? '#D1D5DB' : '#6C757D',
      borderColor: isDark ? '#374151' : '#E2E5E8',
      gridColor: isDark ? 'rgba(209, 213, 219, 0.15)' : 'rgba(0, 0, 0, 0.05)',
      tooltipBg: isDark ? '#1F2937' : 'rgba(255, 255, 255, 0.95)'
    };
  },
  /**
   * Check if dark mode is currently active
   *
   * @returns {boolean} True if dark mode is active
   *
   * @example
   * if (Theme.isDark()) {
   *   // Apply dark-specific styles
   * }
   */
  isDark() {
    return this.current() === 'dark';
  },
  /**
   * Check if light mode is currently active
   *
   * @returns {boolean} True if light mode is active
   */
  isLight() {
    return this.current() === 'light';
  }
};
/* harmony default export */ const theme = (Theme);
;// ../assets/scripts/utils/events.js
/**
 * Adminator Event Utilities
 * Provides efficient event handling with delegation and cleanup
 *
 * @module utils/events
 */

/**
 * Store for event handlers to enable proper cleanup
 * @type {WeakMap<Element, Map<string, Set<Function>>>}
 */
const handlerRegistry = new WeakMap();

/**
 * Store for AbortControllers to enable easy cleanup
 * @type {WeakMap<Element, AbortController>}
 */
const controllerRegistry = new WeakMap();

/**
 * Event utilities namespace
 * @namespace
 */
const Events = {
  /**
   * Add an event listener with automatic cleanup support
   * Uses AbortController for efficient removal
   *
   * @param {Element} element - Target element
   * @param {string} event - Event type
   * @param {Function} handler - Event handler
   * @param {Object} [options={}] - Event listener options
   * @returns {Function} Cleanup function to remove the listener
   *
   * @example
   * const cleanup = Events.on(button, 'click', handleClick);
   * // Later: cleanup() to remove
   */
  on(element, event, handler) {
    let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
    if (!element) return () => {};

    // Get or create AbortController for this element
    let controller = controllerRegistry.get(element);
    if (!controller) {
      controller = new AbortController();
      controllerRegistry.set(element, controller);
    }

    // Register handler
    if (!handlerRegistry.has(element)) {
      handlerRegistry.set(element, new Map());
    }
    const elementHandlers = handlerRegistry.get(element);
    if (!elementHandlers.has(event)) {
      elementHandlers.set(event, new Set());
    }
    elementHandlers.get(event).add(handler);

    // Add listener with abort signal
    element.addEventListener(event, handler, {
      ...options,
      signal: controller.signal
    });

    // Return cleanup function
    return () => {
      var _handlerRegistry$get;
      element.removeEventListener(event, handler, options);
      const handlers = (_handlerRegistry$get = handlerRegistry.get(element)) === null || _handlerRegistry$get === void 0 ? void 0 : _handlerRegistry$get.get(event);
      if (handlers) {
        handlers.delete(handler);
      }
    };
  },
  /**
   * Remove all event listeners from an element
   *
   * @param {Element} element - Target element
   *
   * @example
   * Events.off(element); // Removes all listeners
   */
  off(element) {
    if (!element) return;
    const controller = controllerRegistry.get(element);
    if (controller) {
      controller.abort();
      controllerRegistry.delete(element);
    }
    handlerRegistry.delete(element);
  },
  /**
   * Add event delegation - listen on parent for events from children
   * More efficient than adding listeners to many elements
   *
   * @param {Element} parent - Parent element to listen on
   * @param {string} event - Event type
   * @param {string} selector - CSS selector for target elements
   * @param {Function} handler - Event handler (receives event and matched element)
   * @param {Object} [options={}] - Event listener options
   * @returns {Function} Cleanup function
   *
   * @example
   * // Instead of adding click to every .btn
   * Events.delegate(container, 'click', '.btn', (e, btn) => {
   *   console.log('Button clicked:', btn);
   * });
   */
  delegate(parent, event, selector, handler) {
    let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
    if (!parent) return () => {};
    const delegatedHandler = e => {
      const target = e.target.closest(selector);
      if (target && parent.contains(target)) {
        handler.call(target, e, target);
      }
    };
    return this.on(parent, event, delegatedHandler, options);
  },
  /**
   * Add a one-time event listener
   *
   * @param {Element} element - Target element
   * @param {string} event - Event type
   * @param {Function} handler - Event handler
   * @returns {Function} Cleanup function
   *
   * @example
   * Events.once(button, 'click', handleFirstClick);
   */
  once(element, event, handler) {
    return this.on(element, event, handler, {
      once: true
    });
  },
  /**
   * Create a debounced event handler
   *
   * @param {Function} handler - Original handler
   * @param {number} [delay=250] - Debounce delay in ms
   * @returns {Function} Debounced handler
   *
   * @example
   * const debouncedResize = Events.debounce(handleResize, 200);
   * window.addEventListener('resize', debouncedResize);
   */
  debounce(handler) {
    let delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 250;
    let timeoutId;
    return function debounced() {
      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => handler.apply(this, args), delay);
    };
  },
  /**
   * Create a throttled event handler
   *
   * @param {Function} handler - Original handler
   * @param {number} [limit=250] - Throttle limit in ms
   * @returns {Function} Throttled handler
   *
   * @example
   * const throttledScroll = Events.throttle(handleScroll, 100);
   * window.addEventListener('scroll', throttledScroll);
   */
  throttle(handler) {
    let limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 250;
    let inThrottle;
    return function throttled() {
      if (!inThrottle) {
        for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
          args[_key2] = arguments[_key2];
        }
        handler.apply(this, args);
        inThrottle = true;
        setTimeout(() => inThrottle = false, limit);
      }
    };
  },
  /**
   * Dispatch a custom event
   *
   * @param {Element|Window} target - Target to dispatch on
   * @param {string} eventName - Event name
   * @param {Object} [detail={}] - Event detail data
   * @param {Object} [options={}] - Event options (bubbles, cancelable)
   * @returns {boolean} Whether the event was not cancelled
   *
   * @example
   * Events.emit(element, 'custom:event', { data: 'value' });
   */
  emit(target, eventName) {
    let detail = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
    let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
    const event = new CustomEvent(eventName, {
      detail,
      bubbles: options.bubbles ?? true,
      cancelable: options.cancelable ?? true
    });
    return target.dispatchEvent(event);
  }
};
/* harmony default export */ const events = (Events);
;// ../assets/scripts/utils/performance.js
/**
 * Adminator Performance Utilities
 * Provides ResizeObserver, IntersectionObserver, and lazy loading utilities
 *
 * @module utils/performance
 */

/**
 * Store for ResizeObserver instances
 * @type {WeakMap<Element, Function>}
 */
const resizeCallbacks = new WeakMap();

/**
 * Shared ResizeObserver instance for efficiency
 * @type {ResizeObserver|null}
 */
let sharedResizeObserver = null;

/**
 * Store for IntersectionObserver callbacks
 * @type {WeakMap<Element, Function>}
 */
const intersectionCallbacks = new WeakMap();

/**
 * Map of IntersectionObservers by threshold
 * @type {Map<string, IntersectionObserver>}
 */
const intersectionObservers = new Map();

/**
 * Performance utilities namespace
 * @namespace
 */
const Performance = {
  /**
   * Observe element resize events efficiently
   * Uses shared ResizeObserver for better performance
   *
   * @param {Element} element - Element to observe
   * @param {Function} callback - Callback receiving { width, height, entry }
   * @returns {Function} Cleanup function to stop observing
   *
   * @example
   * const unobserve = Performance.onResize(chart, ({ width, height }) => {
   *   chart.resize(width, height);
   * });
   */
  onResize(element, callback) {
    if (!element || typeof callback !== 'function') {
      return () => {};
    }

    // Create shared observer if needed
    if (!sharedResizeObserver) {
      sharedResizeObserver = new ResizeObserver(entries => {
        for (const entry of entries) {
          const cb = resizeCallbacks.get(entry.target);
          if (cb) {
            const {
              width,
              height
            } = entry.contentRect;
            cb({
              width,
              height,
              entry
            });
          }
        }
      });
    }

    // Store callback and observe
    resizeCallbacks.set(element, callback);
    sharedResizeObserver.observe(element);

    // Return cleanup function
    return () => {
      var _sharedResizeObserver;
      resizeCallbacks.delete(element);
      (_sharedResizeObserver = sharedResizeObserver) === null || _sharedResizeObserver === void 0 || _sharedResizeObserver.unobserve(element);
    };
  },
  /**
   * Observe when element enters/exits viewport
   * Useful for lazy loading and animations
   *
   * @param {Element} element - Element to observe
   * @param {Function} callback - Callback receiving { isIntersecting, entry }
   * @param {Object} [options={}] - IntersectionObserver options
   * @param {number} [options.threshold=0] - Visibility threshold (0-1)
   * @param {string} [options.rootMargin='0px'] - Root margin
   * @returns {Function} Cleanup function to stop observing
   *
   * @example
   * const unobserve = Performance.onVisible(element, ({ isIntersecting }) => {
   *   if (isIntersecting) {
   *     loadContent();
   *     unobserve(); // Stop after first trigger
   *   }
   * });
   */
  onVisible(element, callback) {
    let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
    if (!element || typeof callback !== 'function') {
      return () => {};
    }
    const {
      threshold = 0,
      rootMargin = '0px'
    } = options;
    const key = `${threshold}-${rootMargin}`;

    // Get or create observer for this threshold
    if (!intersectionObservers.has(key)) {
      const observer = new IntersectionObserver(entries => {
        for (const entry of entries) {
          const cb = intersectionCallbacks.get(entry.target);
          if (cb) {
            cb({
              isIntersecting: entry.isIntersecting,
              ratio: entry.intersectionRatio,
              entry
            });
          }
        }
      }, {
        threshold,
        rootMargin
      });
      intersectionObservers.set(key, observer);
    }
    const observer = intersectionObservers.get(key);

    // Store callback and observe
    intersectionCallbacks.set(element, callback);
    observer.observe(element);

    // Return cleanup function
    return () => {
      intersectionCallbacks.delete(element);
      observer.unobserve(element);
    };
  },
  /**
   * Lazy load an element when it becomes visible
   * Automatically handles cleanup after loading
   *
   * @param {Element} element - Element to lazy load
   * @param {Function} loadFn - Function to call when visible
   * @param {Object} [options={}] - Options
   * @param {string} [options.rootMargin='100px'] - Preload margin
   * @returns {Function} Cleanup function
   *
   * @example
   * Performance.lazyLoad(chartContainer, () => {
   *   initializeChart(chartContainer);
   * });
   */
  lazyLoad(element, loadFn) {
    let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
    const {
      rootMargin = '100px'
    } = options;
    let loaded = false;
    const unobserve = this.onVisible(element, _ref => {
      let {
        isIntersecting
      } = _ref;
      if (isIntersecting && !loaded) {
        loaded = true;
        loadFn();
        unobserve();
      }
    }, {
      rootMargin
    });
    return unobserve;
  },
  /**
   * Batch DOM reads and writes to prevent layout thrashing
   *
   * @param {Function} readFn - Function that reads from DOM
   * @param {Function} writeFn - Function that writes to DOM
   *
   * @example
   * Performance.batch(
   *   () => element.offsetHeight, // Read
   *   (height) => element.style.minHeight = height + 'px' // Write
   * );
   */
  batch(readFn, writeFn) {
    // Use requestAnimationFrame for batching
    requestAnimationFrame(() => {
      const value = readFn();
      requestAnimationFrame(() => {
        writeFn(value);
      });
    });
  },
  /**
   * Execute callback on next animation frame
   *
   * @param {Function} callback - Function to execute
   * @returns {number} Request ID for cancellation
   *
   * @example
   * const id = Performance.nextFrame(() => updateUI());
   * // Cancel: cancelAnimationFrame(id);
   */
  nextFrame(callback) {
    return requestAnimationFrame(callback);
  },
  /**
   * Execute callback when browser is idle
   * Falls back to setTimeout if requestIdleCallback not available
   *
   * @param {Function} callback - Function to execute
   * @param {Object} [options={}] - Options
   * @param {number} [options.timeout=1000] - Maximum wait time
   * @returns {number} Request ID for cancellation
   *
   * @example
   * Performance.whenIdle(() => {
   *   // Non-critical work
   *   preloadNextPage();
   * });
   */
  whenIdle(callback) {
    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    const {
      timeout = 1000
    } = options;
    if ('requestIdleCallback' in window) {
      return requestIdleCallback(callback, {
        timeout
      });
    }

    // Fallback for Safari
    return setTimeout(callback, 1);
  },
  /**
   * Cancel an idle callback
   *
   * @param {number} id - Request ID from whenIdle
   */
  cancelIdle(id) {
    if ('cancelIdleCallback' in window) {
      cancelIdleCallback(id);
    } else {
      clearTimeout(id);
    }
  },
  /**
   * Preload a resource (image, script, etc.)
   *
   * @param {string} url - URL to preload
   * @param {string} [as='image'] - Resource type (image, script, style, font)
   * @returns {Promise<void>} Resolves when loaded
   *
   * @example
   * await Performance.preload('/images/hero.jpg', 'image');
   */
  preload(url) {
    let as = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'image';
    return new Promise((resolve, reject) => {
      const link = document.createElement('link');
      link.rel = 'preload';
      link.as = as;
      link.href = url;
      link.onload = resolve;
      link.onerror = reject;
      document.head.appendChild(link);
    });
  },
  /**
   * Measure execution time of a function
   *
   * @param {string} label - Label for the measurement
   * @param {Function} fn - Function to measure
   * @returns {*} Return value of the function
   *
   * @example
   * const result = Performance.measure('render', () => renderChart());
   */
  measure(label, fn) {
    const start = performance.now();
    const result = fn();
    const end = performance.now();
    if (false) // removed by dead control flow
{}
    return result;
  },
  /**
   * Cleanup all observers
   * Call this when destroying the app
   */
  cleanup() {
    // Cleanup resize observer
    if (sharedResizeObserver) {
      sharedResizeObserver.disconnect();
      sharedResizeObserver = null;
    }

    // Cleanup intersection observers
    for (const observer of intersectionObservers.values()) {
      observer.disconnect();
    }
    intersectionObservers.clear();
  }
};
/* harmony default export */ const utils_performance = (Performance);
;// ../assets/scripts/utils/logger.js
/**
 * Adminator Logger Utility
 * Development-only logging utility for debugging
 *
 * @module utils/logger
 */

/**
 * Check if we're in development mode
 * @returns {boolean}
 */
const isDev = () => {
  try {
    return  false || window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
  } catch {
    return false;
  }
};

/**
 * Logger object with development-only output
 * All methods are no-ops in production for zero overhead
 */
const Logger = {
  /**
   * Log informational messages (development only)
   * @param {string} message - The message to log
   * @param {Object} [context] - Additional context data
   */
  info(message, context) {
    if (isDev()) {
      console.info(`[Adminator] ${message}`, context || '');
    }
  },
  /**
   * Log warning messages (development only)
   * @param {string} message - The warning message
   * @param {Object} [context] - Additional context data
   */
  warn(message, context) {
    if (isDev()) {
      console.warn(`[Adminator] ${message}`, context || '');
    }
  },
  /**
   * Log error messages (development only)
   * @param {string} message - The error message
   * @param {Error|Object} [context] - Error object or context data
   */
  error(message, context) {
    if (isDev()) {
      console.error(`[Adminator] ${message}`, context || '');
    }
  },
  /**
   * Log debug messages (development only)
   * @param {string} message - The debug message
   * @param {Object} [context] - Additional context data
   */
  debug(message, context) {
    if (isDev()) {
      console.debug(`[Adminator] ${message}`, context || '');
    }
  },
  /**
   * Group related log messages (development only)
   * @param {string} label - Group label
   */
  group(label) {
    if (isDev()) {
      console.group(`[Adminator] ${label}`);
    }
  },
  /**
   * End a log group (development only)
   */
  groupEnd() {
    if (isDev()) {
      console.groupEnd();
    }
  },
  /**
   * Log with timing information (development only)
   * @param {string} label - Timer label
   */
  time(label) {
    if (isDev()) {
      console.time(`[Adminator] ${label}`);
    }
  },
  /**
   * End timing and log result (development only)
   * @param {string} label - Timer label (must match time() call)
   */
  timeEnd(label) {
    if (isDev()) {
      console.timeEnd(`[Adminator] ${label}`);
    }
  },
  /**
   * Log a table of data (development only)
   * @param {Array|Object} data - Data to display as table
   */
  table(data) {
    if (isDev()) {
      console.table(data);
    }
  }
};
/* harmony default export */ const logger = (Logger);
;// ../assets/scripts/components/Sidebar.js
/**
 * Modern Sidebar Component
 * Replaces jQuery-based sidebar functionality with vanilla JavaScript
 */

class Sidebar {
  constructor() {
    this.sidebar = document.querySelector('.sidebar');
    this.sidebarMenu = document.querySelector('.sidebar .sidebar-menu');
    this.sidebarToggleLinks = document.querySelectorAll('.sidebar-toggle a');
    this.sidebarToggleById = document.querySelector('#sidebar-toggle');
    this.app = document.querySelector('.app');
    this.init();
  }
  init() {
    if (!this.sidebar || !this.sidebarMenu) {
      return;
    }
    this.setupMenuToggle();
    this.setupSidebarToggle();
    this.setActiveLink();
  }

  /**
   * Setup dropdown menu functionality
   */
  setupMenuToggle() {
    const menuLinks = this.sidebarMenu.querySelectorAll('li a');
    menuLinks.forEach(link => {
      link.addEventListener('click', e => {
        const listItem = link.parentElement;
        const dropdownMenu = listItem.querySelector('.dropdown-menu');

        // If this is a regular navigation link (not dropdown), allow normal navigation
        if (!dropdownMenu) {
          // Don't prevent default for regular navigation links
          return;
        }

        // Only prevent default for dropdown toggles
        e.preventDefault();
        if (listItem.classList.contains('open')) {
          this.closeDropdown(listItem, dropdownMenu);
        } else {
          this.closeAllDropdowns();
          this.openDropdown(listItem, dropdownMenu);
        }
      });
    });
  }

  /**
   * Open dropdown with smooth animation
   */
  openDropdown(listItem, dropdownMenu) {
    listItem.classList.add('open');
    dropdownMenu.style.display = 'block';
    dropdownMenu.style.height = '0px';
    dropdownMenu.style.overflow = 'hidden';

    // Get the natural height
    const height = dropdownMenu.scrollHeight;

    // Animate to full height
    dropdownMenu.animate([{
      height: '0px'
    }, {
      height: `${height}px`
    }], {
      duration: 200,
      easing: 'ease-out'
    }).onfinish = () => {
      dropdownMenu.style.height = 'auto';
      dropdownMenu.style.overflow = 'visible';
    };
  }

  /**
   * Close dropdown with smooth animation
   */
  closeDropdown(listItem, dropdownMenu) {
    const height = dropdownMenu.scrollHeight;
    dropdownMenu.style.height = `${height}px`;
    dropdownMenu.style.overflow = 'hidden';
    dropdownMenu.animate([{
      height: `${height}px`
    }, {
      height: '0px'
    }], {
      duration: 200,
      easing: 'ease-in'
    }).onfinish = () => {
      listItem.classList.remove('open');
      dropdownMenu.style.display = 'none';
      dropdownMenu.style.height = '';
      dropdownMenu.style.overflow = '';
    };
  }

  /**
   * Close all open dropdowns
   */
  closeAllDropdowns() {
    const openItems = this.sidebarMenu.querySelectorAll('li.open');
    openItems.forEach(item => {
      const dropdownMenu = item.querySelector('.dropdown-menu');
      if (dropdownMenu) {
        this.closeDropdown(item, dropdownMenu);
      }

      // Also remove the has-active-child class
      item.classList.remove('has-active-child');
    });
  }

  /**
   * Setup sidebar toggle functionality
   */
  setupSidebarToggle() {
    // Handle mobile sidebar toggle links (inside .sidebar-toggle divs)
    this.sidebarToggleLinks.forEach(link => {
      if (link && this.app) {
        link.addEventListener('click', e => {
          e.preventDefault();
          this.toggleSidebar();
        });
      }
    });

    // Handle the main topbar sidebar toggle
    if (this.sidebarToggleById && this.app) {
      this.sidebarToggleById.addEventListener('click', e => {
        e.preventDefault();
        this.toggleSidebar();
      });
    }
  }

  /**
   * Toggle sidebar and handle resize events properly
   */
  toggleSidebar() {
    this.app.classList.toggle('is-collapsed');

    // Only trigger resize for masonry, but avoid chart redraw issues
    setTimeout(() => {
      // Dispatch a custom event instead of generic resize to avoid chart issues
      window.dispatchEvent(new CustomEvent('sidebar:toggle', {
        detail: {
          collapsed: this.app.classList.contains('is-collapsed')
        }
      }));

      // Still trigger resize for masonry but with a specific check
      if (window.EVENT) {
        window.dispatchEvent(window.EVENT);
      }
    }, 300);
  }

  /**
   * Set active link based on current URL
   */
  setActiveLink() {
    // Remove active class from all nav items (including dropdown items)
    const allNavItems = this.sidebar.querySelectorAll('.nav-item');
    allNavItems.forEach(item => {
      item.classList.remove('actived');
    });

    // Close all dropdowns first
    this.closeAllDropdowns();

    // Get current page filename
    const currentPath = window.location.pathname;
    const currentPage = currentPath.split('/').pop() || 'index.html';

    // Find and activate the correct nav item
    const allLinks = this.sidebar.querySelectorAll('a[href]');
    allLinks.forEach(link => {
      const href = link.getAttribute('href');
      if (!href || href === 'javascript:void(0);' || href === 'javascript:void(0)') return;

      // Extract filename from href
      const linkPage = href.split('/').pop();
      if (linkPage === currentPage) {
        const navItem = link.closest('.nav-item');
        if (navItem) {
          navItem.classList.add('actived');

          // If this is inside a dropdown, handle parent dropdown specially
          const parentDropdown = navItem.closest('.dropdown-menu');
          if (parentDropdown) {
            const parentDropdownItem = parentDropdown.closest('.nav-item.dropdown');
            if (parentDropdownItem) {
              // Open the parent dropdown
              parentDropdownItem.classList.add('open');
              parentDropdown.style.display = 'block';

              // Add special styling to indicate parent has active child
              parentDropdownItem.classList.add('has-active-child');
            }
          }
        }
      }
    });
  }

  /**
   * Public method to refresh active links (useful for SPA navigation)
   */
  refreshActiveLink() {
    this.setActiveLink();
  }

  /**
   * Public method to toggle sidebar programmatically
   */
  toggle() {
    if (this.app) {
      this.app.classList.toggle('is-collapsed');
    }
  }

  /**
   * Public method to check if sidebar is collapsed
   */
  isCollapsed() {
    return this.app ? this.app.classList.contains('is-collapsed') : false;
  }
}
/* harmony default export */ const components_Sidebar = (Sidebar);
// EXTERNAL MODULE: ../../node_modules/chart.js/dist/chart.js + 1 modules
var dist_chart = __webpack_require__(371);
;// ../assets/scripts/constants/colors.js
const COLORS = {
  'white': '#ffffff',
  'red-50': '#ffebee',
  'red-100': '#ffcdd2',
  'red-200': '#ef9a9a',
  'red-300': '#e57373',
  'red-400': '#ef5350',
  'red-500': '#f44336',
  'red-600': '#e53935',
  'red-700': '#d32f2f',
  'red-800': '#c62828',
  'red-900': '#b71c1c',
  'red-a100': '#ff8a80',
  'red-a200': '#ff5252',
  'red-a400': '#ff1744',
  'red-a700': '#d50000',
  'pink-50': '#fce4ec',
  'pink-100': '#f8bbd0',
  'pink-200': '#f48fb1',
  'pink-300': '#f06292',
  'pink-400': '#ec407a',
  'pink-500': '#e91e63',
  'pink-600': '#d81b60',
  'pink-700': '#c2185b',
  'pink-800': '#ad1457',
  'pink-900': '#880e4f',
  'pink-a100': '#ff80ab',
  'pink-a200': '#ff4081',
  'pink-a400': '#f50057',
  'pink-a700': '#c51162',
  'purple-50': '#f3e5f5',
  'purple-100': '#e1bee7',
  'purple-200': '#ce93d8',
  'purple-300': '#ba68c8',
  'purple-400': '#ab47bc',
  'purple-500': '#9c27b0',
  'purple-600': '#8e24aa',
  'purple-700': '#7b1fa2',
  'purple-800': '#6a1b9a',
  'purple-900': '#4a148c',
  'purple-a100': '#ea80fc',
  'purple-a200': '#e040fb',
  'purple-a400': '#d500f9',
  'purple-a700': '#aa00ff',
  'deep-purple-50': '#ede7f6',
  'deep-purple-100': '#d1c4e9',
  'deep-purple-200': '#b39ddb',
  'deep-purple-300': '#9575cd',
  'deep-purple-400': '#7e57c2',
  'deep-purple-500': '#673ab7',
  'deep-purple-600': '#5e35b1',
  'deep-purple-700': '#512da8',
  'deep-purple-800': '#4527a0',
  'deep-purple-900': '#311b92',
  'deep-purple-a100': '#b388ff',
  'deep-purple-a200': '#7c4dff',
  'deep-purple-a400': '#651fff',
  'deep-purple-a700': '#6200ea',
  'indigo-50': '#e8eaf6',
  'indigo-100': '#c5cae9',
  'indigo-200': '#9fa8da',
  'indigo-300': '#7986cb',
  'indigo-400': '#5c6bc0',
  'indigo-500': '#3f51b5',
  'indigo-600': '#3949ab',
  'indigo-700': '#303f9f',
  'indigo-800': '#283593',
  'indigo-900': '#1a237e',
  'indigo-a100': '#8c9eff',
  'indigo-a200': '#536dfe',
  'indigo-a400': '#3d5afe',
  'indigo-a700': '#304ffe',
  'blue-50': '#e3f2fd',
  'blue-100': '#bbdefb',
  'blue-200': '#90caf9',
  'blue-300': '#64b5f6',
  'blue-400': '#42a5f5',
  'blue-500': '#2196f3',
  'blue-600': '#1e88e5',
  'blue-700': '#1976d2',
  'blue-800': '#1565c0',
  'blue-900': '#0d47a1',
  'blue-a100': '#82b1ff',
  'blue-a200': '#448aff',
  'blue-a400': '#2979ff',
  'blue-a700': '#2962ff',
  'light-blue-50': '#e1f5fe',
  'light-blue-100': '#b3e5fc',
  'light-blue-200': '#81d4fa',
  'light-blue-300': '#4fc3f7',
  'light-blue-400': '#29b6f6',
  'light-blue-500': '#03a9f4',
  'light-blue-600': '#039be5',
  'light-blue-700': '#0288d1',
  'light-blue-800': '#0277bd',
  'light-blue-900': '#01579b',
  'light-blue-a100': '#80d8ff',
  'light-blue-a200': '#40c4ff',
  'light-blue-a400': '#00b0ff',
  'light-blue-a700': '#0091ea',
  'cyan-50': '#e0f7fa',
  'cyan-100': '#b2ebf2',
  'cyan-200': '#80deea',
  'cyan-300': '#4dd0e1',
  'cyan-400': '#26c6da',
  'cyan-500': '#00bcd4',
  'cyan-600': '#00acc1',
  'cyan-700': '#0097a7',
  'cyan-800': '#00838f',
  'cyan-900': '#006064',
  'cyan-a100': '#84ffff',
  'cyan-a200': '#18ffff',
  'cyan-a400': '#00e5ff',
  'cyan-a700': '#00b8d4',
  'teal-50': '#e0f2f1',
  'teal-100': '#b2dfdb',
  'teal-200': '#80cbc4',
  'teal-300': '#4db6ac',
  'teal-400': '#26a69a',
  'teal-500': '#009688',
  'teal-600': '#00897b',
  'teal-700': '#00796b',
  'teal-800': '#00695c',
  'teal-900': '#004d40',
  'teal-a100': '#a7ffeb',
  'teal-a200': '#64ffda',
  'teal-a400': '#1de9b6',
  'teal-a700': '#00bfa5',
  'green-50': '#e8f5e9',
  'green-100': '#c8e6c9',
  'green-200': '#a5d6a7',
  'green-300': '#81c784',
  'green-400': '#66bb6a',
  'green-500': '#4caf50',
  'green-600': '#43a047',
  'green-700': '#388e3c',
  'green-800': '#2e7d32',
  'green-900': '#1b5e20',
  'green-a100': '#b9f6ca',
  'green-a200': '#69f0ae',
  'green-a400': '#00e676',
  'green-a700': '#00c853',
  'light-green-50': '#f1f8e9',
  'light-green-100': '#dcedc8',
  'light-green-200': '#c5e1a5',
  'light-green-300': '#aed581',
  'light-green-400': '#9ccc65',
  'light-green-500': '#8bc34a',
  'light-green-600': '#7cb342',
  'light-green-700': '#689f38',
  'light-green-800': '#558b2f',
  'light-green-900': '#33691e',
  'light-green-a100': '#ccff90',
  'light-green-a200': '#b2ff59',
  'light-green-a400': '#76ff03',
  'light-green-a700': '#64dd17',
  'lime-50': '#f9fbe7',
  'lime-100': '#f0f4c3',
  'lime-200': '#e6ee9c',
  'lime-300': '#dce775',
  'lime-400': '#d4e157',
  'lime-500': '#cddc39',
  'lime-600': '#c0ca33',
  'lime-700': '#afb42b',
  'lime-800': '#9e9d24',
  'lime-900': '#827717',
  'lime-a100': '#f4ff81',
  'lime-a200': '#eeff41',
  'lime-a400': '#c6ff00',
  'lime-a700': '#aeea00',
  'yellow-50': '#fffde7',
  'yellow-100': '#fff9c4',
  'yellow-200': '#fff59d',
  'yellow-300': '#fff176',
  'yellow-400': '#ffee58',
  'yellow-500': '#ffeb3b',
  'yellow-600': '#fdd835',
  'yellow-700': '#fbc02d',
  'yellow-800': '#f9a825',
  'yellow-900': '#f57f17',
  'yellow-a100': '#ffff8d',
  'yellow-a200': '#ffff00',
  'yellow-a400': '#ffea00',
  'yellow-a700': '#ffd600',
  'amber-50': '#fff8e1',
  'amber-100': '#ffecb3',
  'amber-200': '#ffe082',
  'amber-300': '#ffd54f',
  'amber-400': '#ffca28',
  'amber-500': '#ffc107',
  'amber-600': '#ffb300',
  'amber-700': '#ffa000',
  'amber-800': '#ff8f00',
  'amber-900': '#ff6f00',
  'amber-a100': '#ffe57f',
  'amber-a200': '#ffd740',
  'amber-a400': '#ffc400',
  'amber-a700': '#ffab00',
  'orange-50': '#fff3e0',
  'orange-100': '#ffe0b2',
  'orange-200': '#ffcc80',
  'orange-300': '#ffb74d',
  'orange-400': '#ffa726',
  'orange-500': '#ff9800',
  'orange-600': '#fb8c00',
  'orange-700': '#f57c00',
  'orange-800': '#ef6c00',
  'orange-900': '#e65100',
  'orange-a100': '#ffd180',
  'orange-a200': '#ffab40',
  'orange-a400': '#ff9100',
  'orange-a700': '#ff6d00',
  'deep-orange-50': '#fbe9e7',
  'deep-orange-100': '#ffccbc',
  'deep-orange-200': '#ffab91',
  'deep-orange-300': '#ff8a65',
  'deep-orange-400': '#ff7043',
  'deep-orange-500': '#ff5722',
  'deep-orange-600': '#f4511e',
  'deep-orange-700': '#e64a19',
  'deep-orange-800': '#d84315',
  'deep-orange-900': '#bf360c',
  'deep-orange-a100': '#ff9e80',
  'deep-orange-a200': '#ff6e40',
  'deep-orange-a400': '#ff3d00',
  'deep-orange-a700': '#dd2c00',
  'brown-50': '#efebe9',
  'brown-100': '#d7ccc8',
  'brown-200': '#bcaaa4',
  'brown-300': '#a1887f',
  'brown-400': '#8d6e63',
  'brown-500': '#795548',
  'brown-600': '#6d4c41',
  'brown-700': '#5d4037',
  'brown-800': '#4e342e',
  'brown-900': '#3e2723',
  'grey-50': '#fafafa',
  'grey-100': '#f5f5f5',
  'grey-200': '#eeeeee',
  'grey-300': '#e0e0e0',
  'grey-400': '#bdbdbd',
  'grey-500': '#9e9e9e',
  'grey-600': '#757575',
  'grey-700': '#616161',
  'grey-800': '#424242',
  'grey-900': '#212121',
  'blue-grey-50': '#eceff1',
  'blue-grey-100': '#cfd8dc',
  'blue-grey-200': '#b0bec5',
  'blue-grey-300': '#90a4ae',
  'blue-grey-400': '#78909c',
  'blue-grey-500': '#607d8b',
  'blue-grey-600': '#546e7a',
  'blue-grey-700': '#455a64',
  'blue-grey-800': '#37474f',
  'blue-grey-900': '#263238'
};
const GREYS = {
  'grey-100': '#f9fafb',
  'grey-200': '#f2f3f5',
  'grey-300': '#e6eaf0',
  'grey-400': '#d3d9e3',
  'grey-500': '#b9c2d0',
  'grey-600': '#7c8695',
  'grey-700': '#72777a',
  'grey-800': '#565a5c',
  'grey-900': '#313435'
};

;// ../assets/scripts/components/Chart.js
/**
 * Modern Chart Component
 * Replaces jQuery Sparkline with Chart.js
 */




// Register Chart.js components
dist_chart/* Chart */.t1.register(...dist_chart/* registerables */.$L);
class ChartComponent {
  constructor() {
    this.charts = new Map(); // Store chart instances
    this.debounceTimer = null;
    this.init();
  }
  init() {
    // Only disable resizing for small sparkline charts
    this.createSparklines();
    this.createOtherCharts();
    this.setupResizeHandler();
  }

  /**
   * Create sparklines (only for dashboard page)
   */
  createSparklines() {
    // Only create sparklines if we're on a page that has them
    const sparklineExists = document.getElementById('sparklinedash');
    if (!sparklineExists) {
      return;
    }
    const sparklineConfigs = [{
      id: 'sparklinedash',
      data: [0, 5, 6, 10, 9, 12, 4, 9],
      color: '#4caf50'
    }, {
      id: 'sparklinedash2',
      data: [0, 5, 6, 10, 9, 12, 4, 9],
      color: '#9675ce'
    }, {
      id: 'sparklinedash3',
      data: [0, 5, 6, 10, 9, 12, 4, 9],
      color: '#03a9f3'
    }, {
      id: 'sparklinedash4',
      data: [0, 5, 6, 10, 9, 12, 4, 9],
      color: '#f96262'
    }];
    sparklineConfigs.forEach(config => {
      // Only create if the target element exists
      if (document.getElementById(config.id)) {
        this.createSparklineChart(config);
      }
    });
  }

  /**
   * Create sparkline chart from configuration
   */
  createSparklineChart(_ref) {
    let {
      id,
      data,
      color
    } = _ref;
    let canvas = document.getElementById(id);

    // Only proceed if we have a valid target element
    if (!canvas) {
      return;
    }

    // If element exists but isn't a canvas, replace it with canvas
    if (canvas.tagName !== 'CANVAS') {
      const parent = canvas.parentNode;
      if (!parent) {
        return;
      }

      // Create new canvas element
      const newCanvas = document.createElement('canvas');
      newCanvas.id = id;
      newCanvas.width = 100;
      newCanvas.height = 20;
      newCanvas.style.width = '100px';
      newCanvas.style.height = '20px';

      // Replace the span with canvas
      parent.replaceChild(newCanvas, canvas);
      canvas = newCanvas;
    } else {
      // Set canvas dimensions to match original sparkline
      canvas.width = 100;
      canvas.height = 20;
      canvas.style.width = '100px';
      canvas.style.height = '20px';
    }
    const ctx = canvas.getContext('2d');
    const chart = new dist_chart/* Chart */.t1(ctx, {
      type: 'bar',
      data: {
        labels: data.map((_, i) => i),
        datasets: [{
          data,
          backgroundColor: color,
          borderColor: color,
          borderWidth: 0,
          barPercentage: 0.6,
          categoryPercentage: 0.8
        }]
      },
      options: {
        responsive: false,
        maintainAspectRatio: false,
        animation: false,
        events: [],
        onResize: null,
        scales: {
          x: {
            display: false
          },
          y: {
            display: false
          }
        },
        plugins: {
          legend: {
            display: false
          },
          tooltip: {
            enabled: false
          }
        },
        elements: {
          bar: {
            borderRadius: 1
          }
        }
      }
    });
    this.charts.set(id, chart);
  }

  /**
   * Create other chart types (only if they exist on the page)
   */
  createOtherCharts() {
    // Determine if we're on the dashboard or charts page
    const isChartsPage = document.getElementById('area-chart') !== null;
    const isDashboard = !isChartsPage && document.getElementById('line-chart') !== null;

    // Create Monthly Stats chart with enhanced dual-line data (dashboard only)
    if (isDashboard) {
      this.createMonthlyStatsChart();
    }

    // Charts page specific charts (only on charts page)
    if (isChartsPage) {
      this.createChartsPageCharts();
    }

    // Only create charts if their target elements exist
    if (document.getElementById('sparkline')) {
      this.createLineChart('sparkline', [5, 6, 7, 9, 9, 5, 3, 2, 2, 4, 6, 7]);
    }
    if (document.getElementById('compositebar')) {
      this.createCompositeChart('compositebar', [4, 1, 5, 7, 9, 9, 8, 7, 6, 6, 4, 7, 8, 4, 3, 2, 2, 5, 6, 7]);
    }

    // Regular sparklines with custom colors (only on pages that have them)
    this.createCustomSparklines();

    // Easy Pie Charts (only if they exist)
    this.createEasyPieCharts();
  }

  /**
   * Create enhanced Monthly Stats chart with dual lines and more data
   */
  createMonthlyStatsChart() {
    const canvas = document.getElementById('line-chart');
    if (!canvas) return;
    const ctx = canvas.getContext('2d');

    // Enhanced data for monthly stats
    const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    const salesData = [120, 135, 145, 165, 180, 195, 210, 225, 240, 220, 200, 185];
    const profitData = [45, 52, 58, 62, 68, 75, 82, 88, 92, 85, 78, 72];
    const chart = new dist_chart/* Chart */.t1(ctx, {
      type: 'line',
      data: {
        labels: months,
        datasets: [{
          label: 'Sales ($K)',
          data: salesData,
          borderColor: '#4caf50',
          backgroundColor: 'rgba(76, 175, 80, 0.1)',
          borderWidth: 3,
          pointRadius: 5,
          pointHoverRadius: 7,
          pointBackgroundColor: '#4caf50',
          pointBorderColor: '#ffffff',
          pointBorderWidth: 2,
          tension: 0.4,
          fill: false
        }, {
          label: 'Profit ($K)',
          data: profitData,
          borderColor: '#2196f3',
          backgroundColor: 'rgba(33, 150, 243, 0.1)',
          borderWidth: 3,
          pointRadius: 5,
          pointHoverRadius: 7,
          pointBackgroundColor: '#2196f3',
          pointBorderColor: '#ffffff',
          pointBorderWidth: 2,
          tension: 0.4,
          fill: false
        }]
      },
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: {
            display: true,
            position: 'top',
            labels: {
              padding: 20,
              font: {
                size: 12,
                weight: '600'
              }
            }
          },
          tooltip: {
            enabled: true,
            cornerRadius: 8,
            displayColors: true,
            intersect: false,
            mode: 'index',
            callbacks: {
              label(context) {
                return `${context.dataset.label}: $${context.parsed.y}K`;
              }
            }
          }
        },
        scales: {
          x: {
            grid: {
              display: false
            },
            ticks: {
              font: {
                size: 11
              }
            }
          },
          y: {
            beginAtZero: true,
            grid: {
              borderDash: [5, 5]
            },
            ticks: {
              font: {
                size: 11
              },
              callback(value) {
                return `$${value}K`;
              }
            }
          }
        },
        interaction: {
          intersect: false,
          mode: 'index'
        }
      }
    });
    this.charts.set('line-chart', chart);
  }

  /**
   * Create line chart (only if target exists)
   */
  createLineChart(id, data) {
    let canvas = document.getElementById(id);

    // Only proceed if target element exists
    if (!canvas) {
      return;
    }

    // If element exists but isn't a canvas, replace it with canvas
    if (canvas.tagName !== 'CANVAS') {
      const parent = canvas.parentNode;
      if (!parent) {
        return;
      }

      // Create new canvas element
      const newCanvas = document.createElement('canvas');
      newCanvas.id = id;
      newCanvas.width = 100;
      newCanvas.height = 20;
      newCanvas.style.width = '100px';
      newCanvas.style.height = '20px';

      // Replace element with canvas
      parent.replaceChild(newCanvas, canvas);
      canvas = newCanvas;
    } else {
      canvas.width = 100;
      canvas.height = 20;
      canvas.style.width = '100px';
      canvas.style.height = '20px';
    }
    const ctx = canvas.getContext('2d');
    const chart = new dist_chart/* Chart */.t1(ctx, {
      type: 'line',
      data: {
        labels: data.map((_, i) => i),
        datasets: [{
          data,
          borderColor: COLORS['blue-500'],
          backgroundColor: 'transparent',
          borderWidth: 1,
          pointRadius: 0,
          tension: 0.4
        }]
      },
      options: {
        responsive: false,
        maintainAspectRatio: false,
        animation: false,
        events: [],
        onResize: null,
        scales: {
          x: {
            display: false
          },
          y: {
            display: false
          }
        },
        plugins: {
          legend: {
            display: false
          },
          tooltip: {
            enabled: false
          }
        }
      }
    });
    this.charts.set(id, chart);
  }

  /**
   * Create composite chart (only if target exists)
   */
  createCompositeChart(id, data) {
    let canvas = document.getElementById(id);

    // Only proceed if target element exists
    if (!canvas) {
      return;
    }

    // If element exists but isn't a canvas, replace it with canvas  
    if (canvas.tagName !== 'CANVAS') {
      const parent = canvas.parentNode;
      if (!parent) {
        return;
      }

      // Create new canvas element
      const newCanvas = document.createElement('canvas');
      newCanvas.id = id;
      newCanvas.width = 100;
      newCanvas.height = 20;
      newCanvas.style.width = '100px';
      newCanvas.style.height = '20px';

      // Replace element with canvas
      parent.replaceChild(newCanvas, canvas);
      canvas = newCanvas;
    } else {
      canvas.width = 100;
      canvas.height = 20;
      canvas.style.width = '100px';
      canvas.style.height = '20px';
    }
    const ctx = canvas.getContext('2d');
    const chart = new dist_chart/* Chart */.t1(ctx, {
      type: 'bar',
      data: {
        labels: data.map((_, i) => i),
        datasets: [{
          type: 'bar',
          data,
          backgroundColor: '#aaf',
          borderColor: '#aaf',
          borderWidth: 0
        }, {
          type: 'line',
          data,
          borderColor: 'red',
          backgroundColor: 'transparent',
          borderWidth: 1,
          pointRadius: 0,
          tension: 0.4
        }]
      },
      options: {
        responsive: false,
        maintainAspectRatio: false,
        animation: false,
        events: [],
        onResize: null,
        scales: {
          x: {
            display: false
          },
          y: {
            display: false
          }
        },
        plugins: {
          legend: {
            display: false
          },
          tooltip: {
            enabled: false
          }
        }
      }
    });
    this.charts.set(id, chart);
  }

  /**
   * Create custom sparklines for different elements (only if they exist)
   */
  createCustomSparklines() {
    const sparklineElements = document.querySelectorAll('.sparkline');
    const sparkbarElements = document.querySelectorAll('.sparkbar');
    const sparktriElements = document.querySelectorAll('.sparktri');
    const sparkdiscElements = document.querySelectorAll('.sparkdisc');
    const sparkbullElements = document.querySelectorAll('.sparkbull');
    const sparkboxElements = document.querySelectorAll('.sparkbox');

    // Only create if we have elements
    if (sparklineElements.length === 0 && sparkbarElements.length === 0 && sparktriElements.length === 0 && sparkdiscElements.length === 0 && sparkbullElements.length === 0 && sparkboxElements.length === 0) {
      return;
    }
    const values = [5, 4, 5, -2, 0, 3, -5, 6, 7, 9, 9, 5, -3, -2, 2, -4];
    const valuesAlt = [1, 1, 0, 1, -1, -1, 1, -1, 0, 0, 1, 1];
    sparklineElements.forEach((element, index) => {
      this.createCustomLineChart(element, values, `sparkline-${index}`);
    });
    sparkbarElements.forEach((element, index) => {
      this.createCustomBarChart(element, values, `sparkbar-${index}`);
    });
    sparktriElements.forEach((element, index) => {
      this.createTristateChart(element, valuesAlt, `sparktri-${index}`);
    });
    sparkdiscElements.forEach((element, index) => {
      this.createDiscreteChart(element, values, `sparkdisc-${index}`);
    });
    sparkbullElements.forEach((element, index) => {
      this.createBulletChart(element, values, `sparkbull-${index}`);
    });
    sparkboxElements.forEach((element, index) => {
      this.createBoxChart(element, values, `sparkbox-${index}`);
    });
  }

  /**
   * Create custom line chart for sparkline elements
   */
  createCustomLineChart(element, data, id) {
    // Create canvas if it doesn't exist
    let canvas = element.querySelector('canvas');
    if (!canvas) {
      canvas = document.createElement('canvas');
      canvas.width = 100;
      canvas.height = 20;
      canvas.style.width = '100px';
      canvas.style.height = '20px';
      element.appendChild(canvas);
    }
    const ctx = canvas.getContext('2d');
    const chart = new dist_chart/* Chart */.t1(ctx, {
      type: 'line',
      data: {
        labels: data.map((_, i) => i),
        datasets: [{
          data,
          borderColor: COLORS['red-500'],
          backgroundColor: 'transparent',
          borderWidth: 2,
          pointRadius: 3,
          pointBackgroundColor: COLORS['red-500'],
          tension: 0.4
        }]
      },
      options: {
        responsive: false,
        maintainAspectRatio: false,
        animation: false,
        // Disable animations to prevent resize triggers
        events: [],
        // Disable all events to prevent resize
        onResize: null,
        // Explicitly disable resize callback
        scales: {
          x: {
            display: false
          },
          y: {
            display: false
          }
        },
        plugins: {
          legend: {
            display: false
          },
          tooltip: {
            enabled: false
          } // Disable tooltip to prevent events
        }
      }
    });
    this.charts.set(id, chart);
  }

  /**
   * Create custom bar chart for sparkbar elements
   */
  createCustomBarChart(element, data, id) {
    // Create canvas if it doesn't exist
    let canvas = element.querySelector('canvas');
    if (!canvas) {
      canvas = document.createElement('canvas');
      canvas.width = 100;
      canvas.height = 20;
      canvas.style.width = '100px';
      canvas.style.height = '20px';
      element.appendChild(canvas);
    }
    const ctx = canvas.getContext('2d');
    const chart = new dist_chart/* Chart */.t1(ctx, {
      type: 'bar',
      data: {
        labels: data.map((_, i) => i),
        datasets: [{
          data,
          backgroundColor: data.map(val => val < 0 ? COLORS['deep-purple-500'] : '#39f'),
          borderColor: data.map(val => val < 0 ? COLORS['deep-purple-500'] : '#39f'),
          borderWidth: 1,
          barPercentage: 0.8
        }]
      },
      options: {
        responsive: false,
        maintainAspectRatio: false,
        scales: {
          x: {
            display: false
          },
          y: {
            display: false
          }
        },
        plugins: {
          legend: {
            display: false
          },
          tooltip: {
            enabled: true,
            callbacks: {
              label: context => `${context.parsed.y}°Celsius`
            }
          }
        }
      }
    });
    this.charts.set(id, chart);
  }

  /**
   * Setup resize handler for charts
   */
  setupResizeHandler() {
    // Setup responsive resize for large charts only
    window.addEventListener('resize', () => {
      this.debounceResize();
    });

    // Listen for sidebar toggle events
    window.addEventListener('sidebar:toggle', () => {
      this.debounceResize();
    });
  }

  /**
   * Debounced resize handler
   */
  debounceResize() {
    if (this.debounceTimer) {
      clearTimeout(this.debounceTimer);
    }
    this.debounceTimer = setTimeout(() => {
      this.redrawLargeChartsOnly();
    }, 150);
  }

  /**
   * Redraw only large charts, not sparklines
   */
  redrawLargeChartsOnly() {
    const largeChartIds = ['line-chart', 'area-chart', 'scatter-chart', 'bar-chart', 'doughnut-chart', 'polar-chart', 'radar-chart', 'mixed-chart', 'bubble-chart'];
    largeChartIds.forEach(id => {
      const chart = this.charts.get(id);
      if (chart && chart.options.responsive) {
        chart.resize();
      }
    });
  }

  /**
   * Redraw all charts (used sparingly)
   */
  redrawCharts() {
    this.charts.forEach(chart => {
      if (chart.options.responsive) {
        chart.resize();
      }
    });
  }

  /**
   * Update chart data
   */
  updateChart(id, newData) {
    const chart = this.charts.get(id);
    if (chart) {
      chart.data.datasets[0].data = newData;
      chart.update();
    }
  }

  /**
   * Create charts for the charts.html page
   */
  createChartsPageCharts() {
    // Line Chart
    this.createLargeChart('line-chart', 'line', {
      labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
      datasets: [{
        label: 'Dataset 1',
        data: [65, 59, 80, 81, 56, 55, 40],
        borderColor: 'rgb(75, 192, 192)',
        backgroundColor: 'rgba(75, 192, 192, 0.2)',
        tension: 0.4
      }]
    });

    // Area Chart
    this.createLargeChart('area-chart', 'line', {
      labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
      datasets: [{
        label: 'Dataset 1',
        data: [65, 59, 80, 81, 56, 55, 40],
        borderColor: 'rgb(54, 162, 235)',
        backgroundColor: 'rgba(54, 162, 235, 0.4)',
        fill: true,
        tension: 0.4
      }]
    });

    // Scatter Chart with more data points
    this.createLargeChart('scatter-chart', 'scatter', {
      datasets: [{
        label: 'Dataset 1',
        data: [{
          x: -15,
          y: 8
        }, {
          x: -12,
          y: 12
        }, {
          x: -8,
          y: 3
        }, {
          x: -5,
          y: 15
        }, {
          x: -2,
          y: 7
        }, {
          x: 0,
          y: 10
        }, {
          x: 3,
          y: 18
        }, {
          x: 6,
          y: 5
        }, {
          x: 9,
          y: 22
        }, {
          x: 12,
          y: 8
        }, {
          x: 15,
          y: 14
        }, {
          x: 18,
          y: 19
        }, {
          x: -10,
          y: 0
        }, {
          x: 10,
          y: 5
        }, {
          x: 0.5,
          y: 5.5
        }, {
          x: 7,
          y: 12
        }, {
          x: -7,
          y: 17
        }, {
          x: 4,
          y: 9
        }, {
          x: 11,
          y: 16
        }, {
          x: -3,
          y: 11
        }],
        backgroundColor: 'rgba(255, 99, 132, 0.7)',
        borderColor: 'rgb(255, 99, 132)',
        borderWidth: 1
      }, {
        label: 'Dataset 2',
        data: [{
          x: -13,
          y: 4
        }, {
          x: -9,
          y: 8
        }, {
          x: -6,
          y: 13
        }, {
          x: -1,
          y: 6
        }, {
          x: 2,
          y: 11
        }, {
          x: 5,
          y: 15
        }, {
          x: 8,
          y: 2
        }, {
          x: 13,
          y: 17
        }, {
          x: 16,
          y: 9
        }, {
          x: -4,
          y: 14
        }, {
          x: 1,
          y: 20
        }, {
          x: 14,
          y: 4
        }],
        backgroundColor: 'rgba(54, 162, 235, 0.7)',
        borderColor: 'rgb(54, 162, 235)',
        borderWidth: 1
      }]
    });

    // Bar Chart
    this.createLargeChart('bar-chart', 'bar', {
      labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
      datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        backgroundColor: ['rgba(255, 99, 132, 0.6)', 'rgba(54, 162, 235, 0.6)', 'rgba(255, 205, 86, 0.6)', 'rgba(75, 192, 192, 0.6)', 'rgba(153, 102, 255, 0.6)', 'rgba(255, 159, 64, 0.6)'],
        borderColor: ['rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 205, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)'],
        borderWidth: 1
      }]
    });

    // Doughnut Chart
    this.createLargeChart('doughnut-chart', 'doughnut', {
      labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
      datasets: [{
        label: 'My First Dataset',
        data: [300, 50, 100, 75, 120, 60],
        backgroundColor: ['rgba(255, 99, 132, 0.8)', 'rgba(54, 162, 235, 0.8)', 'rgba(255, 205, 86, 0.8)', 'rgba(75, 192, 192, 0.8)', 'rgba(153, 102, 255, 0.8)', 'rgba(255, 159, 64, 0.8)'],
        borderColor: ['rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 205, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)'],
        borderWidth: 2,
        hoverOffset: 10
      }]
    });

    // Polar Area Chart
    this.createLargeChart('polar-chart', 'polarArea', {
      labels: ['Red', 'Green', 'Yellow', 'Grey', 'Blue'],
      datasets: [{
        label: 'My First Dataset',
        data: [11, 16, 7, 3, 14],
        backgroundColor: ['rgba(255, 99, 132, 0.7)', 'rgba(75, 192, 192, 0.7)', 'rgba(255, 205, 86, 0.7)', 'rgba(201, 203, 207, 0.7)', 'rgba(54, 162, 235, 0.7)'],
        borderColor: ['rgb(255, 99, 132)', 'rgb(75, 192, 192)', 'rgb(255, 205, 86)', 'rgb(201, 203, 207)', 'rgb(54, 162, 235)'],
        borderWidth: 2
      }]
    });

    // Radar Chart
    this.createLargeChart('radar-chart', 'radar', {
      labels: ['Speed', 'Reliability', 'Comfort', 'Safety', 'Efficiency', 'Innovation'],
      datasets: [{
        label: 'Product A',
        data: [65, 59, 90, 81, 56, 55],
        fill: true,
        backgroundColor: 'rgba(54, 162, 235, 0.2)',
        borderColor: 'rgb(54, 162, 235)',
        borderWidth: 2,
        pointBackgroundColor: 'rgb(54, 162, 235)',
        pointBorderColor: '#fff',
        pointHoverBackgroundColor: '#fff',
        pointHoverBorderColor: 'rgb(54, 162, 235)'
      }, {
        label: 'Product B',
        data: [28, 48, 40, 95, 86, 27],
        fill: true,
        backgroundColor: 'rgba(255, 99, 132, 0.2)',
        borderColor: 'rgb(255, 99, 132)',
        borderWidth: 2,
        pointBackgroundColor: 'rgb(255, 99, 132)',
        pointBorderColor: '#fff',
        pointHoverBackgroundColor: '#fff',
        pointHoverBorderColor: 'rgb(255, 99, 132)'
      }]
    });

    // Mixed Chart (Bar + Line)
    this.createLargeChart('mixed-chart', 'bar', {
      labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
      datasets: [{
        type: 'bar',
        label: 'Sales',
        data: [12, 19, 3, 5, 2, 3],
        backgroundColor: 'rgba(54, 162, 235, 0.7)',
        borderColor: 'rgb(54, 162, 235)',
        borderWidth: 1
      }, {
        type: 'line',
        label: 'Revenue',
        data: [18, 25, 8, 15, 12, 18],
        fill: false,
        borderColor: 'rgb(255, 99, 132)',
        backgroundColor: 'rgba(255, 99, 132, 0.2)',
        borderWidth: 3,
        tension: 0.4,
        pointRadius: 5,
        pointHoverRadius: 7
      }]
    });

    // Bubble Chart
    this.createLargeChart('bubble-chart', 'bubble', {
      datasets: [{
        label: 'First Dataset',
        data: [{
          x: 20,
          y: 30,
          r: 15
        }, {
          x: 40,
          y: 10,
          r: 10
        }, {
          x: 30,
          y: 40,
          r: 20
        }, {
          x: 50,
          y: 35,
          r: 12
        }, {
          x: 10,
          y: 50,
          r: 8
        }, {
          x: 60,
          y: 20,
          r: 18
        }, {
          x: 25,
          y: 25,
          r: 14
        }],
        backgroundColor: 'rgba(54, 162, 235, 0.6)',
        borderColor: 'rgb(54, 162, 235)',
        borderWidth: 2
      }, {
        label: 'Second Dataset',
        data: [{
          x: 15,
          y: 45,
          r: 12
        }, {
          x: 35,
          y: 15,
          r: 16
        }, {
          x: 45,
          y: 25,
          r: 9
        }, {
          x: 55,
          y: 45,
          r: 14
        }, {
          x: 25,
          y: 35,
          r: 11
        }],
        backgroundColor: 'rgba(255, 99, 132, 0.6)',
        borderColor: 'rgb(255, 99, 132)',
        borderWidth: 2
      }]
    });
  }

  /**
   * Create large chart for charts page
   */
  createLargeChart(id, type, data) {
    const canvas = document.getElementById(id);
    if (!canvas) return;
    const ctx = canvas.getContext('2d');

    // Define chart-specific options
    const chartOptions = this.getChartOptions(type);
    const chart = new dist_chart/* Chart */.t1(ctx, {
      type,
      data,
      options: chartOptions
    });
    this.charts.set(id, chart);
  }

  /**
   * Get chart-specific options based on chart type
   */
  getChartOptions(type) {
    const baseOptions = {
      responsive: true,
      maintainAspectRatio: false,
      plugins: {
        legend: {
          display: true,
          position: 'top',
          labels: {
            padding: 20,
            font: {
              size: 12,
              weight: '600'
            }
          }
        },
        tooltip: {
          enabled: true,
          cornerRadius: 8,
          displayColors: true
        }
      }
    };

    // Chart type specific configurations
    switch (type) {
      case 'doughnut':
      case 'pie':
        return {
          ...baseOptions,
          plugins: {
            ...baseOptions.plugins,
            legend: {
              ...baseOptions.plugins.legend,
              position: 'right'
            }
          },
          interaction: {
            intersect: false
          }
        };
      case 'polarArea':
        return {
          ...baseOptions,
          scales: {
            r: {
              pointLabels: {
                display: true,
                centerPointLabels: true,
                font: {
                  size: 10
                }
              },
              grid: {}
            }
          }
        };
      case 'radar':
        return {
          ...baseOptions,
          scales: {
            r: {
              angleLines: {
                display: true
              },
              grid: {},
              pointLabels: {
                font: {
                  size: 11
                }
              },
              ticks: {
                display: true,
                font: {
                  size: 10
                }
              }
            }
          }
        };
      case 'bubble':
        return {
          ...baseOptions,
          scales: {
            x: {
              type: 'linear',
              position: 'bottom',
              grid: {
                borderDash: [5, 5]
              },
              ticks: {
                font: {
                  size: 11
                }
              }
            },
            y: {
              beginAtZero: true,
              grid: {
                borderDash: [5, 5]
              },
              ticks: {
                font: {
                  size: 11
                }
              }
            }
          },
          plugins: {
            ...baseOptions.plugins,
            tooltip: {
              ...baseOptions.plugins.tooltip,
              callbacks: {
                label(context) {
                  return `${context.dataset.label}: (${context.parsed.x}, ${context.parsed.y}), Size: ${context.parsed._custom}`;
                }
              }
            }
          }
        };
      case 'scatter':
        return {
          ...baseOptions,
          scales: {
            x: {
              type: 'linear',
              position: 'bottom',
              grid: {
                borderDash: [5, 5]
              },
              ticks: {
                font: {
                  size: 11
                }
              }
            },
            y: {
              grid: {
                borderDash: [5, 5]
              },
              ticks: {
                font: {
                  size: 11
                }
              }
            }
          }
        };
      default:
        // For line, bar, area, mixed charts
        return {
          ...baseOptions,
          scales: {
            x: {
              grid: {
                borderDash: [5, 5]
              },
              ticks: {
                font: {
                  size: 11
                }
              }
            },
            y: {
              beginAtZero: true,
              grid: {
                borderDash: [5, 5]
              },
              ticks: {
                font: {
                  size: 11
                }
              }
            }
          }
        };
    }
  }

  /**
   * Create tristate chart (for .sparktri elements)
   */
  createTristateChart(element, data, id) {
    let canvas = element.querySelector('canvas');
    if (!canvas) {
      canvas = document.createElement('canvas');
      canvas.width = 100;
      canvas.height = 20;
      canvas.style.width = '100px';
      canvas.style.height = '20px';
      element.appendChild(canvas);
    }
    const ctx = canvas.getContext('2d');
    const chart = new dist_chart/* Chart */.t1(ctx, {
      type: 'bar',
      data: {
        labels: data.map((_, i) => i),
        datasets: [{
          data: data.map(val => Math.abs(val)),
          backgroundColor: data.map(val => {
            if (val > 0) return COLORS['light-blue-500'];
            if (val < 0) return '#f90';
            return '#000';
          }),
          borderColor: data.map(val => {
            if (val > 0) return COLORS['light-blue-500'];
            if (val < 0) return '#f90';
            return '#000';
          }),
          borderWidth: 1,
          barPercentage: 0.8
        }]
      },
      options: {
        responsive: false,
        maintainAspectRatio: false,
        scales: {
          x: {
            display: false
          },
          y: {
            display: false
          }
        },
        plugins: {
          legend: {
            display: false
          },
          tooltip: {
            enabled: true,
            callbacks: {
              label: context => `${context.parsed.y}°Celsius`
            }
          }
        }
      }
    });
    this.charts.set(id, chart);
  }

  /**
   * Create discrete chart (for .sparkdisc elements)
   */
  createDiscreteChart(element, data, id) {
    let canvas = element.querySelector('canvas');
    if (!canvas) {
      canvas = document.createElement('canvas');
      canvas.width = 100;
      canvas.height = 20;
      canvas.style.width = '100px';
      canvas.style.height = '20px';
      element.appendChild(canvas);
    }
    const ctx = canvas.getContext('2d');
    const chart = new dist_chart/* Chart */.t1(ctx, {
      type: 'scatter',
      data: {
        datasets: [{
          data: data.map((val, index) => ({
            x: index,
            y: val
          })),
          backgroundColor: '#9f0',
          borderColor: '#9f0',
          pointRadius: 2,
          showLine: false
        }]
      },
      options: {
        responsive: false,
        maintainAspectRatio: false,
        scales: {
          x: {
            display: false
          },
          y: {
            display: false
          }
        },
        plugins: {
          legend: {
            display: false
          },
          tooltip: {
            enabled: true,
            callbacks: {
              label: context => `${context.parsed.y}°Celsius`
            }
          }
        }
      }
    });
    this.charts.set(id, chart);
  }

  /**
   * Create bullet chart (for .sparkbull elements)
   */
  createBulletChart(element, data, id) {
    let canvas = element.querySelector('canvas');
    if (!canvas) {
      canvas = document.createElement('canvas');
      canvas.width = 100;
      canvas.height = 20;
      canvas.style.width = '100px';
      canvas.style.height = '20px';
      element.appendChild(canvas);
    }
    const ctx = canvas.getContext('2d');

    // Simplified bullet chart as horizontal bar
    const chart = new dist_chart/* Chart */.t1(ctx, {
      type: 'bar',
      data: {
        labels: [''],
        datasets: [{
          data: [Math.max(...data)],
          backgroundColor: COLORS['amber-500'],
          borderColor: COLORS['amber-500'],
          borderWidth: 1,
          barPercentage: 0.6
        }]
      },
      options: {
        responsive: false,
        maintainAspectRatio: false,
        indexAxis: 'y',
        scales: {
          x: {
            display: false
          },
          y: {
            display: false
          }
        },
        plugins: {
          legend: {
            display: false
          },
          tooltip: {
            enabled: true,
            callbacks: {
              label: context => `${context.parsed.x}°Celsius`
            }
          }
        }
      }
    });
    this.charts.set(id, chart);
  }

  /**
   * Create box chart (for .sparkbox elements) 
   */
  createBoxChart(element, data, id) {
    let canvas = element.querySelector('canvas');
    if (!canvas) {
      canvas = document.createElement('canvas');
      canvas.width = 100;
      canvas.height = 20;
      canvas.style.width = '100px';
      canvas.style.height = '20px';
      element.appendChild(canvas);
    }
    const ctx = canvas.getContext('2d');

    // Box plot simplified as bar chart showing quartiles
    const sortedData = [...data].sort((a, b) => a - b);
    const q1 = sortedData[Math.floor(sortedData.length * 0.25)];
    const median = sortedData[Math.floor(sortedData.length * 0.5)];
    const q3 = sortedData[Math.floor(sortedData.length * 0.75)];
    const chart = new dist_chart/* Chart */.t1(ctx, {
      type: 'bar',
      data: {
        labels: ['Q1', 'Med', 'Q3'],
        datasets: [{
          data: [q1, median, q3],
          backgroundColor: '#9f0',
          borderColor: '#9f0',
          borderWidth: 1,
          barPercentage: 0.8
        }]
      },
      options: {
        responsive: false,
        maintainAspectRatio: false,
        scales: {
          x: {
            display: false
          },
          y: {
            display: false
          }
        },
        plugins: {
          legend: {
            display: false
          },
          tooltip: {
            enabled: true,
            callbacks: {
              label: context => `${context.parsed.y}°Celsius`
            }
          }
        }
      }
    });
    this.charts.set(id, chart);
  }

  /**
   * Create Easy Pie Charts (replaces jQuery Easy Pie Chart)
   */
  createEasyPieCharts() {
    const easyPieElements = document.querySelectorAll('.easy-pie-chart');
    easyPieElements.forEach((element, index) => {
      const size = parseInt(element.dataset.size) || 80;
      const percent = parseInt(element.dataset.percent) || 0;
      const barColor = element.dataset.barColor || '#f44336';

      // Create canvas for the pie chart
      let canvas = element.querySelector('canvas');
      if (!canvas) {
        canvas = document.createElement('canvas');
        canvas.width = size;
        canvas.height = size;
        canvas.style.width = `${size}px`;
        canvas.style.height = `${size}px`;
        element.appendChild(canvas);
      }

      // Create percentage display
      const percentDisplay = element.querySelector('span');
      if (percentDisplay) {
        percentDisplay.textContent = `${percent}%`;
        percentDisplay.style.position = 'absolute';
        percentDisplay.style.top = '50%';
        percentDisplay.style.left = '50%';
        percentDisplay.style.transform = 'translate(-50%, -50%)';
        percentDisplay.style.fontSize = '14px';
        percentDisplay.style.fontWeight = 'bold';
      }

      // Set element position to relative for absolute positioning of text
      element.style.position = 'relative';
      element.style.display = 'inline-block';
      const ctx = canvas.getContext('2d');
      const chart = new dist_chart/* Chart */.t1(ctx, {
        type: 'doughnut',
        data: {
          datasets: [{
            data: [percent, 100 - percent],
            backgroundColor: [barColor, '#f0f0f0'],
            borderWidth: 0,
            cutout: '70%'
          }]
        },
        options: {
          responsive: false,
          maintainAspectRatio: false,
          plugins: {
            legend: {
              display: false
            },
            tooltip: {
              enabled: false
            }
          }
        }
      });
      this.charts.set(`easy-pie-${index}`, chart);
    });
  }

  /**
   * Destroy all charts
   */
  destroy() {
    this.charts.forEach(chart => {
      chart.destroy();
    });
    this.charts.clear();
    if (this.debounceTimer) {
      clearTimeout(this.debounceTimer);
    }
  }
}
/* harmony default export */ const components_Chart = (ChartComponent);
// EXTERNAL MODULE: ../../node_modules/@fullcalendar/core/index.js
var core = __webpack_require__(932);
// EXTERNAL MODULE: ../../node_modules/@fullcalendar/interaction/index.js
var interaction = __webpack_require__(453);
// EXTERNAL MODULE: ../../node_modules/@fullcalendar/daygrid/index.js
var daygrid = __webpack_require__(699);
// EXTERNAL MODULE: ../../node_modules/@fullcalendar/timegrid/index.js + 1 modules
var timegrid = __webpack_require__(747);
// EXTERNAL MODULE: ../../node_modules/@fullcalendar/list/index.js + 1 modules
var list = __webpack_require__(408);
;// ../assets/scripts/fullcalendar/index.js






document.addEventListener('DOMContentLoaded', function () {
  const calendarEl = document.getElementById('calendar');

  // element found in dom ?
  if (calendarEl == null) {
    return;
  }
  const calendar = new core/* Calendar */.Vv(calendarEl, {
    plugins: [interaction/* default */.Ay, daygrid/* default */.A, timegrid/* default */.A, list/* default */.A],
    headerToolbar: {
      left: 'prev,next today',
      center: 'title',
      right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
    },
    initialDate: date.format(date.now(), 'YYYY-MM-DD'),
    navLinks: true,
    // can click day/week names to navigate views
    editable: true,
    dayMaxEvents: true,
    // allow "more" link when too many events
    events: [{
      title: 'All Day Event',
      start: date.format(date.now(), 'YYYY-MM-DD')
    }, {
      title: 'Long Event',
      start: date.format(date.add(date.now(), 1, 'day'), 'YYYY-MM-DD'),
      end: date.format(date.add(date.now(), 4, 'day'), 'YYYY-MM-DD')
    }, {
      groupId: 999,
      title: 'Repeating Event',
      start: date.format(date.add(date.now(), 2, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T16:00')
    }, {
      groupId: 999,
      title: 'Repeating Event',
      start: date.format(date.add(date.now(), 9, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T16:00')
    }, {
      title: 'Conference',
      start: date.format(date.add(date.now(), 5, 'day'), 'YYYY-MM-DD'),
      end: date.format(date.add(date.now(), 7, 'day'), 'YYYY-MM-DD')
    }, {
      title: 'Meeting',
      start: date.format(date.add(date.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T10:30'),
      end: date.format(date.add(date.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T12:30')
    }, {
      title: 'Lunch',
      start: date.format(date.add(date.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T12:00')
    }, {
      title: 'Meeting',
      start: date.format(date.add(date.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T14:30')
    }, {
      title: 'Happy Hour',
      start: date.format(date.add(date.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T17:30')
    }, {
      title: 'Dinner',
      start: date.format(date.add(date.now(), 3, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T20:00')
    }, {
      title: 'Birthday Party',
      start: date.format(date.add(date.now(), 4, 'day'), 'YYYY-MM-DDTHH:mm:ss').replace(/:\d{2}$/, ':00:00').replace(/T\d{2}:\d{2}/, 'T07:00')
    }, {
      title: 'Click for Google',
      url: 'http://google.com/',
      start: date.format(date.add(date.now(), 14, 'day'), 'YYYY-MM-DD')
    }]
  });
  calendar.render();
});
// EXTERNAL MODULE: ../../node_modules/masonry-layout/masonry.js
var masonry = __webpack_require__(201);
var masonry_default = /*#__PURE__*/__webpack_require__.n(masonry);
;// ../assets/scripts/masonry/index.js

/* harmony default export */ const scripts_masonry = ((function () {
  window.addEventListener('load', () => {
    const masonryElement = document.querySelector('.masonry');
    if (masonryElement) {
      new (masonry_default())(masonryElement, {
        itemSelector: '.masonry-item',
        columnWidth: '.masonry-sizer',
        percentPosition: true
      });
    }
  });
})());
;// ../assets/scripts/popover/index.js
// Simple vanilla JS tooltip and popover implementation
/* harmony default export */ const popover = ((function () {
  // Simple tooltip implementation
  function initTooltips() {
    const tooltipElements = document.querySelectorAll('[data-bs-toggle="tooltip"]');
    tooltipElements.forEach(element => {
      const tooltipText = element.getAttribute('data-bs-title') || element.getAttribute('title');
      if (tooltipText) {
        element.addEventListener('mouseenter', function () {
          const tooltip = document.createElement('div');
          tooltip.className = 'custom-tooltip';
          tooltip.textContent = tooltipText;
          tooltip.style.cssText = `
            position: absolute;
            background: #000;
            color: #fff;
            padding: 4px 8px;
            border-radius: 4px;
            font-size: 12px;
            z-index: 1050;
            pointer-events: none;
            white-space: nowrap;
          `;
          document.body.appendChild(tooltip);
          const rect = element.getBoundingClientRect();
          tooltip.style.left = `${rect.left + rect.width / 2 - tooltip.offsetWidth / 2}px`;
          tooltip.style.top = `${rect.top - tooltip.offsetHeight - 5}px`;
          element._tooltip = tooltip;
        });
        element.addEventListener('mouseleave', function () {
          if (element._tooltip) {
            element._tooltip.remove();
            element._tooltip = null;
          }
        });
      }
    });
  }

  // Simple popover implementation
  function initPopovers() {
    const popoverElements = document.querySelectorAll('[data-bs-toggle="popover"]');
    popoverElements.forEach(element => {
      const popoverContent = element.getAttribute('data-bs-content');
      const popoverTitle = element.getAttribute('data-bs-title');
      if (popoverContent) {
        element.addEventListener('click', function (e) {
          e.preventDefault();

          // Remove existing popover
          if (element._popover) {
            element._popover.remove();
            element._popover = null;
            return;
          }
          const popover = document.createElement('div');
          popover.className = 'custom-popover';
          popover.innerHTML = `
            ${popoverTitle ? `<div class="popover-title">${popoverTitle}</div>` : ''}
            <div class="popover-content">${popoverContent}</div>
          `;
          popover.style.cssText = `
            position: absolute;
            background: #fff;
            border: 1px solid #ccc;
            border-radius: 6px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.15);
            z-index: 1050;
            min-width: 200px;
            max-width: 300px;
          `;
          document.body.appendChild(popover);
          const rect = element.getBoundingClientRect();
          popover.style.left = `${rect.left}px`;
          popover.style.top = `${rect.bottom + 5}px`;
          element._popover = popover;
        });
      }
    });
  }

  // Initialize both
  initTooltips();
  initPopovers();

  // Close popovers when clicking outside
  document.addEventListener('click', function (e) {
    const popovers = document.querySelectorAll('.custom-popover');
    popovers.forEach(popover => {
      if (!popover.contains(e.target)) {
        popover.remove();
      }
    });
  });
})());
// EXTERNAL MODULE: ../../node_modules/perfect-scrollbar/dist/perfect-scrollbar.esm.js
var perfect_scrollbar_esm = __webpack_require__(530);
;// ../assets/scripts/scrollbar/index.js

/* harmony default export */ const scrollbar = ((function () {
  const scrollables = document.querySelectorAll('.scrollable');
  if (scrollables.length > 0) {
    scrollables.forEach(el => {
      new perfect_scrollbar_esm/* default */.A(el);
    });
  }
})());
;// ../assets/scripts/search/index.js
/* harmony default export */ const search = ((function () {
  const searchToggle = document.querySelector('.search-toggle');
  const searchBox = document.querySelector('.search-box');
  const searchInput = document.querySelector('.search-input');
  const searchInputField = document.querySelector('.search-input input');
  if (searchToggle && searchBox && searchInput && searchInputField) {
    searchToggle.addEventListener('click', e => {
      searchBox.classList.toggle('active');
      searchInput.classList.toggle('active');
      searchInputField.focus();
      e.preventDefault();
    });
  }
})());
// EXTERNAL MODULE: ../../node_modules/skycons/skycons.js
var skycons = __webpack_require__(658);
var skycons_default = /*#__PURE__*/__webpack_require__.n(skycons);
;// ../assets/scripts/skycons/index.js


const Skycons = skycons_default()(window);
/* harmony default export */ const scripts_skycons = ((function () {
  let icons;
  const initSkycons = () => {
    const skyconsColor = theme.getCSSVar('--skycons-color');
    if (icons) {
      icons.pause();
      icons.remove('all');
    }
    icons = new Skycons({
      'color': skyconsColor
    });
    const list = ['clear-day', 'clear-night', 'partly-cloudy-day', 'partly-cloudy-night', 'cloudy', 'rain', 'sleet', 'snow', 'wind', 'fog'];
    let i = list.length;
    while (i--) {
      const weatherType = list[i],
        elements = document.getElementsByClassName(weatherType);
      let j = elements.length;
      while (j--) {
        icons.set(elements[j], weatherType);
      }
    }
    icons.play();
  };

  // Initialize skycons
  initSkycons();

  // Listen for theme changes
  window.addEventListener('adminator:themeChanged', initSkycons);
})());
// EXTERNAL MODULE: ../../node_modules/jsvectormap/dist/jsvectormap.esm.js
var jsvectormap_esm = __webpack_require__(82);
// EXTERNAL MODULE: ../../node_modules/jsvectormap/dist/maps/world.js
var world = __webpack_require__(177);
;// ../assets/scripts/utils/storage.js
/**
 * Adminator Storage Utilities
 * Safe localStorage wrapper with error handling
 *
 * @module utils/storage
 */

/**
 * Check if localStorage is available
 * @returns {boolean}
 */
const isAvailable = () => {
  try {
    const test = '__storage_test__';
    localStorage.setItem(test, test);
    localStorage.removeItem(test);
    return true;
  } catch {
    return false;
  }
};

/**
 * In-memory fallback when localStorage is unavailable
 * @type {Map<string, string>}
 */
const memoryStorage = new Map();

/**
 * Storage utility with safe localStorage access
 * Falls back to in-memory storage when localStorage is unavailable
 * (e.g., private browsing, storage quota exceeded)
 *
 * @namespace
 */
const storage_Storage = {
  /**
   * Check if storage is available
   * @returns {boolean}
   */
  isAvailable,
  /**
   * Get an item from storage
   *
   * @param {string} key - Storage key
   * @returns {string|null} Stored value or null
   *
   * @example
   * const theme = Storage.get('theme');
   */
  get(key) {
    try {
      if (isAvailable()) {
        return localStorage.getItem(key);
      }
      return memoryStorage.get(key) ?? null;
    } catch {
      return memoryStorage.get(key) ?? null;
    }
  },
  /**
   * Set an item in storage
   *
   * @param {string} key - Storage key
   * @param {string} value - Value to store
   * @returns {boolean} Success status
   *
   * @example
   * Storage.set('theme', 'dark');
   */
  set(key, value) {
    try {
      if (isAvailable()) {
        localStorage.setItem(key, value);
        return true;
      }
      memoryStorage.set(key, value);
      return true;
    } catch {
      // Fallback to memory storage
      memoryStorage.set(key, value);
      return true;
    }
  },
  /**
   * Remove an item from storage
   *
   * @param {string} key - Storage key
   * @returns {boolean} Success status
   *
   * @example
   * Storage.remove('theme');
   */
  remove(key) {
    try {
      if (isAvailable()) {
        localStorage.removeItem(key);
      }
      memoryStorage.delete(key);
      return true;
    } catch {
      memoryStorage.delete(key);
      return true;
    }
  },
  /**
   * Clear all storage
   *
   * @returns {boolean} Success status
   *
   * @example
   * Storage.clear();
   */
  clear() {
    try {
      if (isAvailable()) {
        localStorage.clear();
      }
      memoryStorage.clear();
      return true;
    } catch {
      memoryStorage.clear();
      return true;
    }
  },
  /**
   * Get a JSON object from storage
   *
   * @param {string} key - Storage key
   * @param {*} [defaultValue=null] - Default value if key doesn't exist or parse fails
   * @returns {*} Parsed object or default value
   *
   * @example
   * const settings = Storage.getJSON('settings', { theme: 'light' });
   */
  getJSON(key) {
    let defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
    try {
      const value = this.get(key);
      if (value === null) {
        return defaultValue;
      }
      return JSON.parse(value);
    } catch {
      return defaultValue;
    }
  },
  /**
   * Set a JSON object in storage
   *
   * @param {string} key - Storage key
   * @param {*} value - Value to store (will be JSON stringified)
   * @returns {boolean} Success status
   *
   * @example
   * Storage.setJSON('settings', { theme: 'dark', sidebar: 'expanded' });
   */
  setJSON(key, value) {
    try {
      return this.set(key, JSON.stringify(value));
    } catch {
      return false;
    }
  },
  /**
   * Check if a key exists in storage
   *
   * @param {string} key - Storage key
   * @returns {boolean}
   *
   * @example
   * if (Storage.has('theme')) {
   *   // Use stored theme
   * }
   */
  has(key) {
    return this.get(key) !== null;
  },
  /**
   * Get all keys in storage
   *
   * @returns {string[]} Array of keys
   *
   * @example
   * const keys = Storage.keys();
   */
  keys() {
    try {
      if (isAvailable()) {
        return Object.keys(localStorage);
      }
      return Array.from(memoryStorage.keys());
    } catch {
      return Array.from(memoryStorage.keys());
    }
  },
  /**
   * Get storage size in bytes (approximate)
   *
   * @returns {number} Size in bytes
   *
   * @example
   * console.log(`Storage used: ${Storage.size()} bytes`);
   */
  size() {
    try {
      let total = 0;
      const keys = this.keys();
      for (const key of keys) {
        const value = this.get(key);
        if (value) {
          total += key.length + value.length;
        }
      }
      return total * 2; // UTF-16 uses 2 bytes per character
    } catch {
      return 0;
    }
  }
};
/* harmony default export */ const storage = ((/* unused pure expression or super */ null && (storage_Storage)));
;// ../assets/scripts/utils/sanitize.js
/**
 * Adminator Sanitization Utilities
 * HTML and input sanitization for security
 *
 * @module utils/sanitize
 */

/**
 * HTML entities map for encoding
 * @type {Object<string, string>}
 */
const HTML_ENTITIES = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#x27;',
  '/': '&#x2F;',
  '`': '&#x60;',
  '=': '&#x3D;'
};

/**
 * Sanitization utilities namespace
 * @namespace
 */
const Sanitize = {
  /**
   * Escape HTML entities to prevent XSS
   *
   * @param {string} str - String to escape
   * @returns {string} Escaped string safe for HTML insertion
   *
   * @example
   * const safe = Sanitize.html('<script>alert("xss")</script>');
   * // Returns: &lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;
   */
  html(str) {
    if (typeof str !== 'string') {
      return String(str ?? '');
    }
    return str.replace(/[&<>"'`=/]/g, char => HTML_ENTITIES[char]);
  },
  /**
   * Escape string for use in HTML attributes
   *
   * @param {string} str - String to escape
   * @returns {string} Escaped string safe for attribute values
   *
   * @example
   * element.setAttribute('data-name', Sanitize.attr(userInput));
   */
  attr(str) {
    return this.html(str);
  },
  /**
   * Sanitize URL to prevent javascript: and data: URLs
   *
   * @param {string} url - URL to sanitize
   * @param {string[]} [allowedProtocols=['http:', 'https:', 'mailto:', 'tel:']] - Allowed protocols
   * @returns {string} Sanitized URL or empty string if invalid
   *
   * @example
   * const safeUrl = Sanitize.url(userProvidedUrl);
   * if (safeUrl) {
   *   window.location.href = safeUrl;
   * }
   */
  url(url) {
    let allowedProtocols = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['http:', 'https:', 'mailto:', 'tel:'];
    if (typeof url !== 'string') {
      return '';
    }

    // Trim and normalize
    const trimmed = url.trim().toLowerCase();

    // Block dangerous protocols
    const dangerousProtocols = ['javascript:', 'data:', 'vbscript:'];
    for (const protocol of dangerousProtocols) {
      if (trimmed.startsWith(protocol)) {
        return '';
      }
    }

    // Check for allowed protocols
    try {
      const parsed = new URL(url, window.location.origin);
      if (!allowedProtocols.includes(parsed.protocol)) {
        // Allow relative URLs
        if (!url.startsWith('/') && !url.startsWith('./') && !url.startsWith('../')) {
          return '';
        }
      }
      return url;
    } catch {
      // If URL parsing fails, check if it's a relative URL
      if (url.startsWith('/') || url.startsWith('./') || url.startsWith('../') || url.startsWith('#')) {
        return url;
      }
      return '';
    }
  },
  /**
   * Strip HTML tags from a string
   *
   * @param {string} str - String with HTML
   * @returns {string} String with HTML tags removed
   *
   * @example
   * const text = Sanitize.stripTags('<p>Hello <b>World</b></p>');
   * // Returns: 'Hello World'
   */
  stripTags(str) {
    if (typeof str !== 'string') {
      return String(str ?? '');
    }

    // Create a temporary element to leverage browser's HTML parser
    const div = document.createElement('div');
    div.innerHTML = str;
    return div.textContent || div.innerText || '';
  },
  /**
   * Sanitize a string for use in CSS
   *
   * @param {string} str - String to sanitize
   * @returns {string} CSS-safe string
   *
   * @example
   * element.style.setProperty('--custom', Sanitize.css(userInput));
   */
  css(str) {
    if (typeof str !== 'string') {
      return '';
    }

    // Remove potentially dangerous CSS values
    return str.replace(/expression\s*\(/gi, '').replace(/url\s*\(/gi, '').replace(/javascript:/gi, '').replace(/[<>"']/g, '');
  },
  /**
   * Sanitize a string for use in a filename
   *
   * @param {string} str - String to sanitize
   * @returns {string} Filename-safe string
   *
   * @example
   * const filename = Sanitize.filename(userInput) + '.txt';
   */
  filename(str) {
    if (typeof str !== 'string') {
      return '';
    }
    return str.replace(/[/\\?%*:|"<>]/g, '-') // Replace dangerous characters
    .replace(/\.\./g, '-') // Prevent directory traversal
    .replace(/^\./, '_') // Don't start with dot
    .slice(0, 255); // Limit length
  },
  /**
   * Create safe innerHTML by escaping interpolated values
   *
   * @param {TemplateStringsArray} strings - Template literal strings
   * @param {...*} values - Values to interpolate
   * @returns {string} HTML string with escaped values
   *
   * @example
   * element.innerHTML = Sanitize.template`<div>${userInput}</div>`;
   */
  template(strings) {
    for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
      values[_key - 1] = arguments[_key];
    }
    return strings.reduce((result, str, i) => {
      const value = values[i - 1];
      const escaped = value !== undefined ? this.html(String(value)) : '';
      return result + escaped + str;
    });
  },
  /**
   * Validate and sanitize an email address
   *
   * @param {string} email - Email to validate
   * @returns {string} Sanitized email or empty string if invalid
   *
   * @example
   * const email = Sanitize.email(userInput);
   * if (email) {
   *   sendEmail(email);
   * }
   */
  email(email) {
    if (typeof email !== 'string') {
      return '';
    }
    const trimmed = email.trim().toLowerCase();

    // Basic email validation
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(trimmed)) {
      return '';
    }

    // Additional checks
    if (trimmed.length > 254) {
      return '';
    }
    return trimmed;
  },
  /**
   * Sanitize a number input
   *
   * @param {*} value - Value to sanitize
   * @param {Object} [options={}] - Options
   * @param {number} [options.min=-Infinity] - Minimum value
   * @param {number} [options.max=Infinity] - Maximum value
   * @param {number} [options.default=0] - Default if invalid
   * @returns {number} Sanitized number
   *
   * @example
   * const age = Sanitize.number(userInput, { min: 0, max: 120, default: 18 });
   */
  number(value) {
    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    const {
      min = -Infinity,
      max = Infinity,
      default: defaultValue = 0
    } = options;
    const num = parseFloat(value);
    if (isNaN(num) || !isFinite(num)) {
      return defaultValue;
    }
    return Math.max(min, Math.min(max, num));
  },
  /**
   * Sanitize an integer input
   *
   * @param {*} value - Value to sanitize
   * @param {Object} [options={}] - Options
   * @param {number} [options.min=-Infinity] - Minimum value
   * @param {number} [options.max=Infinity] - Maximum value
   * @param {number} [options.default=0] - Default if invalid
   * @returns {number} Sanitized integer
   *
   * @example
   * const count = Sanitize.integer(userInput, { min: 1, max: 100 });
   */
  integer(value) {
    let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    return Math.floor(this.number(value, options));
  }
};
/* harmony default export */ const sanitize = ((/* unused pure expression or super */ null && (Sanitize)));
;// ../assets/scripts/utils/index.js
/**
 * Adminator Utilities Index
 * Re-exports all utility modules for convenient importing
 *
 * @module utils
 */

// Re-export all utilities









// Legacy initialization code
/* harmony default export */ const utils = ((function () {
  // ------------------------------------------------------
  // @Window Resize
  // ------------------------------------------------------

  /**
   * NOTE: Register resize event for Masonry layout
   */
  const EVENT = document.createEvent('UIEvents');
  window.EVENT = EVENT;
  EVENT.initUIEvent('resize', true, false, window, 0);
  window.addEventListener('load', () => {
    /**
     * Trigger window resize event after page load
     * for recalculation of masonry layout.
     */
    window.dispatchEvent(EVENT);
  });

  // ------------------------------------------------------
  // @External Links
  // ------------------------------------------------------

  // Open external links in new window
  const externalLinks = document.querySelectorAll('a[href^="http"], a[href^="//"]');
  externalLinks.forEach(link => {
    const href = link.getAttribute('href');
    if (href && !href.includes(window.location.host)) {
      link.setAttribute('rel', 'noopener noreferrer');
      link.setAttribute('target', '_blank');
    }
  });

  // ------------------------------------------------------
  // @Resize Trigger
  // ------------------------------------------------------

  // Trigger resize on any element click
  document.addEventListener('click', () => {
    window.dispatchEvent(window.EVENT);
  });
})());
;// ../assets/scripts/vectorMaps/index.js





/* harmony default export */ const vectorMaps = ((function () {
  // Store map instance for cleanup
  let mapInstance = null;

  // Main initialization function
  const vectorMapInit = () => {
    const worldMapContainer = document.getElementById('world-map-marker');
    if (!worldMapContainer) return;

    // Remove existing map
    const existingMap = document.getElementById('vmap');
    if (existingMap) {
      existingMap.remove();
    }

    // Destroy existing map instance
    if (mapInstance) {
      try {
        mapInstance.destroy();
      } catch {
        // Map instance cleanup
      }
      mapInstance = null;
    }

    // Get current theme colors - using template colors directly
    const isDark = theme.current() === 'dark';
    const colors = {
      backgroundColor: isDark ? '#313644' : '#f9fafb',
      regionColor: isDark ? '#565a5c' : '#e6eaf0',
      borderColor: isDark ? '#72777a' : '#d3d9e3',
      hoverColor: isDark ? '#7774e7' : '#0f9aee',
      selectedColor: isDark ? '#37c936' : '#7774e7',
      markerFill: isDark ? '#0f9aee' : '#7774e7',
      markerStroke: isDark ? '#37c936' : '#0f9aee',
      scaleStart: isDark ? '#b9c2d0' : '#e6eaf0',
      scaleEnd: isDark ? '#0f9aee' : '#007bff',
      textColor: isDark ? '#99abb4' : '#72777a'
    };

    // Create new map container
    const mapContainer = document.createElement('div');
    mapContainer.id = 'vmap';
    mapContainer.style.height = '490px';
    mapContainer.style.position = 'relative';
    mapContainer.style.overflow = 'hidden';
    mapContainer.style.backgroundColor = colors.backgroundColor;
    mapContainer.style.borderRadius = '8px';
    mapContainer.style.border = `1px solid ${colors.borderColor}`;
    worldMapContainer.appendChild(mapContainer);

    // Initialize JSVectorMap
    try {
      mapInstance = (0,jsvectormap_esm/* default */.A)({
        selector: '#vmap',
        map: 'world',
        // Styling options
        backgroundColor: 'transparent',
        // Region styling
        regionStyle: {
          initial: {
            fill: colors.regionColor,
            stroke: colors.borderColor,
            'stroke-width': 1,
            'stroke-opacity': 0.4
          },
          hover: {
            fill: colors.hoverColor,
            cursor: 'pointer'
          },
          selected: {
            fill: colors.selectedColor
          }
        },
        // Marker styling
        markerStyle: {
          initial: {
            r: 7,
            fill: colors.markerFill,
            stroke: colors.markerStroke,
            'stroke-width': 2,
            'stroke-opacity': 0.4
          },
          hover: {
            r: 10,
            fill: colors.hoverColor,
            'stroke-opacity': 0.8,
            cursor: 'pointer'
          }
        },
        // Markers data
        markers: [{
          name: 'INDIA : 350',
          coords: [21.00, 78.00]
        }, {
          name: 'Australia : 250',
          coords: [-33.00, 151.00]
        }, {
          name: 'USA : 250',
          coords: [36.77, -119.41]
        }, {
          name: 'UK : 250',
          coords: [55.37, -3.41]
        }, {
          name: 'UAE : 250',
          coords: [25.20, 55.27]
        }],
        // Simplified approach - remove series for now to test base colors
        // series: {
        //   regions: [
        //     {
        //       attribute: 'fill',
        //       scale: [colors.scaleStart, colors.scaleEnd],
        //       normalizeFunction: 'polynomial',
        //       values: {
        //         'US': 50,
        //         'SA': 30,
        //         'AU': 70,
        //         'IN': 40,
        //         'GB': 60,
        //         'LV': 80,
        //       },
        //     },
        //   ],
        // },

        // Interaction options
        zoomOnScroll: false,
        zoomButtons: false,
        // Event handlers
        onMarkerTooltipShow(event, tooltip, index) {
          // Safe access to marker data
          const marker = this.markers && this.markers[index];
          const markerName = marker ? marker.name : `Marker ${index + 1}`;
          tooltip.text(markerName);
        },
        onRegionTooltipShow(event, tooltip, code) {
          // Safe access to region data
          const regionName = this.mapData && this.mapData.paths && this.mapData.paths[code] ? this.mapData.paths[code].name || code : code;
          const value = this.series && this.series.regions && this.series.regions[0] && this.series.regions[0].values ? this.series.regions[0].values[code] : null;
          tooltip.text(`${regionName}${value ? `: ${value}` : ''}`);
        },
        onLoaded() {
          // Map loaded successfully
        }
      });

      // Store instance for theme updates
      worldMapContainer.mapInstance = mapInstance;
    } catch {
      // Error initializing JSVectorMap

      // Fallback: show a simple message
      mapContainer.innerHTML = `
        <div style="
          display: flex;
          align-items: center;
          justify-content: center;
          height: 100%;
          background: ${colors.backgroundColor};
          border: 1px solid ${colors.borderColor};
          border-radius: 8px;
          color: ${colors.textColor};
          font-size: 14px;
        ">
          <div style="text-align: center;">
            <div style="font-size: 24px; margin-bottom: 8px;">🗺️</div>
            <div>World Map</div>
            <div style="font-size: 12px; margin-top: 4px;">Interactive map will load here</div>
          </div>
        </div>
      `;
    }
  };

  // Theme update function
  const updateMapTheme = () => {
    if (mapInstance) {
      const isDark = theme.current() === 'dark';
      const colors = {
        backgroundColor: isDark ? '#313644' : '#f9fafb',
        regionColor: isDark ? '#565a5c' : '#e6eaf0',
        borderColor: isDark ? '#72777a' : '#d3d9e3',
        hoverColor: isDark ? '#7774e7' : '#0f9aee',
        selectedColor: isDark ? '#37c936' : '#7774e7',
        markerFill: isDark ? '#0f9aee' : '#7774e7',
        markerStroke: isDark ? '#37c936' : '#0f9aee',
        scaleStart: isDark ? '#b9c2d0' : '#e6eaf0',
        scaleEnd: isDark ? '#0f9aee' : '#007bff',
        textColor: isDark ? '#99abb4' : '#72777a'
      };
      try {
        // Update region styles - commented out series for now
        // mapInstance.updateSeries('regions', {
        //   attribute: 'fill',
        //   scale: [colors.scaleStart, colors.scaleEnd],
        //   values: {
        //     'US': 50,
        //     'SA': 30,
        //     'AU': 70,
        //     'IN': 40,
        //     'GB': 60,
        //     'LV': 80,
        //   },
        // });

        // Update container background
        const container = document.getElementById('vmap');
        if (container) {
          container.style.backgroundColor = colors.backgroundColor;
        }
      } catch {
        // Theme update failed, reinitializing map
        vectorMapInit();
      }
    } else {
      vectorMapInit();
    }
  };

  // Initialize map
  vectorMapInit();

  // Reinitialize on window resize
  window.addEventListener('resize', events.debounce(vectorMapInit, 300));

  // Listen for theme changes
  window.addEventListener('adminator:themeChanged', events.debounce(updateMapTheme, 150));

  // Cleanup on page unload
  window.addEventListener('beforeunload', () => {
    if (mapInstance) {
      try {
        mapInstance.destroy();
      } catch {
        // Map cleanup on unload
      }
      mapInstance = null;
    }
  });

  // Return public API
  return {
    init: vectorMapInit,
    updateTheme: updateMapTheme,
    getInstance: () => mapInstance
  };
})());
;// ../assets/scripts/chat/index.js
/* harmony default export */ const chat = ((function () {
  const chatSidebarToggle = document.getElementById('chat-sidebar-toggle');
  const chatSidebar = document.getElementById('chat-sidebar');
  if (chatSidebarToggle && chatSidebar) {
    chatSidebarToggle.addEventListener('click', e => {
      chatSidebar.classList.toggle('open');
      e.preventDefault();
    });
  }
})());
;// ../assets/scripts/email/index.js
/* harmony default export */ const email = ((function () {
  // Email side toggle functionality
  const emailSideToggle = document.querySelector('.email-side-toggle');
  const emailApp = document.querySelector('.email-app');
  if (emailSideToggle && emailApp) {
    emailSideToggle.addEventListener('click', e => {
      emailApp.classList.toggle('side-active');
      e.preventDefault();
    });
  }

  // Email list item and back to mailbox functionality
  const emailListItems = document.querySelectorAll('.email-list-item, .back-to-mailbox');
  const emailContent = document.querySelector('.email-content');
  if (emailListItems.length > 0 && emailContent) {
    emailListItems.forEach(item => {
      item.addEventListener('click', e => {
        emailContent.classList.toggle('open');
        e.preventDefault();
      });
    });
  }
})());
// EXTERNAL MODULE: ../../node_modules/load-google-maps-api/index.js
var load_google_maps_api = __webpack_require__(95);
var load_google_maps_api_default = /*#__PURE__*/__webpack_require__.n(load_google_maps_api);
;// ../assets/scripts/googleMaps/index.js


/* harmony default export */ const googleMaps = ((function () {
  let map, marker;
  const initGoogleMap = () => {
    const googleMapElement = document.getElementById('google-map');
    if (googleMapElement) {
      load_google_maps_api_default()({
        key: 'AIzaSyDW8td30_gj6sGXjiMU0ALeMu1SDEwUnEA'
      }).then(() => {
        const latitude = 26.8206;
        const longitude = 30.8025;
        const mapZoom = 5;
        const {
          google
        } = window;
        const mapOptions = {
          center: new google.maps.LatLng(latitude, longitude),
          zoom: mapZoom,
          mapTypeId: google.maps.MapTypeId.ROADMAP,
          styles: [{
            'featureType': 'landscape',
            'stylers': [{
              'hue': theme.getCSSVar('--gmap-landscape-hue')
            }, {
              'saturation': 43.400000000000006
            }, {
              'lightness': 37.599999999999994
            }, {
              'gamma': 1
            }]
          }, {
            'featureType': 'road.highway',
            'stylers': [{
              'hue': theme.getCSSVar('--gmap-highway-hue')
            }, {
              'saturation': -61.8
            }, {
              'lightness': 45.599999999999994
            }, {
              'gamma': 1
            }]
          }, {
            'featureType': 'road.arterial',
            'stylers': [{
              'hue': theme.getCSSVar('--gmap-road-hue')
            }, {
              'saturation': -100
            }, {
              'lightness': 51.19999999999999
            }, {
              'gamma': 1
            }]
          }, {
            'featureType': 'road.local',
            'stylers': [{
              'hue': theme.getCSSVar('--gmap-road-hue')
            }, {
              'saturation': -100
            }, {
              'lightness': 52
            }, {
              'gamma': 1
            }]
          }, {
            'featureType': 'water',
            'stylers': [{
              'hue': theme.getCSSVar('--gmap-water-hue')
            }, {
              'saturation': -13.200000000000003
            }, {
              'lightness': 2.4000000000000057
            }, {
              'gamma': 1
            }]
          }, {
            'featureType': 'poi',
            'stylers': [{
              'hue': theme.getCSSVar('--gmap-poi-hue')
            }, {
              'saturation': -1.0989010989011234
            }, {
              'lightness': 11.200000000000017
            }, {
              'gamma': 1
            }]
          }]
        };
        map = new google.maps.Map(document.getElementById('google-map'), mapOptions);
        if (marker) {
          marker.setMap(null);
        }
        marker = new google.maps.Marker({
          map,
          position: new google.maps.LatLng(latitude, longitude),
          visible: true
        });
      });
    }
  };

  // Initialize Google Maps
  initGoogleMap();

  // Listen for theme changes
  window.addEventListener('adminator:themeChanged', initGoogleMap);
})());
;// ../assets/scripts/ui/index.js
/**
 * UI Page Bootstrap Components
 * Vanilla JavaScript implementations for Bootstrap components
 */

/* harmony default export */ const ui = ((function () {
  // Modal functionality
  class VanillaModal {
    constructor(element) {
      this.element = element;
      this.modal = null;
      this.backdrop = null;
      this.isOpen = false;
      this.init();
    }
    init() {
      this.modal = document.querySelector(this.element.getAttribute('data-bs-target'));
      if (this.modal) {
        this.element.addEventListener('click', e => {
          e.preventDefault();
          this.show();
        });

        // Close button functionality
        const closeButtons = this.modal.querySelectorAll('[data-bs-dismiss="modal"]');
        closeButtons.forEach(btn => {
          btn.addEventListener('click', () => this.hide());
        });

        // Close on backdrop click
        this.modal.addEventListener('click', e => {
          if (e.target === this.modal) {
            this.hide();
          }
        });
      }
    }
    show() {
      if (this.isOpen) return;

      // Create backdrop
      this.backdrop = document.createElement('div');
      this.backdrop.className = 'modal-backdrop fade show';
      document.body.appendChild(this.backdrop);

      // Show modal
      this.modal.style.display = 'block';
      this.modal.classList.add('show');
      document.body.classList.add('modal-open');
      this.isOpen = true;

      // Focus the modal
      this.modal.setAttribute('tabindex', '-1');
      this.modal.focus();

      // Escape key handler
      this.escapeHandler = e => {
        if (e.key === 'Escape') {
          this.hide();
        }
      };
      document.addEventListener('keydown', this.escapeHandler);
    }
    hide() {
      if (!this.isOpen) return;

      // Hide modal
      this.modal.classList.remove('show');
      this.modal.style.display = 'none';
      document.body.classList.remove('modal-open');

      // Remove backdrop
      if (this.backdrop) {
        this.backdrop.remove();
        this.backdrop = null;
      }
      this.isOpen = false;

      // Remove escape handler
      if (this.escapeHandler) {
        document.removeEventListener('keydown', this.escapeHandler);
        this.escapeHandler = null;
      }
    }
  }

  // Dropdown functionality
  class VanillaDropdown {
    constructor(element) {
      this.element = element;
      this.menu = null;
      this.isOpen = false;
      this.init();
    }
    init() {
      this.menu = this.element.parentNode.querySelector('.dropdown-menu');
      if (this.menu) {
        this.element.addEventListener('click', e => {
          e.preventDefault();
          e.stopPropagation();
          this.toggle();
        });

        // Close on outside click
        document.addEventListener('click', e => {
          if (!this.element.parentNode.contains(e.target)) {
            this.hide();
          }
        });

        // Close on escape
        document.addEventListener('keydown', e => {
          if (e.key === 'Escape' && this.isOpen) {
            this.hide();
          }
        });
      }
    }
    toggle() {
      if (this.isOpen) {
        this.hide();
      } else {
        this.show();
      }
    }
    show() {
      if (this.isOpen) return;

      // Close other dropdowns
      document.querySelectorAll('.dropdown-menu.show').forEach(menu => {
        menu.classList.remove('show');
      });
      this.menu.classList.add('show');
      this.element.setAttribute('aria-expanded', 'true');
      this.isOpen = true;
    }
    hide() {
      if (!this.isOpen) return;
      this.menu.classList.remove('show');
      this.element.setAttribute('aria-expanded', 'false');
      this.isOpen = false;
    }
  }

  // Popover functionality
  class VanillaPopover {
    constructor(element) {
      this.element = element;
      this.popover = null;
      this.isOpen = false;
      this.init();
    }
    init() {
      this.element.addEventListener('click', e => {
        e.preventDefault();
        this.toggle();
      });

      // Close on outside click
      document.addEventListener('click', e => {
        if (!this.element.contains(e.target) && (!this.popover || !this.popover.contains(e.target))) {
          this.hide();
        }
      });
    }
    toggle() {
      if (this.isOpen) {
        this.hide();
      } else {
        this.show();
      }
    }
    show() {
      if (this.isOpen) return;

      // Close other popovers
      document.querySelectorAll('.popover').forEach(popover => {
        popover.remove();
      });
      const title = this.element.getAttribute('title') || this.element.getAttribute('data-bs-title');
      const content = this.element.getAttribute('data-bs-content');
      this.popover = document.createElement('div');
      this.popover.className = 'popover bs-popover-top show';
      this.popover.style.position = 'absolute';
      this.popover.style.zIndex = '1070';
      this.popover.style.maxWidth = '276px';
      this.popover.style.backgroundColor = '#fff';
      this.popover.style.border = '1px solid rgba(0,0,0,.2)';
      this.popover.style.borderRadius = '6px';
      this.popover.style.boxShadow = '0 5px 10px rgba(0,0,0,.2)';
      let popoverContent = '';
      if (title) {
        popoverContent += `<div class="popover-header" style="padding: 8px 14px; margin-bottom: 0; font-size: 14px; background-color: #f7f7f7; border-bottom: 1px solid #ebebeb; border-radius: 5px 5px 0 0; font-weight: 600;">${title}</div>`;
      }
      popoverContent += `<div class="popover-body" style="padding: 9px 14px; word-wrap: break-word;">${content}</div>`;
      this.popover.innerHTML = popoverContent;
      document.body.appendChild(this.popover);

      // Position popover
      const rect = this.element.getBoundingClientRect();
      this.popover.style.left = `${rect.left + rect.width / 2 - this.popover.offsetWidth / 2}px`;
      this.popover.style.top = `${rect.top - this.popover.offsetHeight - 10}px`;
      this.isOpen = true;
    }
    hide() {
      if (!this.isOpen) return;
      if (this.popover) {
        this.popover.remove();
        this.popover = null;
      }
      this.isOpen = false;
    }
  }

  // Tooltip functionality
  class VanillaTooltip {
    constructor(element) {
      this.element = element;
      this.tooltip = null;
      this.init();
    }
    init() {
      this.element.addEventListener('mouseenter', () => this.show());
      this.element.addEventListener('mouseleave', () => this.hide());
      this.element.addEventListener('focus', () => this.show());
      this.element.addEventListener('blur', () => this.hide());
    }
    show() {
      if (this.tooltip) return;
      const title = this.element.getAttribute('title') || this.element.getAttribute('data-bs-title');
      const placement = this.element.getAttribute('data-bs-placement') || 'top';
      if (!title) return;
      this.tooltip = document.createElement('div');
      this.tooltip.className = `tooltip bs-tooltip-${placement} show`;
      this.tooltip.style.position = 'absolute';
      this.tooltip.style.zIndex = '1070';
      this.tooltip.style.maxWidth = '200px';
      this.tooltip.style.padding = '4px 8px';
      this.tooltip.style.fontSize = '12px';
      this.tooltip.style.backgroundColor = '#000';
      this.tooltip.style.color = '#fff';
      this.tooltip.style.borderRadius = '4px';
      this.tooltip.style.pointerEvents = 'none';
      this.tooltip.style.whiteSpace = 'nowrap';
      this.tooltip.innerHTML = `<div class="tooltip-inner">${title}</div>`;
      document.body.appendChild(this.tooltip);

      // Position tooltip
      const rect = this.element.getBoundingClientRect();
      switch (placement) {
        case 'top':
          this.tooltip.style.left = `${rect.left + rect.width / 2 - this.tooltip.offsetWidth / 2}px`;
          this.tooltip.style.top = `${rect.top - this.tooltip.offsetHeight - 5}px`;
          break;
        case 'bottom':
          this.tooltip.style.left = `${rect.left + rect.width / 2 - this.tooltip.offsetWidth / 2}px`;
          this.tooltip.style.top = `${rect.bottom + 5}px`;
          break;
        case 'left':
          this.tooltip.style.left = `${rect.left - this.tooltip.offsetWidth - 5}px`;
          this.tooltip.style.top = `${rect.top + rect.height / 2 - this.tooltip.offsetHeight / 2}px`;
          break;
        case 'right':
          this.tooltip.style.left = `${rect.right + 5}px`;
          this.tooltip.style.top = `${rect.top + rect.height / 2 - this.tooltip.offsetHeight / 2}px`;
          break;
      }
    }
    hide() {
      if (this.tooltip) {
        this.tooltip.remove();
        this.tooltip = null;
      }
    }
  }

  // Accordion functionality
  class VanillaAccordion {
    constructor(element) {
      this.element = element;
      this.accordion = element.closest('.accordion');
      this.target = document.querySelector(element.getAttribute('data-bs-target'));
      this.isOpen = !element.classList.contains('collapsed');
      this.init();
    }
    init() {
      this.element.addEventListener('click', e => {
        e.preventDefault();
        this.toggle();
      });
    }
    toggle() {
      if (this.isOpen) {
        this.hide();
      } else {
        this.show();
      }
    }
    show() {
      if (this.isOpen) return;

      // Close other accordion items in the same parent
      const parentAccordion = this.accordion;
      if (parentAccordion) {
        const otherItems = parentAccordion.querySelectorAll('.accordion-collapse.show');
        otherItems.forEach(item => {
          if (item !== this.target) {
            item.classList.remove('show');
            const button = parentAccordion.querySelector(`[data-bs-target="#${item.id}"]`);
            if (button) {
              button.classList.add('collapsed');
              button.setAttribute('aria-expanded', 'false');
            }
          }
        });
      }

      // Show this item
      this.target.classList.add('show');
      this.element.classList.remove('collapsed');
      this.element.setAttribute('aria-expanded', 'true');
      this.isOpen = true;
    }
    hide() {
      if (!this.isOpen) return;
      this.target.classList.remove('show');
      this.element.classList.add('collapsed');
      this.element.setAttribute('aria-expanded', 'false');
      this.isOpen = false;
    }
  }

  // Initialize all components
  const initComponents = () => {
    // Initialize modals
    document.querySelectorAll('[data-bs-toggle="modal"]').forEach(element => {
      new VanillaModal(element);
    });

    // Initialize dropdowns
    document.querySelectorAll('[data-bs-toggle="dropdown"]').forEach(element => {
      new VanillaDropdown(element);
    });

    // Initialize popovers
    document.querySelectorAll('[data-bs-toggle="popover"]').forEach(element => {
      new VanillaPopover(element);
    });

    // Initialize tooltips
    document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(element => {
      new VanillaTooltip(element);
    });

    // Initialize accordions
    document.querySelectorAll('[data-bs-toggle="collapse"]').forEach(element => {
      new VanillaAccordion(element);
    });
  };

  // Initialize when DOM is ready
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initComponents);
  } else {
    initComponents();
  }

  // Public API
  return {
    init: initComponents,
    Modal: VanillaModal,
    Dropdown: VanillaDropdown,
    Popover: VanillaPopover,
    Tooltip: VanillaTooltip,
    Accordion: VanillaAccordion
  };
})());
;// ../assets/scripts/app.js
/**
 * Modern Adminator Application
 * Main application entry point with enhanced mobile support
 *
 * @module app
 * @version 2.9.0
 */

// Note: Bootstrap 5 CSS is still available via SCSS imports
// Bootstrap JS components removed to eliminate jQuery dependency









// Import styles


// Import other modules that don't need immediate modernization











class AdminatorApp {
  constructor() {
    this.components = new Map();
    this.isInitialized = false;
    this.themeManager = theme;
    this.cleanupFunctions = [];

    // Initialize when DOM is ready
    DOM.ready(() => {
      this.init();
    });
  }

  /**
   * Initialize the application
   */
  init() {
    if (this.isInitialized) return;
    logger.time('Adminator Init');
    try {
      // Initialize core components
      this.initSidebar();
      this.initCharts();
      this.initDataTables();
      this.initDatePickers();
      this.initTheme();
      this.initMobileEnhancements();

      // Setup global event listeners using event delegation
      this.setupGlobalEvents();
      this.isInitialized = true;
      logger.timeEnd('Adminator Init');
      logger.info('Application initialized successfully');

      // Dispatch custom event for other scripts
      events.emit(window, 'adminator:ready', {
        app: this
      });
    } catch (error) {
      logger.error('Error initializing Adminator App', error);
    }
  }

  /**
   * Initialize Sidebar component
   */
  initSidebar() {
    if (DOM.exists('.sidebar')) {
      const sidebar = new components_Sidebar();
      this.components.set('sidebar', sidebar);
    }
  }

  /**
   * Initialize Chart components
   */
  initCharts() {
    // Check if we have any chart elements
    const hasCharts = DOM.exists('#sparklinedash') || DOM.exists('.sparkline') || DOM.exists('.sparkbar') || DOM.exists('.sparktri') || DOM.exists('.sparkdisc') || DOM.exists('.sparkbull') || DOM.exists('.sparkbox') || DOM.exists('.easy-pie-chart') || DOM.exists('#line-chart') || DOM.exists('#area-chart') || DOM.exists('#scatter-chart') || DOM.exists('#bar-chart');
    if (hasCharts) {
      const charts = new components_Chart();
      this.components.set('charts', charts);
    }
  }

  /**
   * Initialize DataTables (modern approach)
   */
  initDataTables() {
    const dataTableElement = DOM.select('#dataTable');
    if (dataTableElement) {
      // For now, use a lightweight approach
      // In future iterations, we can replace with a modern table library
      this.initBasicDataTable(dataTableElement);
    }
  }

  /**
   * Basic DataTable implementation (placeholder for full modernization)
   */
  initBasicDataTable(table) {
    // Add basic sorting functionality
    const headers = DOM.selectAll('th', table);
    headers.forEach(header => {
      if (header.textContent.trim()) {
        header.style.cursor = 'pointer';
        header.style.userSelect = 'none';
        DOM.on(header, 'click', () => {
          // Basic sort functionality can be added here
          // For now, we'll keep the existing DataTables library
        });
      }
    });
  }

  /**
   * Initialize Date Pickers (modern approach with Day.js)
   */
  initDatePickers() {
    const startDatePickers = DOM.selectAll('.start-date');
    const endDatePickers = DOM.selectAll('.end-date');
    [...startDatePickers, ...endDatePickers].forEach(picker => {
      // Convert to HTML5 date input for better UX
      if (picker.type !== 'date') {
        picker.type = 'date';
        picker.classList.add('form-control');

        // Clear the placeholder since HTML5 date inputs don't need it
        picker.removeAttribute('placeholder');

        // Set default value to today if no value is set
        if (!picker.value) {
          picker.value = date.form.toInputValue(date.now());
        }

        // Make sure the input is clickable and focusable
        picker.style.pointerEvents = 'auto';
        picker.style.cursor = 'pointer';

        // Ensure proper styling for HTML5 date input
        picker.style.minHeight = '38px';
        picker.style.lineHeight = '1.5';

        // Date picker converted to HTML5 with Day.js support
      }
    });

    // Add enhanced interaction - handle both field and icon clicks
    [...startDatePickers, ...endDatePickers].forEach(picker => {
      // Handle direct field clicks
      DOM.on(picker, 'click', event => {
        event.target.focus();
        // For mobile browsers, trigger the date picker
        if (event.target.showPicker && typeof event.target.showPicker === 'function') {
          try {
            event.target.showPicker();
          } catch {
            // Fallback if showPicker is not supported
          }
        }
      });

      // Handle calendar icon clicks (find the icon in the input group)
      const inputGroup = picker.closest('.input-group');
      if (inputGroup) {
        const calendarIcon = inputGroup.querySelector('.input-group-text i.ti-calendar');
        if (calendarIcon) {
          DOM.on(calendarIcon, 'click', event => {
            event.preventDefault();
            event.stopPropagation();
            picker.focus();
            if (picker.showPicker && typeof picker.showPicker === 'function') {
              try {
                picker.showPicker();
              } catch {
                // Date picker opened via icon click
              }
            }
          });
        }
      }
    });
  }

  /**
   * Initialize theme system with toggle
   */
  initTheme() {
    // Initializing theme system

    // Initialize theme system first
    this.themeManager.init();

    // Inject theme toggle if missing - with retry mechanism
    setTimeout(() => {
      const navRight = DOM.select('.nav-right');
      // Check for nav-right and theme-toggle existence

      if (navRight && !DOM.exists('#theme-toggle')) {
        const li = document.createElement('li');
        li.className = 'theme-toggle d-flex ai-c';
        const currentTheme = this.themeManager.current();
        const isDark = currentTheme === 'dark';
        li.innerHTML = `
        <div class="form-check form-switch d-flex ai-c" style="margin: 0; padding: 0;" role="group" aria-label="Theme switcher">
          <label class="form-check-label me-2 text-nowrap c-grey-700" for="theme-toggle" style="font-size: 12px; margin-right: 8px;">
            <i class="ti-sun" aria-hidden="true" style="margin-right: 4px;"></i><span class="theme-label">Light</span>
          </label>
          <input class="form-check-input" type="checkbox" id="theme-toggle"
                 role="switch"
                 aria-checked="${isDark}"
                 aria-label="Toggle dark mode"
                 ${isDark ? 'checked' : ''}
                 style="margin: 0;">
          <label class="form-check-label ms-2 text-nowrap c-grey-700" for="theme-toggle" style="font-size: 12px; margin-left: 8px;">
            <span class="theme-label">Dark</span><i class="ti-moon" aria-hidden="true" style="margin-left: 4px;"></i>
          </label>
        </div>
      `;

        // Insert before user dropdown (last item) - safer approach
        const lastItem = navRight.querySelector('li:last-child');
        if (lastItem && lastItem.parentNode === navRight) {
          navRight.insertBefore(li, lastItem);
          // Theme toggle inserted before last item
        } else {
          navRight.appendChild(li);
          // Theme toggle appended to nav-right (safer approach)
        }

        // Add toggle functionality
        const toggle = DOM.select('#theme-toggle');
        if (toggle) {
          DOM.on(toggle, 'change', () => {
            const newTheme = toggle.checked ? 'dark' : 'light';
            toggle.setAttribute('aria-checked', toggle.checked ? 'true' : 'false');
            this.themeManager.apply(newTheme);
          });

          // Listen for theme changes from other sources
          window.addEventListener('adminator:themeChanged', event => {
            const isDark = event.detail.theme === 'dark';
            toggle.checked = isDark;
            toggle.setAttribute('aria-checked', isDark ? 'true' : 'false');

            // Update charts when theme changes
            const charts = this.components.get('charts');
            if (charts) charts.redrawCharts();
          });
        }
      } else {
        // No nav-right found or theme-toggle already exists
      }
    }, 100); // Wait 100ms for DOM to be fully ready
  }

  /**
   * Initialize mobile-specific enhancements
   */
  initMobileEnhancements() {
    // Initializing mobile enhancements
    this.enhanceMobileDropdowns();
    this.enhanceMobileSearch();

    // Prevent horizontal scroll on mobile
    if (this.isMobile()) {
      document.body.style.overflowX = 'hidden';
    }
  }

  /**
   * Setup global event listeners using event delegation for performance
   */
  setupGlobalEvents() {
    // Use event delegation for dropdown clicks (single listener instead of many)
    const dropdownCleanup = events.delegate(document, 'click', '.nav-right .dropdown-toggle', (e, toggle) => this.handleDropdownClick(e, toggle));
    this.cleanupFunctions.push(dropdownCleanup);

    // Global click handler for closing dropdowns/search
    const globalClickCleanup = events.on(document, 'click', event => {
      this.handleGlobalClick(event);
    });
    this.cleanupFunctions.push(globalClickCleanup);

    // Window resize handler with debouncing using Events utility
    const debouncedResize = events.debounce(() => this.handleResize(), 250);
    const resizeCleanup = events.on(window, 'resize', debouncedResize);
    this.cleanupFunctions.push(resizeCleanup);

    // Escape key handler using delegation
    const escapeCleanup = events.on(document, 'keydown', e => {
      if (e.key === 'Escape') {
        this.closeAllOverlays();
      }
    });
    this.cleanupFunctions.push(escapeCleanup);
    logger.debug('Global event listeners set up with delegation');
  }

  /**
   * Handle dropdown toggle clicks
   * @param {Event} e - Click event
   * @param {Element} toggle - The clicked toggle element
   */
  handleDropdownClick(e, toggle) {
    if (!this.isMobile()) return;
    e.preventDefault();
    e.stopPropagation();
    const dropdown = toggle.closest('.dropdown');
    const menu = dropdown === null || dropdown === void 0 ? void 0 : dropdown.querySelector('.dropdown-menu');
    if (!dropdown || !menu) return;

    // Close search if open
    this.closeSearch();

    // Close other dropdowns
    DOM.selectAll('.nav-right .dropdown').forEach(d => {
      if (d !== dropdown) {
        var _d$querySelector;
        d.classList.remove('show');
        (_d$querySelector = d.querySelector('.dropdown-menu')) === null || _d$querySelector === void 0 || _d$querySelector.classList.remove('show');
      }
    });

    // Toggle current dropdown
    const isOpen = dropdown.classList.contains('show');
    dropdown.classList.toggle('show', !isOpen);
    menu.classList.toggle('show', !isOpen);
    document.body.style.overflow = isOpen ? '' : 'hidden';
    document.body.classList.toggle('mobile-menu-open', !isOpen);
  }

  /**
   * Close all overlays (dropdowns, search)
   */
  closeAllOverlays() {
    // Close dropdowns
    DOM.selectAll('.nav-right .dropdown').forEach(dropdown => {
      var _dropdown$querySelect;
      dropdown.classList.remove('show');
      (_dropdown$querySelect = dropdown.querySelector('.dropdown-menu')) === null || _dropdown$querySelect === void 0 || _dropdown$querySelect.classList.remove('show');
    });

    // Close search
    this.closeSearch();
    document.body.style.overflow = '';
    document.body.classList.remove('mobile-menu-open');
  }

  /**
   * Close the search overlay
   */
  closeSearch() {
    const searchBox = DOM.select('.search-box');
    const searchInput = DOM.select('.search-input');
    if (searchBox && searchInput) {
      searchBox.classList.remove('active');
      searchInput.classList.remove('active');
      document.body.classList.remove('search-open');

      // Reset icon
      const searchIcon = searchBox.querySelector('i');
      if (searchIcon) {
        searchIcon.className = 'ti-search';
      }

      // Clear input
      const field = searchInput.querySelector('input');
      if (field) {
        field.value = '';
        field.blur();
      }
    }
  }

  /**
   * Handle window resize events
   */
  handleResize() {
    // Window resized, updating mobile features

    // Close all mobile-specific overlays when switching to desktop
    if (!this.isMobile()) {
      document.body.style.overflow = '';
      document.body.style.overflowX = '';

      // Close dropdowns
      const dropdowns = DOM.selectAll('.nav-right .dropdown');
      dropdowns.forEach(dropdown => {
        dropdown.classList.remove('show');
        const menu = dropdown.querySelector('.dropdown-menu');
        if (menu) menu.classList.remove('show');
      });

      // Close search
      const searchBox = DOM.select('.search-box');
      const searchInput = DOM.select('.search-input');
      if (searchBox && searchInput) {
        searchBox.classList.remove('active');
        searchInput.classList.remove('active');
      }
    } else {
      // Re-enable mobile overflow protection
      document.body.style.overflowX = 'hidden';
    }

    // Re-apply mobile enhancements
    this.enhanceMobileDropdowns();
    this.enhanceMobileSearch();
  }

  /**
   * Handle global click events
   */
  handleGlobalClick(event) {
    // Close mobile dropdowns when clicking outside
    if (!event.target.closest('.dropdown')) {
      const dropdowns = DOM.selectAll('.nav-right .dropdown');
      dropdowns.forEach(dropdown => {
        dropdown.classList.remove('show');
        const menu = dropdown.querySelector('.dropdown-menu');
        if (menu) menu.classList.remove('show');
      });
      document.body.style.overflow = '';
    }

    // Close search when clicking outside
    if (!event.target.closest('.search-box') && !event.target.closest('.search-input')) {
      const searchBox = DOM.select('.search-box');
      const searchInput = DOM.select('.search-input');
      if (searchBox && searchInput) {
        searchBox.classList.remove('active');
        searchInput.classList.remove('active');
        document.body.style.overflow = '';
        document.body.classList.remove('mobile-menu-open');
      }
    }
  }

  /**
   * Check if we're on a mobile device
   */
  isMobile() {
    return window.innerWidth <= 768;
  }

  /**
   * Enhanced mobile dropdown handling with improved email layout
   */
  enhanceMobileDropdowns() {
    if (!this.isMobile()) return;
    const dropdowns = DOM.selectAll('.nav-right .dropdown');
    dropdowns.forEach(dropdown => {
      const toggle = dropdown.querySelector('.dropdown-toggle');
      const menu = dropdown.querySelector('.dropdown-menu');
      if (toggle && menu) {
        // Remove existing listeners to prevent duplicates
        const newToggle = toggle.cloneNode(true);
        toggle.replaceWith(newToggle);

        // Add click functionality for mobile dropdowns
        DOM.on(newToggle, 'click', e => {
          e.preventDefault();
          e.stopPropagation();

          // Close search if open
          const searchBox = DOM.select('.search-box');
          const searchInput = DOM.select('.search-input');
          if (searchBox && searchInput) {
            searchBox.classList.remove('active');
            searchInput.classList.remove('active');
          }

          // Close other dropdowns first
          dropdowns.forEach(otherDropdown => {
            if (otherDropdown !== dropdown) {
              otherDropdown.classList.remove('show');
              const otherMenu = otherDropdown.querySelector('.dropdown-menu');
              if (otherMenu) otherMenu.classList.remove('show');
            }
          });

          // Toggle current dropdown
          const isOpen = dropdown.classList.contains('show');
          if (isOpen) {
            dropdown.classList.remove('show');
            menu.classList.remove('show');
            document.body.style.overflow = '';
            document.body.classList.remove('mobile-menu-open');
          } else {
            dropdown.classList.add('show');
            menu.classList.add('show');
            document.body.style.overflow = 'hidden';
            document.body.classList.add('mobile-menu-open');
          }
        });

        // Enhanced mobile close button functionality
        DOM.on(menu, 'click', e => {
          // Check if clicked on the close area (::before pseudo-element area)
          const rect = menu.getBoundingClientRect();
          const clickY = e.clientY - rect.top;

          // If clicked in top 50px (close button area)
          if (clickY <= 50) {
            dropdown.classList.remove('show');
            menu.classList.remove('show');
            document.body.style.overflow = '';
            document.body.classList.remove('mobile-menu-open');
            e.preventDefault();
            e.stopPropagation();
          }
        });
      }
    });

    // Close dropdowns on escape key
    DOM.on(document, 'keydown', e => {
      if (e.key === 'Escape') {
        dropdowns.forEach(dropdown => {
          dropdown.classList.remove('show');
          const menu = dropdown.querySelector('.dropdown-menu');
          if (menu) menu.classList.remove('show');
        });
        document.body.style.overflow = '';
        document.body.classList.remove('mobile-menu-open');
      }
    });
  }

  /**
     * Enhanced mobile search handling - Full-width search bar
     */
  enhanceMobileSearch() {
    const searchBox = DOM.select('.search-box');
    const searchInput = DOM.select('.search-input');
    if (searchBox && searchInput) {
      const searchToggle = searchBox.querySelector('a');
      const searchField = searchInput.querySelector('input');
      if (searchToggle && searchField) {
        // Setting up full-width search functionality

        // Remove existing listeners to prevent duplication
        const newSearchToggle = searchToggle.cloneNode(true);
        searchToggle.replaceWith(newSearchToggle);
        DOM.on(newSearchToggle, 'click', e => {
          e.preventDefault();
          e.stopPropagation();

          // Full-width search toggle clicked

          // Close any open dropdowns first
          const dropdowns = DOM.selectAll('.nav-right .dropdown');
          dropdowns.forEach(dropdown => {
            dropdown.classList.remove('show');
            const menu = dropdown.querySelector('.dropdown-menu');
            if (menu) menu.classList.remove('show');
          });

          // Toggle search state
          const isActive = searchInput.classList.contains('active');
          const searchIcon = newSearchToggle.querySelector('i');
          if (isActive) {
            // Close search
            searchInput.classList.remove('active');
            document.body.classList.remove('search-open');

            // Change icon back to search
            if (searchIcon) {
              searchIcon.className = 'ti-search';
            }

            // Clear input
            if (searchField) {
              searchField.value = '';
              searchField.blur();
            }

            // Full-width search closed
          } else {
            // Open search
            searchInput.classList.add('active');
            document.body.classList.add('search-open');

            // Change icon to close
            if (searchIcon) {
              searchIcon.className = 'ti-close';
            }

            // Focus the input after a short delay
            setTimeout(() => {
              if (searchField) {
                searchField.focus();
                // Search field focused
              }
            }, 100);

            // Full-width search opened
          }
        });

        // Close search on escape
        DOM.on(document, 'keydown', e => {
          if (e.key === 'Escape' && searchInput.classList.contains('active')) {
            searchInput.classList.remove('active');
            document.body.classList.remove('search-open');

            // Reset icon
            const searchIcon = newSearchToggle.querySelector('i');
            if (searchIcon) {
              searchIcon.className = 'ti-search';
            }

            // Clear input
            if (searchField) {
              searchField.value = '';
              searchField.blur();
            }

            // Full-width search closed via escape
          }
        });

        // Handle search input
        DOM.on(searchField, 'keypress', e => {
          if (e.key === 'Enter') {
            e.preventDefault();
            const query = searchField.value.trim();
            if (query) {
              // Search query submitted
              // Implement your search logic here

              // For demo, close search after "searching"
              searchInput.classList.remove('active');
              document.body.classList.remove('search-open');
              const searchIcon = newSearchToggle.querySelector('i');
              if (searchIcon) {
                searchIcon.className = 'ti-search';
              }
              searchField.value = '';
              searchField.blur();
            }
          }
        });

        // Full-width search functionality initialized
      }
    }
  }

  /**
   * Get a component by name
   */
  getComponent(name) {
    return this.components.get(name);
  }

  /**
   * Check if app is ready
   */
  isReady() {
    return this.isInitialized;
  }

  /**
   * Destroy the application and clean up all resources
   */
  destroy() {
    logger.info('Destroying Adminator App');

    // Clean up all event listeners
    this.cleanupFunctions.forEach(cleanup => {
      if (typeof cleanup === 'function') {
        cleanup();
      }
    });
    this.cleanupFunctions = [];

    // Destroy all components
    this.components.forEach((component, name) => {
      if (typeof component.destroy === 'function') {
        component.destroy();
        logger.debug(`Component destroyed: ${name}`);
      }
    });
    this.components.clear();

    // Cleanup performance observers
    utils_performance.cleanup();
    this.isInitialized = false;
    logger.info('Adminator App destroyed');
  }

  /**
   * Refresh/reinitialize the application
   */
  refresh() {
    logger.info('Refreshing Adminator App');
    if (this.isInitialized) {
      this.destroy();
    }
    setTimeout(() => {
      this.init();
    }, 100);
  }
}

// Initialize the application
const app = new AdminatorApp();

// Make app globally available for debugging
window.AdminatorApp = app;

// Export for module usage
/* harmony default export */ const scripts_app = ((/* unused pure expression or super */ null && (app)));
;// ../assets/scripts/datatable/index.js
// DataTable implementation

/* harmony default export */ const datatable = ((function () {
  // Vanilla JS DataTable implementation
  class VanillaDataTable {
    constructor(element) {
      let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      this.element = element;
      this.options = {
        sortable: true,
        searchable: true,
        pagination: true,
        pageSize: 10,
        ...options
      };
      this.originalData = [];
      this.filteredData = [];
      this.currentPage = 1;
      this.sortColumn = null;
      this.sortDirection = 'asc';
      this.init();
    }
    init() {
      this.extractData();
      this.createControls();
      this.applyStyles();
      this.bindEvents();
      this.render();
    }
    extractData() {
      const rows = this.element.querySelectorAll('tbody tr');
      this.originalData = Array.from(rows).map(row => {
        const cells = row.querySelectorAll('td');
        return Array.from(cells).map(cell => cell.textContent.trim());
      });
      this.filteredData = [...this.originalData];
    }
    createControls() {
      const wrapper = document.createElement('div');
      wrapper.className = 'datatable-wrapper';

      // Create search input
      if (this.options.searchable) {
        const searchWrapper = document.createElement('div');
        searchWrapper.className = 'datatable-search';
        searchWrapper.innerHTML = `
          <label>
            Search: 
            <input type="text" class="form-control" placeholder="Search...">
          </label>
        `;
        wrapper.appendChild(searchWrapper);
      }

      // Create pagination info
      if (this.options.pagination) {
        const infoWrapper = document.createElement('div');
        infoWrapper.className = 'datatable-info';
        wrapper.appendChild(infoWrapper);
      }

      // Wrap the table
      this.element.parentNode.insertBefore(wrapper, this.element);
      wrapper.appendChild(this.element);

      // Create pagination controls
      if (this.options.pagination) {
        const paginationWrapper = document.createElement('div');
        paginationWrapper.className = 'datatable-pagination';
        wrapper.appendChild(paginationWrapper);
      }
      this.wrapper = wrapper;
    }
    applyStyles() {
      // Apply Bootstrap-like styles
      this.element.classList.add('table', 'table-striped', 'table-bordered');

      // Add custom styles
      const style = document.createElement('style');
      style.textContent = `
        .datatable-wrapper {
          margin: 20px 0;
        }
        
        .datatable-search {
          margin-bottom: 15px;
        }
        
        .datatable-search input {
          width: 250px;
          display: inline-block;
          margin-left: 5px;
        }
        
        .datatable-info {
          margin-top: 15px;
          color: var(--c-text-muted, #6c757d);
          font-size: 14px;
        }
        
        .datatable-pagination {
          margin-top: 15px;
          display: flex;
          justify-content: center;
        }
        
        .datatable-pagination button {
          background: var(--c-bkg-card, #fff);
          border: 1px solid var(--c-border, #dee2e6);
          color: var(--c-text-base, #333);
          padding: 6px 12px;
          margin: 0 2px;
          cursor: pointer;
          border-radius: 4px;
        }
        
        .datatable-pagination button:hover {
          background: var(--c-primary, #007bff);
          color: white;
        }
        
        .datatable-pagination button.active {
          background: var(--c-primary, #007bff);
          color: white;
        }
        
        .datatable-pagination button:disabled {
          opacity: 0.6;
          cursor: not-allowed;
        }
        
        .datatable-sort {
          cursor: pointer;
          user-select: none;
          position: relative;
        }
        
        .datatable-sort:hover {
          background: var(--c-bkg-card, #f8f9fa);
        }
        
        .datatable-sort::after {
          content: '↕';
          position: absolute;
          right: 8px;
          opacity: 0.5;
        }
        
        .datatable-sort.asc::after {
          content: '↑';
          opacity: 1;
        }
        
        .datatable-sort.desc::after {
          content: '↓';
          opacity: 1;
        }
      `;
      document.head.appendChild(style);
    }
    bindEvents() {
      // Search functionality
      if (this.options.searchable) {
        const searchInput = this.wrapper.querySelector('.datatable-search input');
        searchInput.addEventListener('input', e => {
          this.search(e.target.value);
        });
      }

      // Sorting functionality
      if (this.options.sortable) {
        const headers = this.element.querySelectorAll('thead th');
        headers.forEach((header, index) => {
          header.classList.add('datatable-sort');
          header.addEventListener('click', () => {
            this.sort(index);
          });
        });
      }
    }
    search(query) {
      if (!query) {
        this.filteredData = [...this.originalData];
      } else {
        this.filteredData = this.originalData.filter(row => row.some(cell => cell.toLowerCase().includes(query.toLowerCase())));
      }
      this.currentPage = 1;
      this.render();
    }
    sort(columnIndex) {
      if (this.sortColumn === columnIndex) {
        this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
      } else {
        this.sortColumn = columnIndex;
        this.sortDirection = 'asc';
      }
      this.filteredData.sort((a, b) => {
        const aVal = a[columnIndex];
        const bVal = b[columnIndex];

        // Try to parse as numbers
        const aNum = parseFloat(aVal);
        const bNum = parseFloat(bVal);
        let comparison = 0;
        if (!isNaN(aNum) && !isNaN(bNum)) {
          comparison = aNum - bNum;
        } else {
          comparison = aVal.localeCompare(bVal);
        }
        return this.sortDirection === 'asc' ? comparison : -comparison;
      });
      this.updateSortHeaders();
      this.render();
    }
    updateSortHeaders() {
      const headers = this.element.querySelectorAll('thead th');
      headers.forEach((header, index) => {
        header.classList.remove('asc', 'desc');
        if (index === this.sortColumn) {
          header.classList.add(this.sortDirection);
        }
      });
    }
    render() {
      const tbody = this.element.querySelector('tbody');
      const startIndex = (this.currentPage - 1) * this.options.pageSize;
      const endIndex = startIndex + this.options.pageSize;
      const pageData = this.filteredData.slice(startIndex, endIndex);

      // Clear tbody
      tbody.innerHTML = '';

      // Add rows
      pageData.forEach(rowData => {
        const row = document.createElement('tr');
        rowData.forEach(cellData => {
          const cell = document.createElement('td');
          cell.textContent = cellData;
          row.appendChild(cell);
        });
        tbody.appendChild(row);
      });

      // Update pagination
      if (this.options.pagination) {
        this.updatePagination();
      }

      // Update info
      this.updateInfo();
    }
    updatePagination() {
      const totalPages = Math.ceil(this.filteredData.length / this.options.pageSize);
      const paginationWrapper = this.wrapper.querySelector('.datatable-pagination');
      paginationWrapper.innerHTML = '';
      if (totalPages <= 1) return;

      // Previous button
      const prevBtn = document.createElement('button');
      prevBtn.textContent = 'Previous';
      prevBtn.disabled = this.currentPage === 1;
      prevBtn.addEventListener('click', () => {
        if (this.currentPage > 1) {
          this.currentPage--;
          this.render();
        }
      });
      paginationWrapper.appendChild(prevBtn);

      // Page numbers
      for (let i = 1; i <= totalPages; i++) {
        const pageBtn = document.createElement('button');
        pageBtn.textContent = i;
        pageBtn.classList.toggle('active', i === this.currentPage);
        pageBtn.addEventListener('click', () => {
          this.currentPage = i;
          this.render();
        });
        paginationWrapper.appendChild(pageBtn);
      }

      // Next button
      const nextBtn = document.createElement('button');
      nextBtn.textContent = 'Next';
      nextBtn.disabled = this.currentPage === totalPages;
      nextBtn.addEventListener('click', () => {
        if (this.currentPage < totalPages) {
          this.currentPage++;
          this.render();
        }
      });
      paginationWrapper.appendChild(nextBtn);
    }
    updateInfo() {
      const infoWrapper = this.wrapper.querySelector('.datatable-info');
      if (!infoWrapper) return;
      const startIndex = (this.currentPage - 1) * this.options.pageSize + 1;
      const endIndex = Math.min(startIndex + this.options.pageSize - 1, this.filteredData.length);
      const total = this.filteredData.length;
      infoWrapper.textContent = `Showing ${startIndex} to ${endIndex} of ${total} entries`;
    }
    destroy() {
      if (this.wrapper && this.wrapper.parentNode) {
        this.wrapper.parentNode.replaceChild(this.element, this.wrapper);
      }
    }
  }

  // Initialize DataTable
  const initializeDataTable = () => {
    const tableElement = document.getElementById('dataTable');
    if (tableElement) {
      // Clean up existing instance
      if (tableElement.dataTableInstance) {
        tableElement.dataTableInstance.destroy();
      }

      // Create new instance
      const dataTable = new VanillaDataTable(tableElement, {
        sortable: true,
        searchable: true,
        pagination: true,
        pageSize: 10
      });

      // Store instance for cleanup
      tableElement.dataTableInstance = dataTable;
    }
  };

  // Initialize on load
  initializeDataTable();

  // Reinitialize on theme change
  window.addEventListener('adminator:themeChanged', () => {
    setTimeout(initializeDataTable, 100);
  });

  // Cleanup on page unload
  window.addEventListener('beforeunload', () => {
    const tableElement = document.getElementById('dataTable');
    if (tableElement && tableElement.dataTableInstance) {
      tableElement.dataTableInstance.destroy();
    }
  });

  // Return public API
  return {
    init: initializeDataTable,
    VanillaDataTable
  };
})());
;// ../assets/scripts/index.js
/**
 * Adminator Admin Template
 * Modern Entry Point - Phase 2 Modernization
 */

// Import the modern application


// Legacy imports that haven't been modernized yet
// These will be gradually replaced in future iterations

// import './datepicker'; // REMOVED: Replaced with modern day.js implementation in app.js

// Note: The following have been modernized and are now handled by app.js:
// - sidebar (now Sidebar component)
// - charts (now ChartComponent using Chart.js instead of jQuery Sparkline)
// - Basic DOM utilities (now DOM utils)

/***/ }

},
/******/ __webpack_require__ => { // webpackRuntimeModules
/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
/******/ __webpack_require__.O(0, [707,311,96], () => (__webpack_exec__(170)));
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ }
]);