@forcecalendar/interface 1.0.13 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"force-calendar-interface.esm.js","sources":["../src/core/BaseComponent.js","../node_modules/@forcecalendar/core/core/timezone/TimezoneDatabase.js","../node_modules/@forcecalendar/core/core/timezone/TimezoneManager.js","../node_modules/@forcecalendar/core/core/events/Event.js","../node_modules/@forcecalendar/core/core/calendar/DateUtils.js","../node_modules/@forcecalendar/core/core/events/RRuleParser.js","../node_modules/@forcecalendar/core/core/events/RecurrenceEngine.js","../node_modules/@forcecalendar/core/core/performance/LRUCache.js","../node_modules/@forcecalendar/core/core/performance/AdaptiveMemoryManager.js","../node_modules/@forcecalendar/core/core/performance/PerformanceOptimizer.js","../node_modules/@forcecalendar/core/core/conflicts/ConflictDetector.js","../node_modules/@forcecalendar/core/core/events/EventStore.js","../node_modules/@forcecalendar/core/core/state/StateManager.js","../node_modules/@forcecalendar/core/core/calendar/Calendar.js","../src/core/EventBus.js","../src/core/StateManager.js","../src/utils/DateUtils.js","../src/utils/DOMUtils.js","../src/utils/StyleUtils.js","../src/components/views/MonthView.js","../src/components/views/WeekView.js","../src/components/views/DayView.js","../src/components/EventForm.js","../src/components/ForceCalendar.js","../src/index.js"],"sourcesContent":["/**\n * BaseComponent - Foundation for all Force Calendar Web Components\n *\n * Provides common functionality:\n * - Shadow DOM setup\n * - Event handling\n * - State management integration\n * - Lifecycle management\n * - Style management\n */\n\nexport class BaseComponent extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n this._listeners = [];\n this._state = null;\n this._props = new Map();\n this._initialized = false;\n }\n\n // Lifecycle methods\n connectedCallback() {\n if (!this._initialized) {\n this.initialize();\n this._initialized = true;\n }\n this.mount();\n }\n\n disconnectedCallback() {\n this.unmount();\n this.cleanup();\n }\n\n // To be overridden by child classes\n initialize() {\n // Setup component-specific initialization\n }\n\n mount() {\n // Component mounted to DOM\n this.render();\n }\n\n unmount() {\n // Component removed from DOM\n }\n\n cleanup() {\n // Clean up event listeners\n this._listeners.forEach(({ element, event, handler }) => {\n element.removeEventListener(event, handler);\n });\n this._listeners = [];\n }\n\n // State management\n setState(newState) {\n const oldState = this._state;\n this._state = { ...this._state, ...newState };\n this.stateChanged(oldState, this._state);\n this.render();\n }\n\n getState() {\n return this._state;\n }\n\n stateChanged(oldState, newState) {\n // Override in child classes to handle state changes\n }\n\n // Props management\n setProp(key, value) {\n const oldValue = this._props.get(key);\n this._props.set(key, value);\n this.propChanged(key, oldValue, value);\n }\n\n getProp(key) {\n return this._props.get(key);\n }\n\n propChanged(key, oldValue, newValue) {\n // Override in child classes to handle prop changes\n }\n\n // Event handling\n addListener(element, event, handler) {\n if (!element || !event || !handler) {\n console.warn('addListener called with invalid parameters', { element, event, handler });\n return;\n }\n const boundHandler = handler.bind(this);\n element.addEventListener(event, boundHandler);\n this._listeners.push({ element, event, handler: boundHandler });\n }\n\n emit(eventName, detail = {}) {\n this.dispatchEvent(new CustomEvent(eventName, {\n detail,\n bubbles: true,\n composed: true\n }));\n }\n\n // Style management\n getStyles() {\n // Override in child classes to provide component styles\n return '';\n }\n\n getBaseStyles() {\n return `\n :host {\n display: block;\n box-sizing: border-box;\n }\n\n *, *::before, *::after {\n box-sizing: inherit;\n }\n `;\n }\n\n // Template rendering\n render() {\n // Clean up existing listeners before replacing DOM\n this.cleanup();\n\n const styles = `\n <style>\n ${this.getBaseStyles()}\n ${this.getStyles()}\n </style>\n `;\n\n const template = this.template();\n this.shadowRoot.innerHTML = styles + template;\n this.afterRender();\n }\n\n template() {\n // Override in child classes to provide component template\n return '';\n }\n\n afterRender() {\n // Override in child classes for post-render operations\n }\n\n // Utility methods\n $(selector) {\n return this.shadowRoot.querySelector(selector);\n }\n\n $$(selector) {\n return this.shadowRoot.querySelectorAll(selector);\n }\n\n // Attribute observation\n static get observedAttributes() {\n return [];\n }\n\n attributeChangedCallback(name, oldValue, newValue) {\n this.setProp(name, newValue);\n if (this._initialized) {\n this.render();\n }\n }\n}","/**\n * TimezoneDatabase - Comprehensive IANA timezone database\n * Contains timezone rules for all major zones worldwide\n */\n\nexport class TimezoneDatabase {\n constructor() {\n // Comprehensive IANA timezone offset data (Standard Time)\n // Offsets in minutes from UTC\n this.timezones = {\n // UTC\n 'UTC': { offset: 0, dst: null },\n 'GMT': { offset: 0, dst: null },\n\n // Africa\n 'Africa/Abidjan': { offset: 0, dst: null },\n 'Africa/Accra': { offset: 0, dst: null },\n 'Africa/Addis_Ababa': { offset: 180, dst: null },\n 'Africa/Algiers': { offset: 60, dst: null },\n 'Africa/Cairo': { offset: 120, dst: null },\n 'Africa/Casablanca': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Africa/Johannesburg': { offset: 120, dst: null },\n 'Africa/Lagos': { offset: 60, dst: null },\n 'Africa/Nairobi': { offset: 180, dst: null },\n\n // Americas\n 'America/Anchorage': { offset: -540, dst: { start: { month: 3, week: 2, day: 0 }, end: { month: 11, week: 1, day: 0 }, offset: 60 }},\n 'America/Argentina/Buenos_Aires': { offset: -180, dst: null },\n 'America/Bogota': { offset: -300, dst: null },\n 'America/Caracas': { offset: -240, dst: null },\n 'America/Chicago': { offset: -360, dst: { start: { month: 3, week: 2, day: 0 }, end: { month: 11, week: 1, day: 0 }, offset: 60 }},\n 'America/Denver': { offset: -420, dst: { start: { month: 3, week: 2, day: 0 }, end: { month: 11, week: 1, day: 0 }, offset: 60 }},\n 'America/Detroit': { offset: -300, dst: { start: { month: 3, week: 2, day: 0 }, end: { month: 11, week: 1, day: 0 }, offset: 60 }},\n 'America/Halifax': { offset: -240, dst: { start: { month: 3, week: 2, day: 0 }, end: { month: 11, week: 1, day: 0 }, offset: 60 }},\n 'America/Los_Angeles': { offset: -480, dst: { start: { month: 3, week: 2, day: 0 }, end: { month: 11, week: 1, day: 0 }, offset: 60 }},\n 'America/Mexico_City': { offset: -360, dst: { start: { month: 4, week: 1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'America/New_York': { offset: -300, dst: { start: { month: 3, week: 2, day: 0 }, end: { month: 11, week: 1, day: 0 }, offset: 60 }},\n 'America/Phoenix': { offset: -420, dst: null },\n 'America/Regina': { offset: -360, dst: null },\n 'America/Santiago': { offset: -180, dst: { start: { month: 9, week: 1, day: 0 }, end: { month: 4, week: 1, day: 0 }, offset: 60 }},\n 'America/Sao_Paulo': { offset: -180, dst: { start: { month: 10, week: 3, day: 0 }, end: { month: 2, week: 3, day: 0 }, offset: 60 }},\n 'America/St_Johns': { offset: -210, dst: { start: { month: 3, week: 2, day: 0 }, end: { month: 11, week: 1, day: 0 }, offset: 60 }},\n 'America/Toronto': { offset: -300, dst: { start: { month: 3, week: 2, day: 0 }, end: { month: 11, week: 1, day: 0 }, offset: 60 }},\n 'America/Vancouver': { offset: -480, dst: { start: { month: 3, week: 2, day: 0 }, end: { month: 11, week: 1, day: 0 }, offset: 60 }},\n\n // Asia\n 'Asia/Baghdad': { offset: 180, dst: null },\n 'Asia/Bangkok': { offset: 420, dst: null },\n 'Asia/Dubai': { offset: 240, dst: null },\n 'Asia/Hong_Kong': { offset: 480, dst: null },\n 'Asia/Jakarta': { offset: 420, dst: null },\n 'Asia/Jerusalem': { offset: 120, dst: { start: { month: 3, week: -1, day: 5 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Asia/Karachi': { offset: 300, dst: null },\n 'Asia/Kolkata': { offset: 330, dst: null },\n 'Asia/Kuala_Lumpur': { offset: 480, dst: null },\n 'Asia/Manila': { offset: 480, dst: null },\n 'Asia/Seoul': { offset: 540, dst: null },\n 'Asia/Shanghai': { offset: 480, dst: null },\n 'Asia/Singapore': { offset: 480, dst: null },\n 'Asia/Taipei': { offset: 480, dst: null },\n 'Asia/Tehran': { offset: 210, dst: { start: { month: 3, week: 4, day: 0 }, end: { month: 9, week: 4, day: 0 }, offset: 60 }},\n 'Asia/Tokyo': { offset: 540, dst: null },\n\n // Atlantic\n 'Atlantic/Azores': { offset: -60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Atlantic/Bermuda': { offset: -240, dst: { start: { month: 3, week: 2, day: 0 }, end: { month: 11, week: 1, day: 0 }, offset: 60 }},\n 'Atlantic/Reykjavik': { offset: 0, dst: null },\n\n // Australia & Pacific\n 'Australia/Adelaide': { offset: 570, dst: { start: { month: 10, week: 1, day: 0 }, end: { month: 4, week: 1, day: 0 }, offset: 60 }},\n 'Australia/Brisbane': { offset: 600, dst: null },\n 'Australia/Darwin': { offset: 570, dst: null },\n 'Australia/Hobart': { offset: 600, dst: { start: { month: 10, week: 1, day: 0 }, end: { month: 4, week: 1, day: 0 }, offset: 60 }},\n 'Australia/Melbourne': { offset: 600, dst: { start: { month: 10, week: 1, day: 0 }, end: { month: 4, week: 1, day: 0 }, offset: 60 }},\n 'Australia/Perth': { offset: 480, dst: null },\n 'Australia/Sydney': { offset: 600, dst: { start: { month: 10, week: 1, day: 0 }, end: { month: 4, week: 1, day: 0 }, offset: 60 }},\n\n // Europe\n 'Europe/Amsterdam': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Athens': { offset: 120, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Berlin': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Brussels': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Budapest': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Copenhagen': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Dublin': { offset: 0, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Helsinki': { offset: 120, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Istanbul': { offset: 180, dst: null },\n 'Europe/Kiev': { offset: 120, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Lisbon': { offset: 0, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/London': { offset: 0, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Madrid': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Moscow': { offset: 180, dst: null },\n 'Europe/Oslo': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Paris': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Prague': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Rome': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Stockholm': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Vienna': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Warsaw': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n 'Europe/Zurich': { offset: 60, dst: { start: { month: 3, week: -1, day: 0 }, end: { month: 10, week: -1, day: 0 }, offset: 60 }},\n\n // Indian\n 'Indian/Maldives': { offset: 300, dst: null },\n 'Indian/Mauritius': { offset: 240, dst: null },\n\n // Pacific\n 'Pacific/Auckland': { offset: 720, dst: { start: { month: 9, week: -1, day: 0 }, end: { month: 4, week: 1, day: 0 }, offset: 60 }},\n 'Pacific/Fiji': { offset: 720, dst: { start: { month: 11, week: 1, day: 0 }, end: { month: 1, week: 3, day: 0 }, offset: 60 }},\n 'Pacific/Guam': { offset: 600, dst: null },\n 'Pacific/Honolulu': { offset: -600, dst: null },\n 'Pacific/Midway': { offset: -660, dst: null },\n 'Pacific/Noumea': { offset: 660, dst: null },\n 'Pacific/Pago_Pago': { offset: -660, dst: null },\n 'Pacific/Port_Moresby': { offset: 600, dst: null },\n 'Pacific/Tahiti': { offset: -600, dst: null }\n };\n\n // Timezone aliases and abbreviations\n this.aliases = {\n // Common abbreviations to IANA\n 'EST': 'America/New_York',\n 'EDT': 'America/New_York',\n 'CST': 'America/Chicago',\n 'CDT': 'America/Chicago',\n 'MST': 'America/Denver',\n 'MDT': 'America/Denver',\n 'PST': 'America/Los_Angeles',\n 'PDT': 'America/Los_Angeles',\n 'AKST': 'America/Anchorage',\n 'AKDT': 'America/Anchorage',\n 'HST': 'Pacific/Honolulu',\n 'AST': 'America/Halifax',\n 'ADT': 'America/Halifax',\n 'NST': 'America/St_Johns',\n 'NDT': 'America/St_Johns',\n 'BST': 'Europe/London',\n 'IST': 'Asia/Kolkata',\n 'WET': 'Europe/Lisbon',\n 'WEST': 'Europe/Lisbon',\n 'CET': 'Europe/Paris',\n 'CEST': 'Europe/Paris',\n 'EET': 'Europe/Athens',\n 'EEST': 'Europe/Athens',\n 'MSK': 'Europe/Moscow',\n 'JST': 'Asia/Tokyo',\n 'KST': 'Asia/Seoul',\n 'CST_CN': 'Asia/Shanghai',\n 'HKT': 'Asia/Hong_Kong',\n 'SGT': 'Asia/Singapore',\n 'AEST': 'Australia/Sydney',\n 'AEDT': 'Australia/Sydney',\n 'ACST': 'Australia/Adelaide',\n 'ACDT': 'Australia/Adelaide',\n 'AWST': 'Australia/Perth',\n 'NZST': 'Pacific/Auckland',\n 'NZDT': 'Pacific/Auckland',\n\n // City/Country aliases\n 'US/Eastern': 'America/New_York',\n 'US/Central': 'America/Chicago',\n 'US/Mountain': 'America/Denver',\n 'US/Pacific': 'America/Los_Angeles',\n 'US/Alaska': 'America/Anchorage',\n 'US/Hawaii': 'Pacific/Honolulu',\n 'Canada/Eastern': 'America/Toronto',\n 'Canada/Central': 'America/Regina',\n 'Canada/Mountain': 'America/Denver',\n 'Canada/Pacific': 'America/Vancouver',\n 'Canada/Atlantic': 'America/Halifax',\n 'Canada/Newfoundland': 'America/St_Johns',\n 'Mexico/General': 'America/Mexico_City',\n 'Brazil/East': 'America/Sao_Paulo',\n 'Chile/Continental': 'America/Santiago',\n 'GB': 'Europe/London',\n 'GB-Eire': 'Europe/London',\n 'Eire': 'Europe/Dublin',\n 'Israel': 'Asia/Jerusalem',\n 'Japan': 'Asia/Tokyo',\n 'Singapore': 'Asia/Singapore',\n 'Hongkong': 'Asia/Hong_Kong',\n 'ROK': 'Asia/Seoul',\n 'PRC': 'Asia/Shanghai',\n 'Australia/NSW': 'Australia/Sydney',\n 'Australia/Victoria': 'Australia/Melbourne',\n 'Australia/Queensland': 'Australia/Brisbane',\n 'Australia/South': 'Australia/Adelaide',\n 'Australia/Tasmania': 'Australia/Hobart',\n 'Australia/West': 'Australia/Perth',\n 'Australia/North': 'Australia/Darwin',\n 'NZ': 'Pacific/Auckland'\n };\n }\n\n /**\n * Get timezone data by identifier\n * @param {string} timezone - Timezone identifier or alias\n * @returns {Object|null} Timezone data or null if not found\n */\n getTimezone(timezone) {\n // Check for alias first\n if (this.aliases[timezone]) {\n timezone = this.aliases[timezone];\n }\n\n return this.timezones[timezone] || null;\n }\n\n /**\n * Get all available timezone identifiers\n * @returns {string[]} Array of timezone identifiers\n */\n getAllTimezones() {\n return Object.keys(this.timezones);\n }\n\n /**\n * Check if a timezone identifier is valid\n * @param {string} timezone - Timezone identifier\n * @returns {boolean} True if valid\n */\n isValidTimezone(timezone) {\n return this.aliases[timezone] !== undefined || this.timezones[timezone] !== undefined;\n }\n\n /**\n * Resolve timezone alias to canonical identifier\n * @param {string} timezone - Timezone identifier or alias\n * @returns {string} Canonical timezone identifier\n */\n resolveAlias(timezone) {\n return this.aliases[timezone] || timezone;\n }\n\n /**\n * Get timezones by offset\n * @param {number} offsetMinutes - Offset in minutes from UTC\n * @returns {string[]} Array of timezone identifiers\n */\n getTimezonesByOffset(offsetMinutes) {\n return Object.entries(this.timezones)\n .filter(([_, data]) => data.offset === offsetMinutes)\n .map(([id, _]) => id);\n }\n\n /**\n * Get common timezones for quick selection\n * @returns {Object} Grouped timezones by region\n */\n getCommonTimezones() {\n return {\n 'Americas': [\n 'America/New_York',\n 'America/Chicago',\n 'America/Denver',\n 'America/Los_Angeles',\n 'America/Toronto',\n 'America/Mexico_City',\n 'America/Sao_Paulo'\n ],\n 'Europe': [\n 'Europe/London',\n 'Europe/Paris',\n 'Europe/Berlin',\n 'Europe/Moscow',\n 'Europe/Rome',\n 'Europe/Madrid',\n 'Europe/Amsterdam'\n ],\n 'Asia': [\n 'Asia/Tokyo',\n 'Asia/Shanghai',\n 'Asia/Hong_Kong',\n 'Asia/Singapore',\n 'Asia/Kolkata',\n 'Asia/Dubai',\n 'Asia/Seoul'\n ],\n 'Australia/Pacific': [\n 'Australia/Sydney',\n 'Australia/Melbourne',\n 'Australia/Brisbane',\n 'Australia/Perth',\n 'Pacific/Auckland',\n 'Pacific/Honolulu'\n ],\n 'Africa': [\n 'Africa/Cairo',\n 'Africa/Lagos',\n 'Africa/Johannesburg',\n 'Africa/Nairobi'\n ]\n };\n }\n}","/**\n * TimezoneManager - Comprehensive timezone handling for global calendar operations\n * Handles timezone conversions, DST transitions, and IANA timezone database\n *\n * Critical for Salesforce orgs spanning multiple timezones\n */\n\nimport { TimezoneDatabase } from './TimezoneDatabase.js';\n\nexport class TimezoneManager {\n constructor() {\n // Initialize comprehensive timezone database\n this.database = new TimezoneDatabase();\n\n // Cache timezone offsets for performance\n this.offsetCache = new Map();\n this.dstCache = new Map();\n\n // Cache size management\n this.maxCacheSize = 1000;\n this.cacheHits = 0;\n this.cacheMisses = 0;\n }\n\n /**\n * Convert date from one timezone to another\n * @param {Date} date - Date to convert\n * @param {string} fromTimezone - Source timezone (IANA identifier)\n * @param {string} toTimezone - Target timezone (IANA identifier)\n * @returns {Date} Converted date\n */\n convertTimezone(date, fromTimezone, toTimezone) {\n if (!date) return null;\n if (fromTimezone === toTimezone) return new Date(date);\n\n // Get offset difference\n const fromOffset = this.getTimezoneOffset(date, fromTimezone);\n const toOffset = this.getTimezoneOffset(date, toTimezone);\n const offsetDiff = (toOffset - fromOffset) * 60 * 1000; // Convert to milliseconds\n\n return new Date(date.getTime() + offsetDiff);\n }\n\n /**\n * Convert date to UTC\n * @param {Date} date - Date in local timezone\n * @param {string} timezone - Source timezone\n * @returns {Date} Date in UTC\n */\n toUTC(date, timezone) {\n if (!date) return null;\n if (timezone === 'UTC') return new Date(date);\n\n // offset is positive for timezones behind UTC (e.g., NYC = +300)\n // To convert local to UTC, we ADD the offset\n const offset = this.getTimezoneOffset(date, timezone);\n return new Date(date.getTime() + (offset * 60 * 1000));\n }\n\n /**\n * Convert UTC date to timezone\n * @param {Date} utcDate - Date in UTC\n * @param {string} timezone - Target timezone\n * @returns {Date} Date in specified timezone\n */\n fromUTC(utcDate, timezone) {\n if (!utcDate) return null;\n if (timezone === 'UTC') return new Date(utcDate);\n\n // offset is positive for timezones behind UTC (e.g., NYC = +300)\n // To convert UTC to local, we SUBTRACT the offset\n const offset = this.getTimezoneOffset(utcDate, timezone);\n return new Date(utcDate.getTime() - (offset * 60 * 1000));\n }\n\n /**\n * Get timezone offset in minutes\n * @param {Date} date - Date to check (for DST calculation)\n * @param {string} timezone - Timezone identifier\n * @returns {number} Offset in minutes from UTC\n */\n getTimezoneOffset(date, timezone) {\n // Resolve any aliases\n timezone = this.database.resolveAlias(timezone);\n\n // Check cache first\n const cacheKey = `${timezone}_${date.getFullYear()}_${date.getMonth()}_${date.getDate()}`;\n if (this.offsetCache.has(cacheKey)) {\n this.cacheHits++;\n this._manageCacheSize();\n return this.offsetCache.get(cacheKey);\n }\n\n this.cacheMisses++;\n\n // Try using Intl API if available (best option for browser/Node.js environments)\n if (typeof Intl !== 'undefined' && Intl.DateTimeFormat) {\n try {\n const formatter = new Intl.DateTimeFormat('en-US', {\n timeZone: timezone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false\n });\n\n // Create same date in target timezone\n const parts = formatter.formatToParts(date);\n const tzDate = new Date(\n parts.find(p => p.type === 'year').value,\n parts.find(p => p.type === 'month').value - 1,\n parts.find(p => p.type === 'day').value,\n parts.find(p => p.type === 'hour').value,\n parts.find(p => p.type === 'minute').value,\n parts.find(p => p.type === 'second').value\n );\n\n const offset = (tzDate.getTime() - date.getTime()) / (1000 * 60);\n this.offsetCache.set(cacheKey, -offset);\n this._manageCacheSize();\n return -offset;\n } catch (e) {\n // Fallback to database calculation\n }\n }\n\n // Fallback: Use timezone database\n const tzData = this.database.getTimezone(timezone);\n if (!tzData) {\n throw new Error(`Unknown timezone: ${timezone}`);\n }\n\n let offset = tzData.offset;\n\n // Apply DST if applicable\n if (tzData.dst && this.isDST(date, timezone, tzData.dst)) {\n offset += tzData.dst.offset;\n }\n\n this.offsetCache.set(cacheKey, offset);\n this._manageCacheSize();\n return offset;\n }\n\n /**\n * Check if date is in DST for given timezone\n * @param {Date} date - Date to check\n * @param {string} timezone - Timezone identifier\n * @param {Object} [dstRule] - DST rule object (optional, will fetch if not provided)\n * @returns {boolean} True if in DST\n */\n isDST(date, timezone, dstRule = null) {\n // Get DST rule if not provided\n if (!dstRule) {\n const tzData = this.database.getTimezone(timezone);\n if (!tzData || !tzData.dst) return false;\n dstRule = tzData.dst;\n }\n\n const year = date.getFullYear();\n const dstStart = this.getNthWeekdayOfMonth(year, dstRule.start.month, dstRule.start.week, dstRule.start.day);\n const dstEnd = this.getNthWeekdayOfMonth(year, dstRule.end.month, dstRule.end.week, dstRule.end.day);\n\n // Handle Southern Hemisphere (DST crosses year boundary)\n if (dstStart > dstEnd) {\n return date >= dstStart || date < dstEnd;\n }\n\n return date >= dstStart && date < dstEnd;\n }\n\n /**\n * Get nth weekday of month\n * @private\n */\n getNthWeekdayOfMonth(year, month, week, dayOfWeek) {\n const date = new Date(year, month, 1);\n const firstDay = date.getDay();\n\n let dayOffset = dayOfWeek - firstDay;\n if (dayOffset < 0) dayOffset += 7;\n\n if (week > 0) {\n // Nth occurrence from start\n date.setDate(1 + dayOffset + (week - 1) * 7);\n } else {\n // Nth occurrence from end\n const lastDay = new Date(year, month + 1, 0).getDate();\n date.setDate(lastDay);\n const lastDayOfWeek = date.getDay();\n let offset = lastDayOfWeek - dayOfWeek;\n if (offset < 0) offset += 7;\n date.setDate(lastDay - offset + (week + 1) * 7);\n }\n\n return date;\n }\n\n /**\n * Get list of common timezones\n * @returns {Array<{value: string, label: string, offset: string}>}\n */\n getCommonTimezones() {\n const now = new Date();\n const timezones = [\n { value: 'America/New_York', label: 'Eastern Time (New York)', region: 'Americas' },\n { value: 'America/Chicago', label: 'Central Time (Chicago)', region: 'Americas' },\n { value: 'America/Denver', label: 'Mountain Time (Denver)', region: 'Americas' },\n { value: 'America/Phoenix', label: 'Mountain Time - Arizona (Phoenix)', region: 'Americas' },\n { value: 'America/Los_Angeles', label: 'Pacific Time (Los Angeles)', region: 'Americas' },\n { value: 'America/Anchorage', label: 'Alaska Time (Anchorage)', region: 'Americas' },\n { value: 'Pacific/Honolulu', label: 'Hawaii Time (Honolulu)', region: 'Pacific' },\n { value: 'America/Toronto', label: 'Eastern Time (Toronto)', region: 'Americas' },\n { value: 'America/Vancouver', label: 'Pacific Time (Vancouver)', region: 'Americas' },\n { value: 'America/Mexico_City', label: 'Central Time (Mexico City)', region: 'Americas' },\n { value: 'America/Sao_Paulo', label: 'Brasilia Time (São Paulo)', region: 'Americas' },\n { value: 'Europe/London', label: 'GMT/BST (London)', region: 'Europe' },\n { value: 'Europe/Paris', label: 'Central European Time (Paris)', region: 'Europe' },\n { value: 'Europe/Berlin', label: 'Central European Time (Berlin)', region: 'Europe' },\n { value: 'Europe/Moscow', label: 'Moscow Time', region: 'Europe' },\n { value: 'Asia/Dubai', label: 'Gulf Time (Dubai)', region: 'Asia' },\n { value: 'Asia/Kolkata', label: 'India Time (Mumbai)', region: 'Asia' },\n { value: 'Asia/Shanghai', label: 'China Time (Shanghai)', region: 'Asia' },\n { value: 'Asia/Tokyo', label: 'Japan Time (Tokyo)', region: 'Asia' },\n { value: 'Asia/Seoul', label: 'Korea Time (Seoul)', region: 'Asia' },\n { value: 'Asia/Singapore', label: 'Singapore Time', region: 'Asia' },\n { value: 'Australia/Sydney', label: 'Australian Eastern Time (Sydney)', region: 'Oceania' },\n { value: 'Australia/Melbourne', label: 'Australian Eastern Time (Melbourne)', region: 'Oceania' },\n { value: 'Pacific/Auckland', label: 'New Zealand Time (Auckland)', region: 'Oceania' },\n { value: 'UTC', label: 'UTC', region: 'UTC' }\n ];\n\n // Add current offset to each timezone\n return timezones.map(tz => {\n const offset = this.getTimezoneOffset(now, tz.value);\n const offsetHours = -offset / 60; // Convert to hours from UTC\n const hours = Math.floor(Math.abs(offsetHours));\n const minutes = Math.round(Math.abs(offsetHours % 1) * 60);\n const sign = offsetHours >= 0 ? '+' : '-';\n const offsetStr = `UTC${sign}${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;\n\n return {\n ...tz,\n offset: offsetStr,\n offsetMinutes: -offset // Store in minutes for sorting\n };\n }).sort((a, b) => a.offsetMinutes - b.offsetMinutes);\n }\n\n /**\n * Format date in specific timezone\n * @param {Date} date - Date to format\n * @param {string} timezone - Timezone for formatting\n * @param {Object} options - Formatting options\n * @returns {string} Formatted date string\n */\n formatInTimezone(date, timezone, options = {}) {\n if (!date) return '';\n\n const defaultOptions = {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n hour12: true,\n timeZone: timezone\n };\n\n const formatOptions = { ...defaultOptions, ...options };\n\n try {\n return new Intl.DateTimeFormat('en-US', formatOptions).format(date);\n } catch (e) {\n // Fallback to basic formatting\n const tzDate = this.fromUTC(this.toUTC(date, 'UTC'), timezone);\n return tzDate.toLocaleString('en-US', options);\n }\n }\n\n /**\n * Get timezone from browser/system\n * @returns {string} IANA timezone identifier\n */\n getSystemTimezone() {\n if (typeof Intl !== 'undefined' && Intl.DateTimeFormat) {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch (e) {\n // Fallback\n }\n }\n\n // Fallback based on offset\n const offset = new Date().getTimezoneOffset();\n const offsetHours = -offset / 60;\n\n // Try to match offset to known timezone\n for (const [tz, tzData] of Object.entries(this.database.timezones)) {\n if (tzData.offset / 60 === offsetHours) {\n return tz;\n }\n }\n\n return 'UTC';\n }\n\n /**\n * Parse timezone from string (handles abbreviations)\n * @param {string} tzString - Timezone string\n * @returns {string} IANA timezone identifier\n */\n parseTimezone(tzString) {\n if (!tzString) return 'UTC';\n\n // Check if it's already an IANA identifier\n if (this.database.timezones.hasOwnProperty(tzString)) {\n return tzString;\n }\n\n // Check abbreviations\n const upperTz = tzString.toUpperCase();\n if (this.database.abbreviations && this.database.abbreviations.hasOwnProperty(upperTz)) {\n return this.database.abbreviations[upperTz];\n }\n\n // Try to parse offset format (e.g., \"+05:30\", \"-08:00\")\n const offsetMatch = tzString.match(/^([+-])(\\d{2}):?(\\d{2})$/);\n if (offsetMatch) {\n const sign = offsetMatch[1] === '+' ? 1 : -1;\n const hours = parseInt(offsetMatch[2], 10);\n const minutes = parseInt(offsetMatch[3], 10);\n const totalOffset = sign * (hours + minutes / 60);\n\n // Find matching timezone\n for (const [tz, tzData] of Object.entries(this.database.timezones)) {\n if (tzData.offset / 60 === totalOffset) {\n return tz;\n }\n }\n }\n\n return 'UTC';\n }\n\n /**\n * Calculate timezone difference in hours\n * @param {string} timezone1 - First timezone\n * @param {string} timezone2 - Second timezone\n * @param {Date} [date] - Date for DST calculation\n * @returns {number} Hour difference\n */\n getTimezoneDifference(timezone1, timezone2, date = new Date()) {\n const offset1 = this.getTimezoneOffset(date, timezone1);\n const offset2 = this.getTimezoneOffset(date, timezone2);\n return (offset2 - offset1) / 60;\n }\n\n /**\n * Clear caches (useful when date changes significantly)\n */\n clearCache() {\n this.offsetCache.clear();\n this.dstCache.clear();\n this.cacheHits = 0;\n this.cacheMisses = 0;\n }\n\n /**\n * Validate timezone identifier\n * @param {string} timezone - Timezone to validate\n * @returns {boolean} True if valid\n */\n isValidTimezone(timezone) {\n return this.database.isValidTimezone(timezone);\n }\n\n /**\n * Get cache statistics\n * @returns {Object} Cache stats\n */\n getCacheStats() {\n const hitRate = this.cacheHits + this.cacheMisses > 0\n ? (this.cacheHits / (this.cacheHits + this.cacheMisses) * 100).toFixed(2)\n : 0;\n\n return {\n offsetCacheSize: this.offsetCache.size,\n dstCacheSize: this.dstCache.size,\n maxCacheSize: this.maxCacheSize,\n cacheHits: this.cacheHits,\n cacheMisses: this.cacheMisses,\n hitRate: `${hitRate}%`\n };\n }\n\n /**\n * Manage cache size - evict old entries if needed\n * @private\n */\n _manageCacheSize() {\n // Clear caches if they get too large\n if (this.offsetCache.size > this.maxCacheSize) {\n // Remove first half of entries (oldest)\n const entriesToRemove = Math.floor(this.offsetCache.size / 2);\n const keys = Array.from(this.offsetCache.keys());\n for (let i = 0; i < entriesToRemove; i++) {\n this.offsetCache.delete(keys[i]);\n }\n }\n\n if (this.dstCache.size > this.maxCacheSize / 2) {\n const entriesToRemove = Math.floor(this.dstCache.size / 2);\n const keys = Array.from(this.dstCache.keys());\n for (let i = 0; i < entriesToRemove; i++) {\n this.dstCache.delete(keys[i]);\n }\n }\n }\n}","/**\n * Event class - represents a calendar event with timezone support\n * Pure JavaScript, no DOM dependencies\n * Locker Service compatible\n */\n\nimport { TimezoneManager } from '../timezone/TimezoneManager.js';\n\nexport class Event {\n /**\n * Normalize event data\n * @param {import('../../types.js').EventData} data - Raw event data\n * @returns {import('../../types.js').EventData} Normalized event data\n */\n static normalize(data) {\n const normalized = { ...data };\n\n // Ensure dates are Date objects\n if (normalized.start && !(normalized.start instanceof Date)) {\n normalized.start = new Date(normalized.start);\n }\n if (normalized.end && !(normalized.end instanceof Date)) {\n normalized.end = new Date(normalized.end);\n }\n\n // If no end date, set it to start date\n if (!normalized.end) {\n normalized.end = normalized.start ? new Date(normalized.start) : null;\n }\n\n // For all-day events, normalize times to midnight\n if (normalized.allDay && normalized.start) {\n normalized.start.setHours(0, 0, 0, 0);\n if (normalized.end) {\n normalized.end.setHours(23, 59, 59, 999);\n }\n }\n\n // Normalize string fields\n normalized.id = String(normalized.id || '').trim();\n normalized.title = String(normalized.title || '').trim();\n normalized.description = String(normalized.description || '').trim();\n normalized.location = String(normalized.location || '').trim();\n\n // Normalize arrays\n normalized.attendees = Array.isArray(normalized.attendees) ? normalized.attendees : [];\n normalized.reminders = Array.isArray(normalized.reminders) ? normalized.reminders : [];\n\n // Handle both 'category' (singular) and 'categories' (plural)\n if (data.category && !data.categories) {\n // If single category is provided, convert to array\n normalized.categories = [data.category];\n } else if (normalized.categories) {\n normalized.categories = Array.isArray(normalized.categories) ? normalized.categories : [];\n } else {\n normalized.categories = [];\n }\n\n normalized.attachments = Array.isArray(normalized.attachments) ? normalized.attachments : [];\n\n // Normalize status and visibility\n const validStatuses = ['confirmed', 'tentative', 'cancelled'];\n if (!validStatuses.includes(normalized.status)) {\n normalized.status = 'confirmed';\n }\n\n const validVisibilities = ['public', 'private', 'confidential'];\n if (!validVisibilities.includes(normalized.visibility)) {\n normalized.visibility = 'public';\n }\n\n // Normalize colors\n if (normalized.color && !normalized.backgroundColor) {\n normalized.backgroundColor = normalized.color;\n }\n if (normalized.color && !normalized.borderColor) {\n normalized.borderColor = normalized.color;\n }\n\n return normalized;\n }\n\n /**\n * Validate event data\n * @param {import('../../types.js').EventData} data - Normalized event data\n * @throws {Error} If validation fails\n */\n static validate(data) {\n // Required fields\n if (!data.id) {\n throw new Error('Event must have an id');\n }\n if (!data.title) {\n throw new Error('Event must have a title');\n }\n if (!data.start) {\n throw new Error('Event must have a start date');\n }\n\n // Validate dates\n if (!(data.start instanceof Date) || isNaN(data.start.getTime())) {\n throw new Error('Invalid start date');\n }\n if (data.end && (!(data.end instanceof Date) || isNaN(data.end.getTime()))) {\n throw new Error('Invalid end date');\n }\n\n // Validate date order\n if (data.end && data.start && data.end < data.start) {\n throw new Error('Event end time cannot be before start time');\n }\n\n // Validate recurrence\n if (data.recurring && !data.recurrenceRule) {\n throw new Error('Recurring events must have a recurrence rule');\n }\n\n // Validate attendees\n if (data.attendees && data.attendees.length > 0) {\n data.attendees.forEach((attendee, index) => {\n if (!attendee.email || !attendee.name) {\n throw new Error(`Attendee at index ${index} must have email and name`);\n }\n // Validate email format\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(attendee.email)) {\n throw new Error(`Invalid email for attendee: ${attendee.email}`);\n }\n });\n }\n\n // Validate reminders\n if (data.reminders && data.reminders.length > 0) {\n data.reminders.forEach((reminder, index) => {\n if (!reminder.method || reminder.minutesBefore == null) {\n throw new Error(`Reminder at index ${index} must have method and minutesBefore`);\n }\n if (reminder.minutesBefore < 0) {\n throw new Error('Reminder minutesBefore must be non-negative');\n }\n });\n }\n\n // Validate timezone if provided\n if (data.timeZone) {\n try {\n // Test if timezone is valid by trying to use it\n new Intl.DateTimeFormat('en-US', { timeZone: data.timeZone });\n } catch (e) {\n throw new Error(`Invalid timezone: ${data.timeZone}`);\n }\n }\n }\n\n /**\n * Create a new Event instance\n * @param {import('../../types.js').EventData} eventData - Event data object\n * @throws {Error} If required fields are missing or invalid\n */\n constructor({\n id,\n title,\n start,\n end,\n allDay = false,\n description = '',\n location = '',\n color = null,\n backgroundColor = null,\n borderColor = null,\n textColor = null,\n recurring = false,\n recurrenceRule = null,\n timeZone = null,\n endTimeZone = null,\n status = 'confirmed',\n visibility = 'public',\n organizer = null,\n attendees = [],\n reminders = [],\n category, // Support singular category (no default)\n categories, // Support plural categories (no default)\n attachments = [],\n conferenceData = null,\n metadata = {},\n ...rest // Capture any extra properties\n }) {\n // Normalize and validate input\n const normalized = Event.normalize({\n id,\n title,\n start,\n end,\n allDay,\n description,\n location,\n color,\n backgroundColor,\n borderColor,\n textColor,\n recurring,\n recurrenceRule,\n timeZone,\n endTimeZone,\n status,\n visibility,\n organizer,\n attendees,\n reminders,\n category, // Pass category to normalize\n categories, // Pass categories to normalize\n attachments,\n conferenceData,\n metadata,\n ...rest // Pass any extra properties\n });\n\n // Validate normalized data\n Event.validate(normalized);\n\n this.id = normalized.id;\n this.title = normalized.title;\n\n // Initialize timezone manager\n this._timezoneManager = new TimezoneManager();\n\n // Timezone handling\n // Store the timezone the event was created in (wall-clock time)\n this.timeZone = normalized.timeZone || this._timezoneManager.getSystemTimezone();\n this.endTimeZone = normalized.endTimeZone || this.timeZone; // Different end timezone for flights etc.\n\n // Store dates as provided (wall-clock time in event timezone)\n this.start = normalized.start;\n this.end = normalized.end;\n\n // Store UTC versions for efficient querying and comparison\n this.startUTC = this._timezoneManager.toUTC(this.start, this.timeZone);\n this.endUTC = this._timezoneManager.toUTC(this.end, this.endTimeZone);\n\n this.allDay = normalized.allDay;\n this.description = normalized.description;\n this.location = normalized.location;\n\n // Styling\n this.color = normalized.color;\n this.backgroundColor = normalized.backgroundColor;\n this.borderColor = normalized.borderColor;\n this.textColor = normalized.textColor;\n\n // Recurrence\n this.recurring = normalized.recurring;\n this.recurrenceRule = normalized.recurrenceRule;\n\n // Store original timezone from system if not provided\n this._originalTimeZone = normalized.timeZone || null;\n\n // Event status and visibility\n this.status = normalized.status;\n this.visibility = normalized.visibility;\n\n // People\n this.organizer = normalized.organizer;\n this.attendees = [...normalized.attendees];\n\n // Reminders\n this.reminders = [...normalized.reminders];\n\n // Categories/Tags\n this.categories = normalized.categories ? [...normalized.categories] : [];\n\n // Attachments\n this.attachments = [...normalized.attachments];\n\n // Conference/Virtual meeting\n this.conferenceData = normalized.conferenceData;\n\n // Custom metadata for extensibility\n this.metadata = { ...normalized.metadata };\n\n // Computed properties cache\n this._cache = {};\n\n // Validate complex properties\n this._validateAttendees();\n this._validateReminders();\n }\n\n /**\n * Get event duration in milliseconds\n * @returns {number} Duration in milliseconds\n */\n get duration() {\n if (!this._cache.duration) {\n // Use UTC times for accurate duration calculation\n this._cache.duration = this.endUTC.getTime() - this.startUTC.getTime();\n }\n return this._cache.duration;\n }\n\n /**\n * Get start date in a specific timezone\n * @param {string} timezone - Target timezone\n * @returns {Date} Start date in specified timezone\n */\n getStartInTimezone(timezone) {\n if (timezone === this.timeZone) {\n return new Date(this.start);\n }\n return this._timezoneManager.fromUTC(this.startUTC, timezone);\n }\n\n /**\n * Get end date in a specific timezone\n * @param {string} timezone - Target timezone\n * @returns {Date} End date in specified timezone\n */\n getEndInTimezone(timezone) {\n if (timezone === this.endTimeZone) {\n return new Date(this.end);\n }\n return this._timezoneManager.fromUTC(this.endUTC, timezone);\n }\n\n /**\n * Update event times preserving the timezone\n * @param {Date} start - New start date\n * @param {Date} end - New end date\n * @param {string} [timezone] - Timezone for the new dates\n */\n updateTimes(start, end, timezone) {\n const tz = timezone || this.timeZone;\n\n this.start = start instanceof Date ? start : new Date(start);\n this.end = end instanceof Date ? end : new Date(end);\n\n if (timezone) {\n this.timeZone = timezone;\n this.endTimeZone = timezone;\n }\n\n // Update UTC versions\n this.startUTC = this._timezoneManager.toUTC(this.start, this.timeZone);\n this.endUTC = this._timezoneManager.toUTC(this.end, this.endTimeZone);\n\n // Clear cache\n this._cache = {};\n\n // Validate\n if (this.endUTC < this.startUTC) {\n throw new Error('Event end time cannot be before start time');\n }\n }\n\n /**\n * Get event duration in minutes\n * @returns {number} Duration in minutes\n */\n get durationMinutes() {\n return Math.floor(this.duration / (1000 * 60));\n }\n\n /**\n * Get event duration in hours\n * @returns {number} Duration in hours\n */\n get durationHours() {\n return this.duration / (1000 * 60 * 60);\n }\n\n /**\n * Check if this is a multi-day event\n * @returns {boolean} True if event spans multiple days\n */\n get isMultiDay() {\n if (!this._cache.hasOwnProperty('isMultiDay')) {\n const startDay = this.start.toDateString();\n const endDay = this.end.toDateString();\n this._cache.isMultiDay = startDay !== endDay;\n }\n return this._cache.isMultiDay;\n }\n\n /**\n * Check if event is recurring\n * @returns {boolean} True if event is recurring\n */\n isRecurring() {\n return this.recurring && this.recurrenceRule !== null;\n }\n\n /**\n * Check if event occurs on a specific date\n * @param {Date|string} date - The date to check\n * @returns {boolean} True if event occurs on the given date\n */\n occursOn(date) {\n if (!(date instanceof Date)) {\n date = new Date(date);\n }\n\n const dateString = date.toDateString();\n const startString = this.start.toDateString();\n const endString = this.end.toDateString();\n\n // For all-day events, check if date falls within range\n if (this.allDay) {\n return date >= new Date(startString) && date <= new Date(endString);\n }\n\n // For timed events, check if any part of the event occurs on this date\n if (this.isMultiDay) {\n // Multi-day event: check if date is within range\n const dayStart = new Date(dateString);\n const dayEnd = new Date(dateString);\n dayEnd.setHours(23, 59, 59, 999);\n\n return this.start <= dayEnd && this.end >= dayStart;\n } else {\n // Single day event: check if it's on the same day\n return startString === dateString;\n }\n }\n\n /**\n * Check if this event overlaps with another event\n * @param {Event|{start: Date, end: Date}} otherEvent - The other event or time range to check\n * @returns {boolean} True if events overlap\n * @throws {Error} If otherEvent is not an Event instance or doesn't have start/end\n */\n overlaps(otherEvent) {\n if (otherEvent instanceof Event) {\n // Events don't overlap if one ends before the other starts\n return !(this.end <= otherEvent.start || this.start >= otherEvent.end);\n } else if (otherEvent && otherEvent.start && otherEvent.end) {\n // Allow checking against time ranges\n return !(this.end <= otherEvent.start || this.start >= otherEvent.end);\n } else {\n throw new Error('Parameter must be an Event instance or have start/end properties');\n }\n }\n\n /**\n * Check if event contains a specific datetime\n * @param {Date|string} datetime - The datetime to check\n * @returns {boolean} True if the datetime falls within the event\n */\n contains(datetime) {\n if (!(datetime instanceof Date)) {\n datetime = new Date(datetime);\n }\n return datetime >= this.start && datetime <= this.end;\n }\n\n /**\n * Clone the event with optional updates\n * @param {Partial<import('../../types.js').EventData>} [updates={}] - Properties to update in the clone\n * @returns {Event} New Event instance with updated properties\n */\n clone(updates = {}) {\n return new Event({\n id: this.id,\n title: this.title,\n start: new Date(this.start),\n end: new Date(this.end),\n allDay: this.allDay,\n description: this.description,\n location: this.location,\n color: this.color,\n backgroundColor: this.backgroundColor,\n borderColor: this.borderColor,\n textColor: this.textColor,\n recurring: this.recurring,\n recurrenceRule: this.recurrenceRule,\n timeZone: this.timeZone,\n status: this.status,\n visibility: this.visibility,\n organizer: this.organizer ? { ...this.organizer } : null,\n attendees: this.attendees.map(a => ({ ...a })),\n reminders: this.reminders.map(r => ({ ...r })),\n categories: [...this.categories],\n attachments: this.attachments.map(a => ({ ...a })),\n conferenceData: this.conferenceData ? { ...this.conferenceData } : null,\n metadata: { ...this.metadata },\n ...updates\n });\n }\n\n /**\n * Convert event to plain object\n * @returns {import('../../types.js').EventData} Plain object representation of the event\n */\n toObject() {\n return {\n id: this.id,\n title: this.title,\n start: this.start.toISOString(),\n end: this.end.toISOString(),\n allDay: this.allDay,\n description: this.description,\n location: this.location,\n color: this.color,\n backgroundColor: this.backgroundColor,\n borderColor: this.borderColor,\n textColor: this.textColor,\n recurring: this.recurring,\n recurrenceRule: this.recurrenceRule,\n timeZone: this.timeZone,\n status: this.status,\n visibility: this.visibility,\n organizer: this.organizer,\n attendees: this.attendees,\n reminders: this.reminders,\n categories: this.categories,\n attachments: this.attachments,\n conferenceData: this.conferenceData,\n metadata: { ...this.metadata }\n };\n }\n\n /**\n * Create Event from plain object\n * @param {import('../../types.js').EventData} obj - Plain object with event properties\n * @returns {Event} New Event instance\n */\n static fromObject(obj) {\n return new Event(obj);\n }\n\n /**\n * Compare events for equality\n * @param {Event} other - The other event\n * @returns {boolean} True if events are equal\n */\n equals(other) {\n if (!(other instanceof Event)) return false;\n\n return (\n this.id === other.id &&\n this.title === other.title &&\n this.start.getTime() === other.start.getTime() &&\n this.end.getTime() === other.end.getTime() &&\n this.allDay === other.allDay &&\n this.description === other.description &&\n this.location === other.location &&\n this.recurring === other.recurring &&\n this.recurrenceRule === other.recurrenceRule &&\n this.status === other.status\n );\n }\n\n // ============ Attendee Management Methods ============\n\n /**\n * Add an attendee to the event\n * @param {import('../../types.js').Attendee} attendee - Attendee to add\n * @returns {boolean} True if attendee was added, false if already exists\n */\n addAttendee(attendee) {\n if (!attendee || !attendee.email) {\n throw new Error('Attendee must have an email');\n }\n\n // Check if attendee already exists\n if (this.hasAttendee(attendee.email)) {\n return false;\n }\n\n // Generate ID if not provided\n if (!attendee.id) {\n attendee.id = `attendee_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n // Set defaults\n attendee.responseStatus = attendee.responseStatus || 'needs-action';\n attendee.role = attendee.role || 'required';\n\n this.attendees.push(attendee);\n return true;\n }\n\n /**\n * Remove an attendee from the event\n * @param {string} emailOrId - Email or ID of the attendee to remove\n * @returns {boolean} True if attendee was removed\n */\n removeAttendee(emailOrId) {\n const index = this.attendees.findIndex(\n a => a.email === emailOrId || a.id === emailOrId\n );\n\n if (index !== -1) {\n this.attendees.splice(index, 1);\n return true;\n }\n return false;\n }\n\n /**\n * Update an attendee's response status\n * @param {string} email - Attendee's email\n * @param {import('../../types.js').AttendeeResponseStatus} responseStatus - New response status\n * @returns {boolean} True if attendee was updated\n */\n updateAttendeeResponse(email, responseStatus) {\n const attendee = this.getAttendee(email);\n if (attendee) {\n attendee.responseStatus = responseStatus;\n attendee.responseTime = new Date();\n return true;\n }\n return false;\n }\n\n /**\n * Get an attendee by email\n * @param {string} email - Attendee's email\n * @returns {import('../../types.js').Attendee|null} The attendee or null\n */\n getAttendee(email) {\n return this.attendees.find(a => a.email === email) || null;\n }\n\n /**\n * Check if an attendee exists\n * @param {string} email - Attendee's email\n * @returns {boolean} True if attendee exists\n */\n hasAttendee(email) {\n return this.attendees.some(a => a.email === email);\n }\n\n /**\n * Get attendees by response status\n * @param {import('../../types.js').AttendeeResponseStatus} status - Response status to filter by\n * @returns {import('../../types.js').Attendee[]} Filtered attendees\n */\n getAttendeesByStatus(status) {\n return this.attendees.filter(a => a.responseStatus === status);\n }\n\n /**\n * Get count of attendees by response status\n * @returns {Object.<string, number>} Count by status\n */\n getAttendeeCounts() {\n return this.attendees.reduce((counts, attendee) => {\n const status = attendee.responseStatus || 'needs-action';\n counts[status] = (counts[status] || 0) + 1;\n return counts;\n }, {});\n }\n\n // ============ Reminder Management Methods ============\n\n /**\n * Add a reminder to the event\n * @param {import('../../types.js').Reminder} reminder - Reminder to add\n * @returns {boolean} True if reminder was added\n */\n addReminder(reminder) {\n if (!reminder || typeof reminder.minutesBefore !== 'number') {\n throw new Error('Reminder must have minutesBefore property');\n }\n\n // Generate ID if not provided\n if (!reminder.id) {\n reminder.id = `reminder_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n // Set defaults\n reminder.method = reminder.method || 'popup';\n reminder.enabled = reminder.enabled !== false;\n\n // Check for duplicate\n const duplicate = this.reminders.some(\n r => r.method === reminder.method && r.minutesBefore === reminder.minutesBefore\n );\n\n if (duplicate) {\n return false;\n }\n\n this.reminders.push(reminder);\n return true;\n }\n\n /**\n * Remove a reminder from the event\n * @param {string} reminderId - ID of the reminder to remove\n * @returns {boolean} True if reminder was removed\n */\n removeReminder(reminderId) {\n const index = this.reminders.findIndex(r => r.id === reminderId);\n if (index !== -1) {\n this.reminders.splice(index, 1);\n return true;\n }\n return false;\n }\n\n /**\n * Get active reminders\n * @returns {import('../../types.js').Reminder[]} Active reminders\n */\n getActiveReminders() {\n return this.reminders.filter(r => r.enabled !== false);\n }\n\n /**\n * Get reminder trigger times\n * @returns {Date[]} Array of dates when reminders should trigger\n */\n getReminderTriggerTimes() {\n return this.getActiveReminders().map(reminder => {\n const triggerTime = new Date(this.start);\n triggerTime.setMinutes(triggerTime.getMinutes() - reminder.minutesBefore);\n return triggerTime;\n });\n }\n\n // ============ Category Management Methods ============\n\n /**\n * Add a category to the event\n * @param {string} category - Category to add\n * @returns {boolean} True if category was added\n */\n addCategory(category) {\n if (!category || typeof category !== 'string') {\n throw new Error('Category must be a non-empty string');\n }\n\n const normalizedCategory = category.trim().toLowerCase();\n if (!this.hasCategory(normalizedCategory)) {\n this.categories.push(normalizedCategory);\n return true;\n }\n return false;\n }\n\n /**\n * Remove a category from the event\n * @param {string} category - Category to remove\n * @returns {boolean} True if category was removed\n */\n removeCategory(category) {\n const normalizedCategory = category.trim().toLowerCase();\n const index = this.categories.findIndex(\n c => c.toLowerCase() === normalizedCategory\n );\n\n if (index !== -1) {\n this.categories.splice(index, 1);\n return true;\n }\n return false;\n }\n\n /**\n * Get primary category (first in array) for backward compatibility\n * @returns {string|null} Primary category or null\n */\n get category() {\n return this.categories && this.categories.length > 0 ? this.categories[0] : null;\n }\n\n /**\n * Check if event has a specific category\n * @param {string} category - Category to check\n * @returns {boolean} True if event has the category\n */\n hasCategory(category) {\n const normalizedCategory = category.trim().toLowerCase();\n return this.categories.some(c => c.toLowerCase() === normalizedCategory);\n }\n\n /**\n * Check if event has any of the specified categories\n * @param {string[]} categories - Categories to check\n * @returns {boolean} True if event has any of the categories\n */\n hasAnyCategory(categories) {\n return categories.some(category => this.hasCategory(category));\n }\n\n /**\n * Check if event has all of the specified categories\n * @param {string[]} categories - Categories to check\n * @returns {boolean} True if event has all of the categories\n */\n hasAllCategories(categories) {\n return categories.every(category => this.hasCategory(category));\n }\n\n // ============ Validation Methods ============\n\n /**\n * Validate attendees\n * @private\n * @throws {Error} If attendees are invalid\n */\n _validateAttendees() {\n for (const attendee of this.attendees) {\n if (!attendee.email) {\n throw new Error('All attendees must have an email address');\n }\n if (!attendee.name) {\n attendee.name = attendee.email; // Use email as fallback name\n }\n if (!this._isValidEmail(attendee.email)) {\n throw new Error(`Invalid attendee email: ${attendee.email}`);\n }\n }\n }\n\n /**\n * Validate reminders\n * @private\n * @throws {Error} If reminders are invalid\n */\n _validateReminders() {\n for (const reminder of this.reminders) {\n if (typeof reminder.minutesBefore !== 'number' || reminder.minutesBefore < 0) {\n throw new Error('Reminder minutesBefore must be a positive number');\n }\n\n const validMethods = ['email', 'popup', 'sms'];\n if (!validMethods.includes(reminder.method)) {\n throw new Error(`Invalid reminder method: ${reminder.method}`);\n }\n }\n }\n\n /**\n * Validate email address\n * @private\n * @param {string} email - Email to validate\n * @returns {boolean} True if email is valid\n */\n _isValidEmail(email) {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n }\n\n // ============ Enhanced Getters ============\n\n /**\n * Check if the event is cancelled\n * @returns {boolean} True if event is cancelled\n */\n get isCancelled() {\n return this.status === 'cancelled';\n }\n\n /**\n * Check if the event is tentative\n * @returns {boolean} True if event is tentative\n */\n get isTentative() {\n return this.status === 'tentative';\n }\n\n /**\n * Check if the event is confirmed\n * @returns {boolean} True if event is confirmed\n */\n get isConfirmed() {\n return this.status === 'confirmed';\n }\n\n /**\n * Check if the event is private\n * @returns {boolean} True if event is private\n */\n get isPrivate() {\n return this.visibility === 'private';\n }\n\n /**\n * Check if the event is public\n * @returns {boolean} True if event is public\n */\n get isPublic() {\n return this.visibility === 'public';\n }\n\n /**\n * Check if the event has attendees\n * @returns {boolean} True if event has attendees\n */\n get hasAttendees() {\n return this.attendees.length > 0;\n }\n\n /**\n * Check if the event has reminders\n * @returns {boolean} True if event has reminders\n */\n get hasReminders() {\n return this.reminders.length > 0;\n }\n\n /**\n * Check if the event is a meeting (has attendees or conference data)\n * @returns {boolean} True if event is a meeting\n */\n get isMeeting() {\n return this.hasAttendees || this.conferenceData !== null;\n }\n\n /**\n * Check if the event is virtual (has conference data)\n * @returns {boolean} True if event is virtual\n */\n get isVirtual() {\n return this.conferenceData !== null;\n }\n}","/**\n * DateUtils - Date manipulation utilities\n * Pure functions, no external dependencies\n * Locker Service compatible\n */\nexport class DateUtils {\n /**\n * Get the start of a day\n * @param {Date} date - The date\n * @returns {Date}\n */\n static startOfDay(date) {\n const result = new Date(date);\n result.setHours(0, 0, 0, 0);\n return result;\n }\n\n /**\n * Get the end of a day\n * @param {Date} date - The date\n * @returns {Date}\n */\n static endOfDay(date) {\n const result = new Date(date);\n result.setHours(23, 59, 59, 999);\n return result;\n }\n\n /**\n * Get the start of a week\n * @param {Date} date - The date\n * @param {number} [weekStartsOn=0] - 0 = Sunday, 1 = Monday, etc.\n * @returns {Date} Start of the week\n */\n static startOfWeek(date, weekStartsOn = 0) {\n const result = new Date(date);\n const day = result.getDay();\n const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;\n\n // Use setTime to handle month/year boundaries correctly\n result.setTime(result.getTime() - (diff * 24 * 60 * 60 * 1000));\n result.setHours(0, 0, 0, 0);\n return result;\n }\n\n /**\n * Get the end of a week\n * @param {Date} date - The date\n * @param {number} weekStartsOn - 0 = Sunday, 1 = Monday, etc.\n * @returns {Date}\n */\n static endOfWeek(date, weekStartsOn = 0) {\n const result = DateUtils.startOfWeek(date, weekStartsOn);\n // Use setTime to handle month/year boundaries correctly\n result.setTime(result.getTime() + (6 * 24 * 60 * 60 * 1000));\n result.setHours(23, 59, 59, 999);\n return result;\n }\n\n /**\n * Get the start of a month\n * @param {Date} date - The date\n * @returns {Date}\n */\n static startOfMonth(date) {\n return new Date(date.getFullYear(), date.getMonth(), 1, 0, 0, 0, 0);\n }\n\n /**\n * Get the end of a month\n * @param {Date} date - The date\n * @returns {Date}\n */\n static endOfMonth(date) {\n return new Date(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59, 999);\n }\n\n /**\n * Get the start of a year\n * @param {Date} date - The date\n * @returns {Date}\n */\n static startOfYear(date) {\n return new Date(date.getFullYear(), 0, 1, 0, 0, 0, 0);\n }\n\n /**\n * Get the end of a year\n * @param {Date} date - The date\n * @returns {Date}\n */\n static endOfYear(date) {\n return new Date(date.getFullYear(), 11, 31, 23, 59, 59, 999);\n }\n\n /**\n * Add days to a date\n * @param {Date} date - The date\n * @param {number} days - Number of days to add (can be negative)\n * @returns {Date}\n */\n static addDays(date, days) {\n const result = new Date(date);\n // Use setTime to handle month/year boundaries correctly\n result.setTime(result.getTime() + (days * 24 * 60 * 60 * 1000));\n return result;\n }\n\n /**\n * Add weeks to a date\n * @param {Date} date - The date\n * @param {number} weeks - Number of weeks to add\n * @returns {Date}\n */\n static addWeeks(date, weeks) {\n return DateUtils.addDays(date, weeks * 7);\n }\n\n /**\n * Add months to a date\n * @param {Date} date - The date\n * @param {number} months - Number of months to add\n * @returns {Date}\n */\n static addMonths(date, months) {\n const result = new Date(date);\n const dayOfMonth = result.getDate();\n result.setMonth(result.getMonth() + months);\n\n // Handle edge case where day doesn't exist in new month\n if (result.getDate() !== dayOfMonth) {\n result.setDate(0); // Go to last day of previous month\n }\n\n return result;\n }\n\n /**\n * Add years to a date\n * @param {Date} date - The date\n * @param {number} years - Number of years to add\n * @returns {Date}\n */\n static addYears(date, years) {\n const result = new Date(date);\n result.setFullYear(result.getFullYear() + years);\n return result;\n }\n\n /**\n * Get a consistent UTC date string for indexing (YYYY-MM-DD format)\n * @param {Date} date - The date\n * @returns {string} UTC date string\n */\n static getUTCDateString(date) {\n const year = date.getUTCFullYear();\n const month = String(date.getUTCMonth() + 1).padStart(2, '0');\n const day = String(date.getUTCDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n /**\n * Get a consistent local date string for indexing (YYYY-MM-DD format)\n * @param {Date} date - The date\n * @returns {string} Local date string\n */\n static getLocalDateString(date) {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n /**\n * Check if a date is today\n * @param {Date} date - The date to check\n * @returns {boolean}\n */\n static isToday(date) {\n const today = new Date();\n return date.toDateString() === today.toDateString();\n }\n\n /**\n * Check if a date is in the past\n * @param {Date} date - The date to check\n * @returns {boolean}\n */\n static isPast(date) {\n return date < new Date();\n }\n\n /**\n * Check if a date is in the future\n * @param {Date} date - The date to check\n * @returns {boolean}\n */\n static isFuture(date) {\n return date > new Date();\n }\n\n /**\n * Check if two dates are on the same day\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {boolean}\n */\n static isSameDay(date1, date2) {\n return date1.getFullYear() === date2.getFullYear() &&\n date1.getMonth() === date2.getMonth() &&\n date1.getDate() === date2.getDate();\n }\n\n /**\n * Check if two dates are in the same week\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @param {number} weekStartsOn - 0 = Sunday, 1 = Monday, etc.\n * @returns {boolean}\n */\n static isSameWeek(date1, date2, weekStartsOn = 0) {\n const week1Start = DateUtils.startOfWeek(date1, weekStartsOn);\n const week2Start = DateUtils.startOfWeek(date2, weekStartsOn);\n return week1Start.toDateString() === week2Start.toDateString();\n }\n\n /**\n * Check if two dates are in the same month\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {boolean}\n */\n static isSameMonth(date1, date2) {\n return date1.getFullYear() === date2.getFullYear() &&\n date1.getMonth() === date2.getMonth();\n }\n\n /**\n * Check if two dates are in the same year\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {boolean}\n */\n static isSameYear(date1, date2) {\n return date1.getFullYear() === date2.getFullYear();\n }\n\n /**\n * Get the difference in days between two dates\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {number}\n */\n static differenceInDays(date1, date2) {\n const diff = date1.getTime() - date2.getTime();\n return Math.floor(diff / (1000 * 60 * 60 * 24));\n }\n\n /**\n * Get the difference in weeks between two dates\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {number}\n */\n static differenceInWeeks(date1, date2) {\n return Math.floor(DateUtils.differenceInDays(date1, date2) / 7);\n }\n\n /**\n * Get the difference in months between two dates\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {number}\n */\n static differenceInMonths(date1, date2) {\n const yearDiff = date1.getFullYear() - date2.getFullYear();\n const monthDiff = date1.getMonth() - date2.getMonth();\n return yearDiff * 12 + monthDiff;\n }\n\n /**\n * Get the week number of a date\n * @param {Date} date - The date\n * @returns {number}\n */\n static getWeekNumber(date) {\n const firstDayOfYear = new Date(date.getFullYear(), 0, 1);\n const pastDaysOfYear = (date - firstDayOfYear) / 86400000;\n return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);\n }\n\n /**\n * Get the day of week for a date\n * @param {Date} date - The date\n * @param {number} weekStartsOn - 0 = Sunday, 1 = Monday, etc.\n * @returns {number} 0-6 where 0 is the first day of the week\n */\n static getDayOfWeek(date, weekStartsOn = 0) {\n const day = date.getDay();\n return (day - weekStartsOn + 7) % 7;\n }\n\n /**\n * Get days in a month\n * @param {Date} date - Any date in the month\n * @returns {number}\n */\n static getDaysInMonth(date) {\n return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();\n }\n\n /**\n * Format a date using Intl.DateTimeFormat\n * @param {Date} date - The date to format\n * @param {string} locale - The locale\n * @param {Object} options - Intl.DateTimeFormat options\n * @returns {string}\n */\n static format(date, locale = 'en-US', options = {}) {\n return new Intl.DateTimeFormat(locale, options).format(date);\n }\n\n /**\n * Get month name\n * @param {Date} date - The date\n * @param {string} locale - The locale\n * @param {string} format - 'long', 'short', or 'narrow'\n * @returns {string}\n */\n static getMonthName(date, locale = 'en-US', format = 'long') {\n return DateUtils.format(date, locale, { month: format });\n }\n\n /**\n * Get day name\n * @param {Date} date - The date\n * @param {string} locale - The locale\n * @param {string} format - 'long', 'short', or 'narrow'\n * @returns {string}\n */\n static getDayName(date, locale = 'en-US', format = 'long') {\n return DateUtils.format(date, locale, { weekday: format });\n }\n\n /**\n * Format time\n * @param {Date} date - The date\n * @param {string} locale - The locale\n * @param {boolean} use24Hour - Use 24-hour format\n * @returns {string}\n */\n static formatTime(date, locale = 'en-US', use24Hour = false) {\n return DateUtils.format(date, locale, {\n hour: 'numeric',\n minute: '2-digit',\n hour12: !use24Hour\n });\n }\n\n /**\n * Parse a time string (HH:MM) to hours and minutes\n * @param {string} timeString - Time string like \"09:30\"\n * @returns {{hours: number, minutes: number}}\n */\n static parseTime(timeString) {\n const [hours, minutes] = timeString.split(':').map(Number);\n return { hours, minutes };\n }\n\n /**\n * Set time on a date\n * @param {Date} date - The date\n * @param {string} timeString - Time string like \"09:30\"\n * @returns {Date}\n */\n static setTime(date, timeString) {\n const result = new Date(date);\n const { hours, minutes } = DateUtils.parseTime(timeString);\n result.setHours(hours, minutes, 0, 0);\n return result;\n }\n\n /**\n * Check if a year is a leap year\n * @param {number} year - The year\n * @returns {boolean}\n */\n static isLeapYear(year) {\n return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);\n }\n\n /**\n * Get an array of dates between start and end\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @returns {Date[]}\n */\n static getDateRange(start, end) {\n const dates = [];\n const current = new Date(start);\n const endTime = end.getTime();\n\n while (current.getTime() <= endTime) {\n dates.push(new Date(current));\n // Use setTime to handle month/year boundaries correctly\n current.setTime(current.getTime() + (24 * 60 * 60 * 1000));\n }\n\n return dates;\n }\n\n /**\n * Clone a date\n * @param {Date} date - The date to clone\n * @returns {Date}\n */\n static clone(date) {\n return new Date(date);\n }\n\n /**\n * Validate if a value is a valid date\n * @param {*} value - Value to check\n * @returns {boolean}\n */\n static isValidDate(value) {\n return value instanceof Date && !isNaN(value.getTime());\n }\n\n /**\n * Convert a date to a specific timezone\n * @param {Date} date - The date to convert\n * @param {string} timeZone - IANA timezone string (e.g., 'America/New_York')\n * @returns {Date} - Date object adjusted for timezone\n */\n static toTimeZone(date, timeZone) {\n // Get the date string in the target timezone\n const formatter = new Intl.DateTimeFormat('en-US', {\n timeZone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false\n });\n\n const parts = formatter.formatToParts(date);\n const dateObj = {};\n parts.forEach(part => {\n if (part.type !== 'literal') {\n dateObj[part.type] = part.value;\n }\n });\n\n // Create new date in the target timezone\n return new Date(\n `${dateObj.year}-${dateObj.month}-${dateObj.day}T${dateObj.hour}:${dateObj.minute}:${dateObj.second}`\n );\n }\n\n /**\n * Get timezone offset in minutes for a date\n * @param {Date} date - The date\n * @param {string} timeZone - IANA timezone string\n * @returns {number} - Offset in minutes\n */\n static getTimezoneOffset(date, timeZone) {\n const utcDate = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));\n const tzDate = new Date(date.toLocaleString('en-US', { timeZone }));\n return (utcDate.getTime() - tzDate.getTime()) / 60000;\n }\n\n /**\n * Check if DST is in effect for a date in a timezone\n * @param {Date} date - The date to check\n * @param {string} timeZone - IANA timezone string\n * @returns {boolean}\n */\n static isDST(date, timeZone) {\n const jan = new Date(date.getFullYear(), 0, 1);\n const jul = new Date(date.getFullYear(), 6, 1);\n const janOffset = DateUtils.getTimezoneOffset(jan, timeZone);\n const julOffset = DateUtils.getTimezoneOffset(jul, timeZone);\n const currentOffset = DateUtils.getTimezoneOffset(date, timeZone);\n\n return Math.max(janOffset, julOffset) === currentOffset;\n }\n\n /**\n * Add time accounting for DST transitions\n * @param {Date} date - The date\n * @param {number} hours - Hours to add\n * @param {string} timeZone - IANA timezone string\n * @returns {Date}\n */\n static addHoursWithDST(date, hours, timeZone) {\n const result = new Date(date);\n const originalOffset = DateUtils.getTimezoneOffset(date, timeZone);\n\n // Add hours\n result.setTime(result.getTime() + (hours * 60 * 60 * 1000));\n\n // Check if DST transition occurred\n const newOffset = DateUtils.getTimezoneOffset(result, timeZone);\n if (originalOffset !== newOffset) {\n // Adjust for DST change\n const dstAdjustment = (newOffset - originalOffset) * 60000;\n result.setTime(result.getTime() + dstAdjustment);\n }\n\n return result;\n }\n\n /**\n * Create a date in a specific timezone\n * @param {number} year\n * @param {number} month - 0-indexed\n * @param {number} day\n * @param {number} hour\n * @param {number} minute\n * @param {number} second\n * @param {string} timeZone - IANA timezone string\n * @returns {Date}\n */\n static createInTimeZone(year, month, day, hour = 0, minute = 0, second = 0, timeZone) {\n // Create date string in ISO format\n const dateStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;\n const timeStr = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}:${String(second).padStart(2, '0')}`;\n\n // Use Intl API to get the UTC time for this local time in the timezone\n const formatter = new Intl.DateTimeFormat('en-US', {\n timeZone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false\n });\n\n // Parse the local date in the target timezone\n const localDate = new Date(`${dateStr}T${timeStr}`);\n\n // Get offset and adjust\n const offset = DateUtils.getTimezoneOffset(localDate, timeZone);\n const utcTime = localDate.getTime() + (offset * 60000);\n\n return new Date(utcTime);\n }\n}","/**\n * RRuleParser - Full RFC 5545 compliant RRULE parser\n * Supports all RFC 5545 recurrence rule features\n */\n\nexport class RRuleParser {\n /**\n * Parse an RRULE string into a structured rule object\n * @param {string|Object} rrule - RRULE string or rule object\n * @returns {Object} Parsed rule object\n */\n static parse(rrule) {\n // If already an object, validate and return\n if (typeof rrule === 'object') {\n return this.validateRule(rrule);\n }\n\n const rule = {\n freq: null,\n interval: 1,\n count: null,\n until: null,\n byDay: [],\n byWeekNo: [],\n byMonth: [],\n byMonthDay: [],\n byYearDay: [],\n bySetPos: [],\n byHour: [],\n byMinute: [],\n bySecond: [],\n wkst: 'MO', // Week start day\n exceptions: [],\n tzid: null\n };\n\n // Parse RRULE string\n const parts = rrule.toUpperCase().split(';');\n\n for (const part of parts) {\n const [key, value] = part.split('=');\n\n switch (key) {\n case 'FREQ':\n rule.freq = this.parseFrequency(value);\n break;\n\n case 'INTERVAL':\n rule.interval = parseInt(value, 10);\n if (rule.interval < 1) rule.interval = 1;\n break;\n\n case 'COUNT':\n rule.count = parseInt(value, 10);\n break;\n\n case 'UNTIL':\n rule.until = this.parseDateTime(value);\n break;\n\n case 'BYDAY':\n rule.byDay = this.parseByDay(value);\n break;\n\n case 'BYWEEKNO':\n rule.byWeekNo = this.parseIntList(value);\n break;\n\n case 'BYMONTH':\n rule.byMonth = this.parseIntList(value);\n break;\n\n case 'BYMONTHDAY':\n rule.byMonthDay = this.parseIntList(value);\n break;\n\n case 'BYYEARDAY':\n rule.byYearDay = this.parseIntList(value);\n break;\n\n case 'BYSETPOS':\n rule.bySetPos = this.parseIntList(value);\n break;\n\n case 'BYHOUR':\n rule.byHour = this.parseIntList(value);\n break;\n\n case 'BYMINUTE':\n rule.byMinute = this.parseIntList(value);\n break;\n\n case 'BYSECOND':\n rule.bySecond = this.parseIntList(value);\n break;\n\n case 'WKST':\n rule.wkst = value;\n break;\n\n case 'EXDATE':\n rule.exceptions = this.parseExceptionDates(value);\n break;\n\n case 'TZID':\n rule.tzid = value;\n break;\n }\n }\n\n return this.validateRule(rule);\n }\n\n /**\n * Parse frequency value\n * @private\n */\n static parseFrequency(freq) {\n const validFrequencies = ['SECONDLY', 'MINUTELY', 'HOURLY', 'DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY'];\n return validFrequencies.includes(freq) ? freq : 'DAILY';\n }\n\n /**\n * Parse BYDAY value\n * Returns array of strings like ['MO', '2TU', '-1FR'] for compatibility with RecurrenceEngine\n * @private\n */\n static parseByDay(value) {\n const days = value.split(',');\n const weekDays = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'];\n const result = [];\n\n for (const day of days) {\n const trimmed = day.trim().toUpperCase();\n const match = trimmed.match(/^([+-]?\\d*)([A-Z]{2})$/);\n if (match) {\n const [_, nth, weekday] = match;\n if (weekDays.includes(weekday)) {\n // Return string format for RecurrenceEngine compatibility\n // e.g., 'MO', '2MO', '-1FR'\n result.push(nth ? `${nth}${weekday}` : weekday);\n }\n }\n }\n\n return result;\n }\n\n /**\n * Parse comma-separated integer list\n * @private\n */\n static parseIntList(value) {\n return value.split(',').map(v => parseInt(v.trim(), 10)).filter(v => !isNaN(v));\n }\n\n /**\n * Parse date/datetime value\n * @private\n */\n static parseDateTime(value) {\n // Handle different date formats\n // YYYYMMDD\n if (value.length === 8) {\n const year = parseInt(value.substr(0, 4), 10);\n const month = parseInt(value.substr(4, 2), 10) - 1;\n const day = parseInt(value.substr(6, 2), 10);\n return new Date(year, month, day);\n }\n\n // YYYYMMDDTHHMMSS\n if (value.length === 15 && value[8] === 'T') {\n const year = parseInt(value.substr(0, 4), 10);\n const month = parseInt(value.substr(4, 2), 10) - 1;\n const day = parseInt(value.substr(6, 2), 10);\n const hour = parseInt(value.substr(9, 2), 10);\n const minute = parseInt(value.substr(11, 2), 10);\n const second = parseInt(value.substr(13, 2), 10);\n return new Date(year, month, day, hour, minute, second);\n }\n\n // YYYYMMDDTHHMMSSZ (UTC)\n if (value.length === 16 && value[8] === 'T' && value[15] === 'Z') {\n const year = parseInt(value.substr(0, 4), 10);\n const month = parseInt(value.substr(4, 2), 10) - 1;\n const day = parseInt(value.substr(6, 2), 10);\n const hour = parseInt(value.substr(9, 2), 10);\n const minute = parseInt(value.substr(11, 2), 10);\n const second = parseInt(value.substr(13, 2), 10);\n return new Date(Date.UTC(year, month, day, hour, minute, second));\n }\n\n // Try standard date parse as fallback\n return new Date(value);\n }\n\n /**\n * Parse exception dates\n * @private\n */\n static parseExceptionDates(value) {\n const dates = value.split(',');\n return dates.map(date => this.parseDateTime(date.trim()));\n }\n\n /**\n * Validate and normalize rule\n * @private\n */\n static validateRule(rule) {\n // Ensure frequency is set\n if (!rule.freq) {\n rule.freq = 'DAILY';\n }\n\n // Cannot have both COUNT and UNTIL\n if (rule.count && rule.until) {\n throw new Error('RRULE cannot have both COUNT and UNTIL');\n }\n\n // Validate interval\n if (rule.interval < 1) {\n rule.interval = 1;\n }\n\n // Validate by* arrays\n const validateArray = (arr, min, max) => {\n return arr.filter(v => v >= min && v <= max);\n };\n\n rule.byMonth = validateArray(rule.byMonth || [], 1, 12);\n rule.byMonthDay = validateArray(rule.byMonthDay || [], -31, 31).filter(v => v !== 0);\n rule.byYearDay = validateArray(rule.byYearDay || [], -366, 366).filter(v => v !== 0);\n rule.byWeekNo = validateArray(rule.byWeekNo || [], -53, 53).filter(v => v !== 0);\n rule.byHour = validateArray(rule.byHour || [], 0, 23);\n rule.byMinute = validateArray(rule.byMinute || [], 0, 59);\n rule.bySecond = validateArray(rule.bySecond || [], 0, 59);\n\n return rule;\n }\n\n /**\n * Build RRULE string from rule object\n * @param {Object} rule - Rule object\n * @returns {string} RRULE string\n */\n static buildRRule(rule) {\n const parts = [];\n\n // Required frequency\n parts.push(`FREQ=${rule.freq}`);\n\n // Optional interval\n if (rule.interval && rule.interval > 1) {\n parts.push(`INTERVAL=${rule.interval}`);\n }\n\n // Count or until\n if (rule.count) {\n parts.push(`COUNT=${rule.count}`);\n } else if (rule.until) {\n parts.push(`UNTIL=${this.formatDateTime(rule.until)}`);\n }\n\n // By* rules\n if (rule.byDay && rule.byDay.length > 0) {\n const dayStr = rule.byDay.map(d => {\n return d.nth ? `${d.nth}${d.weekday}` : d.weekday;\n }).join(',');\n parts.push(`BYDAY=${dayStr}`);\n }\n\n if (rule.byMonth && rule.byMonth.length > 0) {\n parts.push(`BYMONTH=${rule.byMonth.join(',')}`);\n }\n\n if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n parts.push(`BYMONTHDAY=${rule.byMonthDay.join(',')}`);\n }\n\n if (rule.byYearDay && rule.byYearDay.length > 0) {\n parts.push(`BYYEARDAY=${rule.byYearDay.join(',')}`);\n }\n\n if (rule.byWeekNo && rule.byWeekNo.length > 0) {\n parts.push(`BYWEEKNO=${rule.byWeekNo.join(',')}`);\n }\n\n if (rule.bySetPos && rule.bySetPos.length > 0) {\n parts.push(`BYSETPOS=${rule.bySetPos.join(',')}`);\n }\n\n if (rule.byHour && rule.byHour.length > 0) {\n parts.push(`BYHOUR=${rule.byHour.join(',')}`);\n }\n\n if (rule.byMinute && rule.byMinute.length > 0) {\n parts.push(`BYMINUTE=${rule.byMinute.join(',')}`);\n }\n\n if (rule.bySecond && rule.bySecond.length > 0) {\n parts.push(`BYSECOND=${rule.bySecond.join(',')}`);\n }\n\n // Week start\n if (rule.wkst && rule.wkst !== 'MO') {\n parts.push(`WKST=${rule.wkst}`);\n }\n\n return parts.join(';');\n }\n\n /**\n * Format date/datetime for RRULE\n * @private\n */\n static formatDateTime(date) {\n const year = date.getUTCFullYear();\n const month = String(date.getUTCMonth() + 1).padStart(2, '0');\n const day = String(date.getUTCDate()).padStart(2, '0');\n const hour = String(date.getUTCHours()).padStart(2, '0');\n const minute = String(date.getUTCMinutes()).padStart(2, '0');\n const second = String(date.getUTCSeconds()).padStart(2, '0');\n\n return `${year}${month}${day}T${hour}${minute}${second}Z`;\n }\n\n /**\n * Get human-readable description of rule\n * @param {Object} rule - Parsed rule object\n * @returns {string} Human-readable description\n */\n static getDescription(rule) {\n const freqMap = {\n 'SECONDLY': 'second',\n 'MINUTELY': 'minute',\n 'HOURLY': 'hour',\n 'DAILY': 'day',\n 'WEEKLY': 'week',\n 'MONTHLY': 'month',\n 'YEARLY': 'year'\n };\n\n const weekdayMap = {\n 'SU': 'Sunday',\n 'MO': 'Monday',\n 'TU': 'Tuesday',\n 'WE': 'Wednesday',\n 'TH': 'Thursday',\n 'FR': 'Friday',\n 'SA': 'Saturday'\n };\n\n const nthMap = {\n 1: 'first',\n 2: 'second',\n 3: 'third',\n 4: 'fourth',\n 5: 'fifth',\n '-1': 'last',\n '-2': 'second to last'\n };\n\n let description = 'Every';\n\n // Interval\n if (rule.interval > 1) {\n description += ` ${rule.interval}`;\n }\n\n // Frequency\n description += ` ${freqMap[rule.freq]}`;\n if (rule.interval > 1) {\n description += 's';\n }\n\n // By day\n if (rule.byDay && rule.byDay.length > 0) {\n if (rule.freq === 'WEEKLY') {\n const days = rule.byDay.map(d => weekdayMap[d.weekday]).join(', ');\n description += ` on ${days}`;\n } else if (rule.freq === 'MONTHLY' || rule.freq === 'YEARLY') {\n const dayDescs = rule.byDay.map(d => {\n if (d.nth) {\n return `the ${nthMap[d.nth] || d.nth} ${weekdayMap[d.weekday]}`;\n }\n return weekdayMap[d.weekday];\n }).join(', ');\n description += ` on ${dayDescs}`;\n }\n }\n\n // By month day\n if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n const days = rule.byMonthDay.map(d => {\n if (d < 0) {\n return `${Math.abs(d)} day(s) from the end`;\n }\n return `day ${d}`;\n }).join(', ');\n description += ` on ${days}`;\n }\n\n // By month\n if (rule.byMonth && rule.byMonth.length > 0) {\n const monthNames = ['January', 'February', 'March', 'April', 'May', 'June',\n 'July', 'August', 'September', 'October', 'November', 'December'];\n const months = rule.byMonth.map(m => monthNames[m - 1]).join(', ');\n description += ` in ${months}`;\n }\n\n // Count or until\n if (rule.count) {\n description += `, ${rule.count} time${rule.count > 1 ? 's' : ''}`;\n } else if (rule.until) {\n description += `, until ${rule.until.toLocaleDateString()}`;\n }\n\n return description;\n }\n}","import { DateUtils } from '../calendar/DateUtils.js';\nimport { TimezoneManager } from '../timezone/TimezoneManager.js';\nimport { RRuleParser } from './RRuleParser.js';\n\n/**\n * RecurrenceEngine - Handles expansion of recurring events\n * Full support for RFC 5545 (iCalendar) RRULE specification\n */\nexport class RecurrenceEngine {\n /**\n * Expand a recurring event into individual occurrences\n * @param {import('./Event.js').Event} event - The recurring event\n * @param {Date} rangeStart - Start of the expansion range\n * @param {Date} rangeEnd - End of the expansion range\n * @param {number} [maxOccurrences=365] - Maximum number of occurrences to generate\n * @param {string} [timezone] - Timezone for expansion (important for DST)\n * @returns {import('../../types.js').EventOccurrence[]} Array of occurrence objects with start/end dates\n */\n static expandEvent(event, rangeStart, rangeEnd, maxOccurrences = 365, timezone = null) {\n if (!event.recurring || !event.recurrenceRule) {\n return [{ start: event.start, end: event.end, timezone: event.timeZone }];\n }\n\n const rule = this.parseRule(event.recurrenceRule);\n const occurrences = [];\n const duration = event.end - event.start;\n const eventTimezone = timezone || event.timeZone || 'UTC';\n const tzManager = new TimezoneManager();\n\n // Work in event's timezone for accurate recurrence calculation\n let currentDate = new Date(event.start);\n let count = 0;\n\n // If UNTIL is specified, use it as the range end\n if (rule.until && rule.until < rangeEnd) {\n rangeEnd = rule.until;\n }\n\n // Track DST transitions for proper timezone handling\n let lastOffset = tzManager.getTimezoneOffset(currentDate, eventTimezone);\n\n while (currentDate <= rangeEnd && count < maxOccurrences) {\n // Check if this occurrence is within the range\n if (currentDate >= rangeStart) {\n const occurrenceStart = new Date(currentDate);\n const occurrenceEnd = new Date(currentDate.getTime() + duration);\n\n // Handle DST transitions\n const currentOffset = tzManager.getTimezoneOffset(occurrenceStart, eventTimezone);\n if (currentOffset !== lastOffset) {\n // Adjust for DST change\n const offsetDiff = lastOffset - currentOffset;\n occurrenceStart.setMinutes(occurrenceStart.getMinutes() + offsetDiff);\n occurrenceEnd.setMinutes(occurrenceEnd.getMinutes() + offsetDiff);\n }\n lastOffset = currentOffset;\n\n // Apply exceptions if any\n if (!this.isException(occurrenceStart, rule, event.id)) {\n occurrences.push({\n start: occurrenceStart,\n end: occurrenceEnd,\n recurringEventId: event.id,\n timezone: eventTimezone,\n originalStart: event.start\n });\n }\n }\n\n // Calculate next occurrence\n currentDate = this.getNextOccurrence(currentDate, rule, eventTimezone);\n count++;\n\n // Check COUNT limit\n if (rule.count && count >= rule.count) {\n break;\n }\n }\n\n return occurrences;\n }\n\n /**\n * Parse an RRULE string into a rule object\n * @param {string|import('../../types.js').RecurrenceRule} ruleString - RRULE string (e.g., \"FREQ=DAILY;INTERVAL=1;COUNT=10\") or rule object\n * @returns {import('../../types.js').RecurrenceRule} Parsed rule object\n */\n static parseRule(ruleString) {\n // Use the new comprehensive parser\n return RRuleParser.parse(ruleString);\n }\n\n /**\n * Calculate the next occurrence based on the rule\n * @param {Date} currentDate - Current occurrence date\n * @param {Object} rule - Recurrence rule object\n * @param {string} [timezone] - Timezone for calculation\n * @returns {Date} Next occurrence date\n */\n static getNextOccurrence(currentDate, rule, timezone = 'UTC') {\n const next = new Date(currentDate);\n\n switch (rule.freq) {\n case 'DAILY':\n next.setDate(next.getDate() + rule.interval);\n break;\n\n case 'WEEKLY':\n if (rule.byDay && rule.byDay.length > 0) {\n // Find next day that matches byDay\n // Limit iterations to prevent infinite loop with malformed byDay\n const maxIterations = 8; // 7 days + 1 for safety\n let iterations = 0;\n next.setDate(next.getDate() + 1);\n while (!this.matchesByDay(next, rule.byDay) && iterations < maxIterations) {\n next.setDate(next.getDate() + 1);\n iterations++;\n }\n // If no match found, fall back to simple weekly interval\n if (iterations >= maxIterations) {\n console.warn('RecurrenceEngine: Invalid byDay rule, falling back to weekly interval');\n next.setDate(next.getDate() + (7 * rule.interval) - maxIterations);\n }\n } else {\n // Simple weekly recurrence\n next.setDate(next.getDate() + (7 * rule.interval));\n }\n break;\n\n case 'MONTHLY':\n if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n // Specific day(s) of month\n const currentMonth = next.getMonth();\n next.setMonth(currentMonth + rule.interval);\n next.setDate(rule.byMonthDay[0]); // Use first specified day\n } else if (rule.byDay && rule.byDay.length > 0) {\n // Specific weekday of month (e.g., \"2nd Tuesday\")\n next.setMonth(next.getMonth() + rule.interval);\n this.setToWeekdayOfMonth(next, rule.byDay[0], rule.bySetPos[0] || 1);\n } else {\n // Same day of month\n next.setMonth(next.getMonth() + rule.interval);\n }\n break;\n\n case 'YEARLY':\n if (rule.byMonth && rule.byMonth.length > 0) {\n next.setFullYear(next.getFullYear() + rule.interval);\n next.setMonth(rule.byMonth[0] - 1); // Months are 0-indexed\n } else {\n next.setFullYear(next.getFullYear() + rule.interval);\n }\n break;\n\n default:\n // Unsupported frequency\n next.setTime(next.getTime() + (24 * 60 * 60 * 1000)); // Daily fallback\n }\n\n return next;\n }\n\n /**\n * Check if a date matches the BYDAY rule\n * @param {Date} date - Date to check\n * @param {Array<string>} byDay - Array of day codes (e.g., ['MO', 'WE', 'FR'])\n * @returns {boolean}\n */\n static matchesByDay(date, byDay) {\n const dayMap = {\n 'SU': 0, 'MO': 1, 'TU': 2, 'WE': 3,\n 'TH': 4, 'FR': 5, 'SA': 6\n };\n\n const dayOfWeek = date.getDay();\n return byDay.some(day => {\n // Handle numbered weekdays (e.g., \"2MO\" for 2nd Monday)\n const match = day.match(/^(-?\\d+)?([A-Z]{2})$/);\n if (match) {\n const weekdayCode = match[2];\n return dayMap[weekdayCode] === dayOfWeek;\n }\n return false;\n });\n }\n\n /**\n * Set date to specific weekday of month\n * @param {Date} date - Date to modify\n * @param {string} weekday - Weekday code (e.g., 'MO', 'TU')\n * @param {number} position - Position in month (1-5, or -1 for last)\n */\n static setToWeekdayOfMonth(date, weekday, position = 1) {\n const dayMap = {\n 'SU': 0, 'MO': 1, 'TU': 2, 'WE': 3,\n 'TH': 4, 'FR': 5, 'SA': 6\n };\n\n // Extract weekday code if it has a number prefix\n const match = weekday.match(/^(-?\\d+)?([A-Z]{2})$/);\n const weekdayCode = match ? match[2] : weekday;\n const targetDay = dayMap[weekdayCode];\n\n date.setDate(1); // Start at first of month\n\n // Find first occurrence of the weekday\n while (date.getDay() !== targetDay) {\n date.setDate(date.getDate() + 1);\n }\n\n // Move to the nth occurrence\n if (position > 1) {\n date.setDate(date.getDate() + (7 * (position - 1)));\n } else if (position === -1) {\n // Last occurrence of the month\n const nextMonth = new Date(date);\n nextMonth.setMonth(nextMonth.getMonth() + 1);\n nextMonth.setDate(0); // Last day of current month\n\n while (nextMonth.getDay() !== targetDay) {\n nextMonth.setDate(nextMonth.getDate() - 1);\n }\n date.setTime(nextMonth.getTime());\n }\n }\n\n /**\n * Check if a date is an exception\n * @param {Date} date - Date to check\n * @param {Object} rule - Rule object with exceptions\n * @param {string} [eventId] - Event ID for better exception tracking\n * @returns {boolean}\n */\n static isException(date, rule, eventId = null) {\n if (!rule.exceptions || rule.exceptions.length === 0) {\n return false;\n }\n\n // Support both date-only and date-time exceptions\n const dateStr = date.toDateString();\n const dateTime = date.getTime();\n\n return rule.exceptions.some(exDate => {\n if (typeof exDate === 'object' && exDate.date) {\n // Enhanced exception format with reason\n const exceptionDate = exDate.date instanceof Date ? exDate.date : new Date(exDate.date);\n if (exDate.matchTime) {\n return Math.abs(exceptionDate.getTime() - dateTime) < 1000; // Within 1 second\n }\n return exceptionDate.toDateString() === dateStr;\n } else {\n // Simple date exception\n const exceptionDate = exDate instanceof Date ? exDate : new Date(exDate);\n return exceptionDate.toDateString() === dateStr;\n }\n });\n }\n\n /**\n * Add exception dates to a recurrence rule\n * @param {Object} rule - Recurrence rule\n * @param {Date|Date[]} exceptions - Exception date(s) to add\n * @param {Object} [options] - Options for exception\n * @returns {Object} Updated rule\n */\n static addExceptions(rule, exceptions, options = {}) {\n if (!rule.exceptions) {\n rule.exceptions = [];\n }\n\n const exceptionArray = Array.isArray(exceptions) ? exceptions : [exceptions];\n\n exceptionArray.forEach(date => {\n if (options.reason || options.matchTime) {\n rule.exceptions.push({\n date: date,\n reason: options.reason,\n matchTime: options.matchTime || false\n });\n } else {\n rule.exceptions.push(date);\n }\n });\n\n return rule;\n }\n\n /**\n * Parse date from RRULE format (YYYYMMDDTHHMMSSZ)\n * @param {string} dateStr - Date string in RRULE format\n * @returns {Date}\n */\n static parseDate(dateStr) {\n if (dateStr.length === 8) {\n // YYYYMMDD\n const year = parseInt(dateStr.substr(0, 4), 10);\n const month = parseInt(dateStr.substr(4, 2), 10) - 1;\n const day = parseInt(dateStr.substr(6, 2), 10);\n return new Date(year, month, day);\n } else if (dateStr.length === 15 || dateStr.length === 16) {\n // YYYYMMDDTHHMMSS[Z]\n const year = parseInt(dateStr.substr(0, 4), 10);\n const month = parseInt(dateStr.substr(4, 2), 10) - 1;\n const day = parseInt(dateStr.substr(6, 2), 10);\n const hour = parseInt(dateStr.substr(9, 2), 10);\n const minute = parseInt(dateStr.substr(11, 2), 10);\n const second = parseInt(dateStr.substr(13, 2), 10);\n\n if (dateStr.endsWith('Z')) {\n return new Date(Date.UTC(year, month, day, hour, minute, second));\n } else {\n return new Date(year, month, day, hour, minute, second);\n }\n }\n\n // Fallback to standard date parsing\n return new Date(dateStr);\n }\n\n /**\n * Generate a human-readable description of the recurrence rule\n * @param {Object|string} rule - Recurrence rule\n * @returns {string} Human-readable description\n */\n static getDescription(rule) {\n if (typeof rule === 'string') {\n rule = this.parseRule(rule);\n }\n\n let description = '';\n const interval = rule.interval || 1;\n\n switch (rule.freq) {\n case 'DAILY':\n description = interval === 1 ? 'Daily' : `Every ${interval} days`;\n break;\n case 'WEEKLY':\n description = interval === 1 ? 'Weekly' : `Every ${interval} weeks`;\n if (rule.byDay && rule.byDay.length > 0) {\n const days = rule.byDay.map(d => this.getDayName(d)).join(', ');\n description += ` on ${days}`;\n }\n break;\n case 'MONTHLY':\n description = interval === 1 ? 'Monthly' : `Every ${interval} months`;\n if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n description += ` on day ${rule.byMonthDay.join(', ')}`;\n }\n break;\n case 'YEARLY':\n description = interval === 1 ? 'Yearly' : `Every ${interval} years`;\n break;\n }\n\n if (rule.count) {\n description += `, ${rule.count} times`;\n } else if (rule.until) {\n description += `, until ${rule.until.toLocaleDateString()}`;\n }\n\n return description;\n }\n\n /**\n * Get day name from RRULE day code\n * @param {string} dayCode - Day code (e.g., 'MO', '2TU')\n * @returns {string} Day name\n */\n static getDayName(dayCode) {\n const dayNames = {\n 'SU': 'Sunday', 'MO': 'Monday', 'TU': 'Tuesday',\n 'WE': 'Wednesday', 'TH': 'Thursday', 'FR': 'Friday',\n 'SA': 'Saturday'\n };\n\n // Extract day code if it has a number prefix\n const match = dayCode.match(/^(-?\\d+)?([A-Z]{2})$/);\n const code = match ? match[2] : dayCode;\n const position = match && match[1] ? parseInt(match[1], 10) : null;\n\n let name = dayNames[code] || dayCode;\n\n if (position) {\n const ordinals = ['', '1st', '2nd', '3rd', '4th', '5th'];\n const ordinal = position === -1 ? 'Last' : (ordinals[position] || `${position}th`);\n name = `${ordinal} ${name}`;\n }\n\n return name;\n }\n}","/**\n * LRU (Least Recently Used) Cache implementation\n * Provides O(1) get and put operations\n */\nexport class LRUCache {\n /**\n * Create a new LRU Cache\n * @param {number} capacity - Maximum number of items in cache\n */\n constructor(capacity = 100) {\n this.capacity = capacity;\n this.cache = new Map();\n this.hits = 0;\n this.misses = 0;\n this.evictions = 0;\n }\n\n /**\n * Get a value from the cache\n * @param {string} key - Cache key\n * @returns {*} Cached value or undefined\n */\n get(key) {\n if (!this.cache.has(key)) {\n this.misses++;\n return undefined;\n }\n\n // Move to end (most recently used)\n const value = this.cache.get(key);\n this.cache.delete(key);\n this.cache.set(key, value);\n this.hits++;\n return value;\n }\n\n /**\n * Put a value in the cache\n * @param {string} key - Cache key\n * @param {*} value - Value to cache\n */\n put(key, value) {\n // Remove if exists to update position\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.capacity) {\n // Remove least recently used (first item)\n const firstKey = this.cache.keys().next().value;\n this.cache.delete(firstKey);\n this.evictions++;\n }\n\n this.cache.set(key, value);\n }\n\n /**\n * Check if key exists in cache\n * @param {string} key - Cache key\n * @returns {boolean} True if key exists\n */\n has(key) {\n return this.cache.has(key);\n }\n\n /**\n * Remove a key from the cache\n * @param {string} key - Cache key\n * @returns {boolean} True if key was removed\n */\n delete(key) {\n return this.cache.delete(key);\n }\n\n /**\n * Clear all cached items\n */\n clear() {\n this.cache.clear();\n this.hits = 0;\n this.misses = 0;\n this.evictions = 0;\n }\n\n /**\n * Get cache statistics\n * @returns {Object} Cache stats\n */\n getStats() {\n const hitRate = this.hits + this.misses > 0\n ? (this.hits / (this.hits + this.misses) * 100).toFixed(2)\n : 0;\n\n return {\n size: this.cache.size,\n capacity: this.capacity,\n hits: this.hits,\n misses: this.misses,\n evictions: this.evictions,\n hitRate: `${hitRate}%`\n };\n }\n\n /**\n * Get all keys in order (least to most recently used)\n * @returns {string[]} Array of keys\n */\n keys() {\n return Array.from(this.cache.keys());\n }\n\n /**\n * Get cache size\n * @returns {number} Number of items in cache\n */\n get size() {\n return this.cache.size;\n }\n}","/**\n * AdaptiveMemoryManager - Dynamically manages cache sizes based on memory pressure\n * Monitors memory usage and adjusts cache capacity to prevent memory issues\n */\n\nexport class AdaptiveMemoryManager {\n constructor(config = {}) {\n this.config = {\n checkInterval: 30000, // Check memory every 30 seconds\n memoryThreshold: 0.8, // Start reducing cache at 80% memory usage\n criticalThreshold: 0.95, // Emergency clear at 95% memory usage\n minCacheSize: 10, // Minimum cache size to maintain\n maxCacheSize: 10000, // Maximum cache size allowed\n adaptiveScaling: true, // Enable/disable adaptive scaling\n ...config\n };\n\n // Cache references\n this.caches = new Map();\n\n // Memory statistics\n this.stats = {\n adjustments: 0,\n emergencyClears: 0,\n lastMemoryUsage: 0,\n lastCheckTime: null,\n cacheResizes: []\n };\n\n // Start monitoring if enabled\n this.monitoringInterval = null;\n if (this.config.adaptiveScaling) {\n this.startMonitoring();\n }\n }\n\n /**\n * Register a cache for management\n * @param {string} name - Cache identifier\n * @param {Object} cache - Cache instance with size/clear methods\n * @param {Object} [options] - Cache-specific options\n */\n registerCache(name, cache, options = {}) {\n this.caches.set(name, {\n cache,\n priority: options.priority || 1, // Higher priority = less likely to be reduced\n currentCapacity: options.initialCapacity || 100,\n minCapacity: options.minCapacity || this.config.minCacheSize,\n maxCapacity: options.maxCapacity || this.config.maxCacheSize,\n scaleFactor: options.scaleFactor || 0.5, // How much to reduce on pressure\n lastAccess: Date.now()\n });\n }\n\n /**\n * Unregister a cache\n * @param {string} name - Cache identifier\n */\n unregisterCache(name) {\n this.caches.delete(name);\n }\n\n /**\n * Start memory monitoring\n */\n startMonitoring() {\n if (this.monitoringInterval) {\n return;\n }\n\n this.monitoringInterval = setInterval(() => {\n this.checkMemoryPressure();\n }, this.config.checkInterval);\n\n // Initial check\n this.checkMemoryPressure();\n }\n\n /**\n * Stop memory monitoring\n */\n stopMonitoring() {\n if (this.monitoringInterval) {\n clearInterval(this.monitoringInterval);\n this.monitoringInterval = null;\n }\n }\n\n /**\n * Check memory pressure and adjust caches\n */\n async checkMemoryPressure() {\n const memoryUsage = await this.getMemoryUsage();\n this.stats.lastMemoryUsage = memoryUsage;\n this.stats.lastCheckTime = new Date();\n\n if (memoryUsage > this.config.criticalThreshold) {\n // Emergency clear - clear all caches\n this.emergencyClear();\n } else if (memoryUsage > this.config.memoryThreshold) {\n // Memory pressure - reduce cache sizes\n this.reduceCacheSizes(memoryUsage);\n } else if (memoryUsage < this.config.memoryThreshold - 0.2) {\n // Memory available - can increase cache sizes\n this.increaseCacheSizes();\n }\n }\n\n /**\n * Get current memory usage percentage\n * @returns {Promise<number>} Memory usage as percentage (0-1)\n */\n async getMemoryUsage() {\n // Browser environment\n if (typeof performance !== 'undefined' && performance.memory) {\n const memInfo = performance.memory;\n if (memInfo.jsHeapSizeLimit && memInfo.usedJSHeapSize) {\n return memInfo.usedJSHeapSize / memInfo.jsHeapSizeLimit;\n }\n }\n\n // Node.js environment - use indirect access to avoid LWC static analysis\n try {\n const g = typeof globalThis !== 'undefined' ? globalThis : {};\n const p = g.process;\n if (p && typeof p === 'object') {\n const memFn = p.memoryUsage;\n if (typeof memFn === 'function') {\n const usage = memFn.call(p);\n return usage.heapUsed / usage.heapTotal;\n }\n }\n } catch (e) {\n // Ignore - not in Node.js environment\n }\n\n // Fallback - estimate based on cache sizes\n return this.estimateMemoryUsage();\n }\n\n /**\n * Estimate memory usage based on cache sizes\n * @private\n */\n estimateMemoryUsage() {\n let totalItems = 0;\n let maxItems = 0;\n\n for (const [_, cacheInfo] of this.caches) {\n if (cacheInfo.cache.size !== undefined) {\n totalItems += cacheInfo.cache.size;\n maxItems += cacheInfo.maxCapacity;\n }\n }\n\n return maxItems > 0 ? totalItems / maxItems : 0.5;\n }\n\n /**\n * Reduce cache sizes based on memory pressure\n * @param {number} memoryUsage - Current memory usage percentage\n */\n reduceCacheSizes(memoryUsage) {\n const pressureLevel = (memoryUsage - this.config.memoryThreshold) /\n (this.config.criticalThreshold - this.config.memoryThreshold);\n\n // Sort caches by priority (lower priority first)\n const sortedCaches = Array.from(this.caches.entries())\n .sort((a, b) => a[1].priority - b[1].priority);\n\n for (const [name, cacheInfo] of sortedCaches) {\n const reduction = Math.floor(cacheInfo.currentCapacity * cacheInfo.scaleFactor * pressureLevel);\n const newCapacity = Math.max(\n cacheInfo.minCapacity,\n cacheInfo.currentCapacity - reduction\n );\n\n if (newCapacity < cacheInfo.currentCapacity) {\n this.resizeCache(name, cacheInfo, newCapacity);\n }\n }\n\n this.stats.adjustments++;\n }\n\n /**\n * Increase cache sizes when memory is available\n */\n increaseCacheSizes() {\n for (const [name, cacheInfo] of this.caches) {\n // Only increase if cache is being actively used\n const timeSinceAccess = Date.now() - cacheInfo.lastAccess;\n if (timeSinceAccess < 60000) { // Used in last minute\n const increase = Math.floor(cacheInfo.currentCapacity * 0.2);\n const newCapacity = Math.min(\n cacheInfo.maxCapacity,\n cacheInfo.currentCapacity + increase\n );\n\n if (newCapacity > cacheInfo.currentCapacity) {\n this.resizeCache(name, cacheInfo, newCapacity);\n }\n }\n }\n }\n\n /**\n * Resize a cache\n * @private\n */\n resizeCache(name, cacheInfo, newCapacity) {\n const oldCapacity = cacheInfo.currentCapacity;\n cacheInfo.currentCapacity = newCapacity;\n\n // If cache has a capacity property, update it\n if (cacheInfo.cache.capacity !== undefined) {\n cacheInfo.cache.capacity = newCapacity;\n }\n\n // If cache is now over capacity, evict excess items\n if (cacheInfo.cache.size > newCapacity) {\n this.evictExcessItems(cacheInfo.cache, newCapacity);\n }\n\n // Record resize event\n this.stats.cacheResizes.push({\n cache: name,\n timestamp: new Date(),\n oldCapacity,\n newCapacity,\n reason: newCapacity < oldCapacity ? 'pressure' : 'available'\n });\n\n // Keep only last 100 resize events\n if (this.stats.cacheResizes.length > 100) {\n this.stats.cacheResizes.shift();\n }\n }\n\n /**\n * Evict excess items from cache\n * @private\n */\n evictExcessItems(cache, targetSize) {\n if (cache.size <= targetSize) {\n return;\n }\n\n const itemsToRemove = cache.size - targetSize;\n\n // If cache is a Map or has keys method\n if (cache.keys) {\n const keys = Array.from(cache.keys());\n for (let i = 0; i < itemsToRemove; i++) {\n cache.delete(keys[i]);\n }\n } else if (cache.clear) {\n // Last resort - clear the cache\n cache.clear();\n }\n }\n\n /**\n * Emergency clear all caches\n */\n emergencyClear() {\n for (const [name, cacheInfo] of this.caches) {\n if (cacheInfo.cache.clear) {\n cacheInfo.cache.clear();\n }\n // Reset to minimum capacity\n cacheInfo.currentCapacity = cacheInfo.minCapacity;\n }\n\n this.stats.emergencyClears++;\n console.warn('AdaptiveMemoryManager: Emergency cache clear triggered');\n }\n\n /**\n * Update cache access time\n * @param {string} name - Cache name\n */\n touchCache(name) {\n const cacheInfo = this.caches.get(name);\n if (cacheInfo) {\n cacheInfo.lastAccess = Date.now();\n }\n }\n\n /**\n * Get memory management statistics\n * @returns {Object} Statistics object\n */\n getStats() {\n const cacheStats = {};\n for (const [name, cacheInfo] of this.caches) {\n cacheStats[name] = {\n size: cacheInfo.cache.size || 0,\n capacity: cacheInfo.currentCapacity,\n priority: cacheInfo.priority,\n lastAccess: new Date(cacheInfo.lastAccess)\n };\n }\n\n return {\n ...this.stats,\n memoryUsagePercent: `${(this.stats.lastMemoryUsage * 100).toFixed(2)}%`,\n totalCaches: this.caches.size,\n cacheStats,\n monitoring: this.monitoringInterval !== null\n };\n }\n\n /**\n * Manual trigger for memory pressure check\n */\n async checkNow() {\n await this.checkMemoryPressure();\n }\n\n /**\n * Set memory thresholds\n * @param {Object} thresholds - New threshold values\n */\n setThresholds(thresholds) {\n if (thresholds.memoryThreshold !== undefined) {\n this.config.memoryThreshold = Math.max(0.5, Math.min(0.95, thresholds.memoryThreshold));\n }\n if (thresholds.criticalThreshold !== undefined) {\n this.config.criticalThreshold = Math.max(this.config.memoryThreshold + 0.05, Math.min(1.0, thresholds.criticalThreshold));\n }\n }\n\n /**\n * Destroy manager and clean up\n */\n destroy() {\n this.stopMonitoring();\n this.caches.clear();\n }\n}","/**\n * PerformanceOptimizer - Optimizes calendar operations for large datasets\n * Includes caching, lazy loading, and batch processing with adaptive memory management\n */\n\nimport { LRUCache } from './LRUCache.js';\nimport { AdaptiveMemoryManager } from './AdaptiveMemoryManager.js';\n\nexport class PerformanceOptimizer {\n constructor(config = {}) {\n // Configuration\n this.config = {\n enableCache: true,\n cacheCapacity: 500,\n maxIndexDays: 365,\n batchSize: 100,\n enableMetrics: true,\n cleanupInterval: 3600000, // 1 hour in ms\n maxIndexAge: 30 * 24 * 60 * 60 * 1000, // 30 days in ms\n enableAdaptiveMemory: true, // Enable adaptive memory management\n ...config\n };\n\n // Caches with initial capacities\n this.eventCache = new LRUCache(this.config.cacheCapacity);\n this.queryCache = new LRUCache(Math.floor(this.config.cacheCapacity / 2));\n this.dateRangeCache = new LRUCache(Math.floor(this.config.cacheCapacity / 4));\n\n // Adaptive memory manager\n if (this.config.enableAdaptiveMemory) {\n this.memoryManager = new AdaptiveMemoryManager({\n checkInterval: 30000,\n memoryThreshold: 0.75,\n criticalThreshold: 0.90\n });\n\n // Register caches with memory manager\n this.memoryManager.registerCache('events', this.eventCache, {\n priority: 3, // Highest priority\n initialCapacity: this.config.cacheCapacity,\n minCapacity: 50,\n maxCapacity: 2000\n });\n\n this.memoryManager.registerCache('queries', this.queryCache, {\n priority: 2,\n initialCapacity: Math.floor(this.config.cacheCapacity / 2),\n minCapacity: 25,\n maxCapacity: 1000\n });\n\n this.memoryManager.registerCache('dateRanges', this.dateRangeCache, {\n priority: 1,\n initialCapacity: Math.floor(this.config.cacheCapacity / 4),\n minCapacity: 10,\n maxCapacity: 500\n });\n }\n\n // Lazy loading tracking\n this.lazyIndexes = new Map(); // eventId -> Set of date strings\n this.pendingIndexes = new Map(); // eventId -> Promise\n\n // Batch processing\n this.batchQueue = [];\n this.batchTimer = null;\n this.batchCallbacks = [];\n\n // Performance metrics\n this.metrics = {\n operations: {},\n averageTimes: {},\n slowQueries: []\n };\n\n // Cleanup timer\n this.cleanupTimer = null;\n if (this.config.cleanupInterval > 0) {\n this.startCleanupTimer();\n }\n }\n\n /**\n * Measure operation performance\n * @param {string} operation - Operation name\n * @param {Function} fn - Function to measure\n * @returns {*} Function result\n */\n measure(operation, fn) {\n if (!this.config.enableMetrics) {\n return fn();\n }\n\n const start = performance.now();\n try {\n const result = fn();\n const duration = performance.now() - start;\n this.recordMetric(operation, duration);\n return result;\n } catch (error) {\n const duration = performance.now() - start;\n this.recordMetric(operation, duration, true);\n throw error;\n }\n }\n\n /**\n * Measure async operation performance\n * @param {string} operation - Operation name\n * @param {Function} fn - Async function to measure\n * @returns {Promise<*>} Function result\n */\n async measureAsync(operation, fn) {\n if (!this.config.enableMetrics) {\n return await fn();\n }\n\n const start = performance.now();\n try {\n const result = await fn();\n const duration = performance.now() - start;\n this.recordMetric(operation, duration);\n return result;\n } catch (error) {\n const duration = performance.now() - start;\n this.recordMetric(operation, duration, true);\n throw error;\n }\n }\n\n /**\n * Record performance metric\n * @private\n */\n recordMetric(operation, duration, isError = false) {\n if (!this.metrics.operations[operation]) {\n this.metrics.operations[operation] = {\n count: 0,\n totalTime: 0,\n errors: 0,\n min: Infinity,\n max: 0\n };\n }\n\n const metric = this.metrics.operations[operation];\n metric.count++;\n metric.totalTime += duration;\n metric.min = Math.min(metric.min, duration);\n metric.max = Math.max(metric.max, duration);\n\n if (isError) {\n metric.errors++;\n }\n\n // Update average\n this.metrics.averageTimes[operation] = metric.totalTime / metric.count;\n\n // Track slow queries\n if (duration > 100) {\n this.metrics.slowQueries.push({\n operation,\n duration,\n timestamp: new Date(),\n isError\n });\n\n // Keep only last 100 slow queries\n if (this.metrics.slowQueries.length > 100) {\n this.metrics.slowQueries.shift();\n }\n }\n }\n\n /**\n * Get performance metrics\n * @returns {Object} Performance metrics\n */\n getMetrics() {\n const summary = {\n cacheStats: {\n event: this.eventCache.getStats(),\n query: this.queryCache.getStats(),\n dateRange: this.dateRangeCache.getStats()\n },\n operations: {},\n slowestOperations: [],\n recentSlowQueries: this.metrics.slowQueries.slice(-10),\n memoryManagement: this.memoryManager ? this.memoryManager.getStats() : null\n };\n\n // Process operations\n for (const [op, data] of Object.entries(this.metrics.operations)) {\n summary.operations[op] = {\n count: data.count,\n avgTime: `${(data.totalTime / data.count).toFixed(2)}ms`,\n minTime: `${data.min.toFixed(2)}ms`,\n maxTime: `${data.max.toFixed(2)}ms`,\n totalTime: `${data.totalTime.toFixed(2)}ms`,\n errors: data.errors,\n errorRate: `${((data.errors / data.count) * 100).toFixed(2)}%`\n };\n }\n\n // Find slowest operations\n summary.slowestOperations = Object.entries(this.metrics.averageTimes)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([op, time]) => ({\n operation: op,\n avgTime: `${time.toFixed(2)}ms`\n }));\n\n return summary;\n }\n\n /**\n * Check if event should use lazy indexing\n * @param {import('../events/Event.js').Event} event - Event to check\n * @returns {boolean} True if should use lazy indexing\n */\n shouldUseLazyIndexing(event) {\n const daySpan = Math.ceil(\n (event.end - event.start) / (24 * 60 * 60 * 1000)\n );\n return daySpan > this.config.maxIndexDays;\n }\n\n /**\n * Create lazy index markers for large events\n * @param {import('../events/Event.js').Event} event - Event to index\n * @returns {Object} Index boundaries\n */\n createLazyIndexMarkers(event) {\n const markers = {\n eventId: event.id,\n start: event.start,\n end: event.end,\n indexed: new Set(),\n pending: false\n };\n\n // Index first and last month only initially\n const startMonth = new Date(event.start.getFullYear(), event.start.getMonth(), 1);\n const endMonth = new Date(event.end.getFullYear(), event.end.getMonth(), 1);\n\n markers.indexed.add(this.getMonthKey(startMonth));\n if (this.getMonthKey(startMonth) !== this.getMonthKey(endMonth)) {\n markers.indexed.add(this.getMonthKey(endMonth));\n }\n\n this.lazyIndexes.set(event.id, markers);\n return markers;\n }\n\n /**\n * Expand lazy index for a specific date range\n * @param {string} eventId - Event ID\n * @param {Date} rangeStart - Start of range to index\n * @param {Date} rangeEnd - End of range to index\n * @returns {Promise<Set<string>>} Indexed date strings\n */\n async expandLazyIndex(eventId, rangeStart, rangeEnd) {\n const markers = this.lazyIndexes.get(eventId);\n if (!markers) {\n return new Set();\n }\n\n // Check if already pending\n if (markers.pending) {\n return this.pendingIndexes.get(eventId);\n }\n\n markers.pending = true;\n\n const promise = new Promise((resolve) => {\n // Simulate async indexing (in real app, could be in worker)\n setTimeout(() => {\n const indexed = new Set();\n const current = new Date(rangeStart);\n\n while (current <= rangeEnd) {\n const dateStr = current.toDateString();\n if (!markers.indexed.has(dateStr)) {\n indexed.add(dateStr);\n markers.indexed.add(dateStr);\n }\n current.setDate(current.getDate() + 1);\n }\n\n markers.pending = false;\n this.pendingIndexes.delete(eventId);\n resolve(indexed);\n }, 0);\n });\n\n this.pendingIndexes.set(eventId, promise);\n return promise;\n }\n\n /**\n * Get month key for date\n * @private\n */\n getMonthKey(date) {\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n }\n\n /**\n * Cache event with TTL\n * @param {string} key - Cache key\n * @param {*} value - Value to cache\n * @param {string} cacheType - Type of cache to use\n */\n cache(key, value, cacheType = 'event') {\n if (!this.config.enableCache) return;\n\n let cache;\n let cacheManagerName;\n\n switch (cacheType) {\n case 'event':\n cache = this.eventCache;\n cacheManagerName = 'events';\n break;\n case 'query':\n cache = this.queryCache;\n cacheManagerName = 'queries';\n break;\n case 'dateRange':\n cache = this.dateRangeCache;\n cacheManagerName = 'dateRanges';\n break;\n default:\n return;\n }\n\n cache.put(key, value);\n\n // Update access time in memory manager\n if (this.memoryManager) {\n this.memoryManager.touchCache(cacheManagerName);\n }\n }\n\n /**\n * Get from cache\n * @param {string} key - Cache key\n * @param {string} cacheType - Type of cache\n * @returns {*} Cached value or undefined\n */\n getFromCache(key, cacheType = 'event') {\n if (!this.config.enableCache) return undefined;\n\n let result;\n let cacheManagerName;\n\n switch (cacheType) {\n case 'event':\n result = this.eventCache.get(key);\n cacheManagerName = 'events';\n break;\n case 'query':\n result = this.queryCache.get(key);\n cacheManagerName = 'queries';\n break;\n case 'dateRange':\n result = this.dateRangeCache.get(key);\n cacheManagerName = 'dateRanges';\n break;\n default:\n return undefined;\n }\n\n // Update access time on cache hit\n if (result !== undefined && this.memoryManager) {\n this.memoryManager.touchCache(cacheManagerName);\n }\n\n return result;\n }\n\n /**\n * Invalidate caches for an event\n * @param {string} eventId - Event ID\n */\n invalidateEventCaches(eventId) {\n // Remove from event cache\n this.eventCache.delete(eventId);\n\n // Clear query cache (conservative approach)\n // In production, track which queries include this event\n this.queryCache.clear();\n this.dateRangeCache.clear();\n }\n\n /**\n * Batch operation for efficiency\n * @param {Function} operation - Operation to batch\n * @returns {Promise} Batch result\n */\n batch(operation) {\n return new Promise((resolve, reject) => {\n this.batchQueue.push(operation);\n this.batchCallbacks.push({ resolve, reject });\n\n if (this.batchQueue.length >= this.config.batchSize) {\n this.processBatch();\n } else if (!this.batchTimer) {\n // Process batch after 10ms if not full\n this.batchTimer = setTimeout(() => this.processBatch(), 10);\n }\n });\n }\n\n /**\n * Process batched operations\n * @private\n */\n processBatch() {\n if (this.batchTimer) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n\n if (this.batchQueue.length === 0) return;\n\n const operations = this.batchQueue.splice(0);\n const callbacks = this.batchCallbacks.splice(0);\n\n // Process all operations\n const results = [];\n const errors = [];\n\n operations.forEach((op, index) => {\n try {\n results[index] = op();\n } catch (error) {\n errors[index] = error;\n }\n });\n\n // Resolve callbacks\n callbacks.forEach((callback, index) => {\n if (errors[index]) {\n callback.reject(errors[index]);\n } else {\n callback.resolve(results[index]);\n }\n });\n }\n\n /**\n * Start cleanup timer for old indexes\n * @private\n */\n startCleanupTimer() {\n this.cleanupTimer = setInterval(() => {\n this.cleanupOldIndexes();\n }, this.config.cleanupInterval);\n }\n\n /**\n * Clean up old indexes\n * @private\n */\n cleanupOldIndexes() {\n const now = Date.now();\n const maxAge = this.config.maxIndexAge;\n\n // Clean up lazy indexes for events that are too old\n for (const [eventId, markers] of this.lazyIndexes) {\n if (markers.end.getTime() < now - maxAge) {\n this.lazyIndexes.delete(eventId);\n }\n }\n\n // Clean up slow query log\n if (this.metrics.slowQueries.length > 100) {\n this.metrics.slowQueries = this.metrics.slowQueries.slice(-100);\n }\n }\n\n /**\n * Optimize query by checking cache first\n * @param {string} queryKey - Unique query identifier\n * @param {Function} queryFn - Function to execute if not cached\n * @returns {*} Query result\n */\n optimizeQuery(queryKey, queryFn) {\n // Check cache first\n const cached = this.getFromCache(queryKey, 'query');\n if (cached !== undefined) {\n return cached;\n }\n\n // Execute query and cache result\n const result = this.measure(`query:${queryKey}`, queryFn);\n this.cache(queryKey, result, 'query');\n return result;\n }\n\n /**\n * Destroy optimizer and clean up resources\n */\n destroy() {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = null;\n }\n\n if (this.batchTimer) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n\n this.eventCache.clear();\n this.queryCache.clear();\n this.dateRangeCache.clear();\n this.lazyIndexes.clear();\n this.pendingIndexes.clear();\n }\n}","/**\n * ConflictDetector - Detects scheduling conflicts between events\n * Checks for time overlaps, attendee conflicts, and resource conflicts\n */\n\nimport { DateUtils } from '../calendar/DateUtils.js';\n\nexport class ConflictDetector {\n /**\n * Create a new ConflictDetector\n * @param {import('../events/EventStore.js').EventStore} eventStore - Event store instance\n */\n constructor(eventStore) {\n this.eventStore = eventStore;\n this.conflictIdCounter = 0;\n }\n\n /**\n * Check for conflicts for a specific event\n * @param {import('../events/Event.js').Event|import('../../types.js').EventData} event - Event to check\n * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options\n * @returns {import('../../types.js').ConflictSummary} Conflict summary\n */\n checkConflicts(event, options = {}) {\n // Default options\n const opts = {\n checkAttendees: true,\n checkResources: true,\n checkLocation: true,\n ignoreAllDay: false,\n excludeEventIds: [],\n includeStatuses: ['confirmed', 'tentative'],\n bufferMinutes: 0,\n ...options\n };\n\n // Ensure we have an Event object\n if (!event.start || !event.end) {\n throw new Error('Event must have start and end dates');\n }\n\n const conflicts = [];\n const affectedEventIds = new Set();\n const affectedAttendees = new Set();\n\n // Get potential conflicting events in the time range\n const searchStart = new Date(event.start.getTime() - opts.bufferMinutes * 60000);\n const searchEnd = new Date(event.end.getTime() + opts.bufferMinutes * 60000);\n\n const potentialConflicts = this.eventStore.getEventsInRange(searchStart, searchEnd, false)\n .filter(e => {\n // Exclude self\n if (e.id === event.id) return false;\n // Exclude specified event IDs\n if (opts.excludeEventIds.includes(e.id)) return false;\n // Filter by status\n if (!opts.includeStatuses.includes(e.status)) return false;\n // Ignore all-day events if specified\n if (opts.ignoreAllDay && (e.allDay || event.allDay)) return false;\n // Ignore cancelled events\n if (e.status === 'cancelled') return false;\n return true;\n });\n\n // Check each potential conflict\n for (const conflictingEvent of potentialConflicts) {\n const eventConflicts = this._detectEventConflicts(\n event,\n conflictingEvent,\n opts\n );\n\n if (eventConflicts.length > 0) {\n conflicts.push(...eventConflicts);\n affectedEventIds.add(event.id);\n affectedEventIds.add(conflictingEvent.id);\n\n // Track affected attendees\n if (event.attendees) {\n event.attendees.forEach(a => affectedAttendees.add(a.email));\n }\n if (conflictingEvent.attendees) {\n conflictingEvent.attendees.forEach(a => affectedAttendees.add(a.email));\n }\n }\n }\n\n // Build summary\n return this._buildConflictSummary(conflicts, affectedEventIds, affectedAttendees);\n }\n\n /**\n * Check for conflicts between two specific events\n * @param {import('../events/Event.js').Event} event1 - First event\n * @param {import('../events/Event.js').Event} event2 - Second event\n * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options\n * @returns {import('../../types.js').ConflictDetails[]} Array of conflicts\n */\n checkEventPairConflicts(event1, event2, options = {}) {\n const opts = {\n checkAttendees: true,\n checkResources: true,\n checkLocation: true,\n bufferMinutes: 0,\n ...options\n };\n\n return this._detectEventConflicts(event1, event2, opts);\n }\n\n /**\n * Get busy periods for a set of attendees\n * @param {string[]} attendeeEmails - Attendee email addresses\n * @param {Date} start - Start of period\n * @param {Date} end - End of period\n * @param {Object} [options={}] - Options\n * @returns {Array<{start: Date, end: Date, eventIds: string[]}>} Busy periods\n */\n getBusyPeriods(attendeeEmails, start, end, options = {}) {\n const opts = {\n includeStatuses: ['confirmed', 'tentative'],\n mergePeriods: true,\n ...options\n };\n\n const busyPeriods = [];\n const events = this.eventStore.getEventsInRange(start, end, false);\n\n // Find events with these attendees\n const attendeeEvents = events.filter(event => {\n if (!opts.includeStatuses.includes(event.status)) return false;\n if (event.status === 'cancelled') return false;\n\n return event.attendees && event.attendees.some(attendee =>\n attendeeEmails.includes(attendee.email)\n );\n });\n\n // Convert to busy periods\n attendeeEvents.forEach(event => {\n busyPeriods.push({\n start: event.start,\n end: event.end,\n eventIds: [event.id]\n });\n });\n\n // Merge overlapping periods if requested\n if (opts.mergePeriods && busyPeriods.length > 1) {\n return this._mergeBusyPeriods(busyPeriods);\n }\n\n return busyPeriods.sort((a, b) => a.start - b.start);\n }\n\n /**\n * Get free time slots\n * @param {Date} start - Start of search period\n * @param {Date} end - End of search period\n * @param {number} duration - Required duration in minutes\n * @param {Object} [options={}] - Options\n * @returns {Array<{start: Date, end: Date}>} Free time slots\n */\n getFreePeriods(start, end, duration, options = {}) {\n const opts = {\n attendeeEmails: [],\n businessHoursOnly: false,\n businessHours: { start: '09:00', end: '17:00' },\n excludeWeekends: false,\n ...options\n };\n\n const freePeriods = [];\n\n // Get busy periods\n const busyPeriods = opts.attendeeEmails.length > 0\n ? this.getBusyPeriods(opts.attendeeEmails, start, end)\n : this._getAllBusyPeriods(start, end);\n\n // Find gaps between busy periods\n let currentTime = new Date(start);\n\n for (const busy of busyPeriods) {\n if (currentTime < busy.start) {\n // Found a gap\n const gapDuration = (busy.start - currentTime) / 60000; // minutes\n if (gapDuration >= duration) {\n // Check if within business hours if required\n if (!opts.businessHoursOnly || this._isWithinBusinessHours(currentTime, busy.start, opts)) {\n freePeriods.push({\n start: new Date(currentTime),\n end: new Date(busy.start)\n });\n }\n }\n }\n currentTime = new Date(Math.max(currentTime.getTime(), busy.end.getTime()));\n }\n\n // Check final period\n if (currentTime < end) {\n const gapDuration = (end - currentTime) / 60000;\n if (gapDuration >= duration) {\n if (!opts.businessHoursOnly || this._isWithinBusinessHours(currentTime, end, opts)) {\n freePeriods.push({\n start: new Date(currentTime),\n end: new Date(end)\n });\n }\n }\n }\n\n return freePeriods;\n }\n\n /**\n * Detect conflicts between two events\n * @private\n */\n _detectEventConflicts(event1, event2, options) {\n const conflicts = [];\n\n // Check time overlap with buffer\n const hasTimeOverlap = this._checkTimeOverlap(\n event1,\n event2,\n options.bufferMinutes\n );\n\n if (hasTimeOverlap) {\n // Time conflict\n const timeConflict = this._createTimeConflict(event1, event2);\n conflicts.push(timeConflict);\n\n // Check attendee conflicts (only if time overlaps)\n if (options.checkAttendees) {\n const attendeeConflicts = this._checkAttendeeConflicts(event1, event2);\n conflicts.push(...attendeeConflicts);\n }\n\n // Check resource conflicts (only if time overlaps)\n if (options.checkResources) {\n const resourceConflicts = this._checkResourceConflicts(event1, event2);\n conflicts.push(...resourceConflicts);\n }\n\n // Check location conflicts (only if time overlaps)\n if (options.checkLocation) {\n const locationConflict = this._checkLocationConflict(event1, event2);\n if (locationConflict) {\n conflicts.push(locationConflict);\n }\n }\n }\n\n return conflicts;\n }\n\n /**\n * Check for time overlap between events\n * @private\n */\n _checkTimeOverlap(event1, event2, bufferMinutes = 0) {\n const buffer = bufferMinutes * 60000; // Convert to milliseconds\n\n const start1 = event1.start.getTime() - buffer;\n const end1 = event1.end.getTime() + buffer;\n const start2 = event2.start.getTime();\n const end2 = event2.end.getTime();\n\n return !(end1 <= start2 || end2 <= start1);\n }\n\n /**\n * Create time conflict details\n * @private\n */\n _createTimeConflict(event1, event2) {\n const overlapStart = new Date(Math.max(event1.start.getTime(), event2.start.getTime()));\n const overlapEnd = new Date(Math.min(event1.end.getTime(), event2.end.getTime()));\n const overlapMinutes = (overlapEnd - overlapStart) / 60000;\n\n // Determine severity based on overlap duration and event importance\n let severity = 'low';\n if (overlapMinutes >= 60) {\n severity = 'high';\n } else if (overlapMinutes >= 30) {\n severity = 'medium';\n }\n\n // Increase severity for confirmed events\n if (event1.status === 'confirmed' && event2.status === 'confirmed') {\n severity = severity === 'low' ? 'medium' : severity === 'medium' ? 'high' : 'critical';\n }\n\n return {\n id: `conflict_${++this.conflictIdCounter}`,\n type: 'time',\n severity,\n eventId: event1.id,\n conflictingEventId: event2.id,\n description: `Time overlap: ${event1.title} conflicts with ${event2.title}`,\n overlapStart,\n overlapEnd,\n overlapMinutes,\n metadata: {\n event1Title: event1.title,\n event2Title: event2.title,\n event1Status: event1.status,\n event2Status: event2.status\n }\n };\n }\n\n /**\n * Check for attendee conflicts\n * @private\n */\n _checkAttendeeConflicts(event1, event2) {\n const conflicts = [];\n\n if (!event1.attendees || !event2.attendees) {\n return conflicts;\n }\n\n const conflictingAttendees = [];\n\n for (const attendee1 of event1.attendees) {\n for (const attendee2 of event2.attendees) {\n if (attendee1.email === attendee2.email) {\n // Same attendee in both events\n conflictingAttendees.push(attendee1.email);\n }\n }\n }\n\n if (conflictingAttendees.length > 0) {\n // Determine severity based on attendee responses\n let severity = 'medium';\n\n // Check if any conflicting attendee has accepted both\n const hasAcceptedBoth = conflictingAttendees.some(email => {\n const a1 = event1.attendees.find(a => a.email === email);\n const a2 = event2.attendees.find(a => a.email === email);\n return a1?.responseStatus === 'accepted' && a2?.responseStatus === 'accepted';\n });\n\n if (hasAcceptedBoth) {\n severity = 'critical';\n }\n\n conflicts.push({\n id: `conflict_${++this.conflictIdCounter}`,\n type: 'attendee',\n severity,\n eventId: event1.id,\n conflictingEventId: event2.id,\n description: `Attendee conflict: ${conflictingAttendees.length} attendee(s) double-booked`,\n conflictingAttendees,\n metadata: {\n attendeeCount: conflictingAttendees.length,\n attendeeEmails: conflictingAttendees\n }\n });\n }\n\n return conflicts;\n }\n\n /**\n * Check for resource conflicts\n * @private\n */\n _checkResourceConflicts(event1, event2) {\n const conflicts = [];\n\n // Check if events have resource attendees\n const resources1 = event1.attendees?.filter(a => a.resource) || [];\n const resources2 = event2.attendees?.filter(a => a.resource) || [];\n\n for (const resource1 of resources1) {\n for (const resource2 of resources2) {\n if (resource1.email === resource2.email) {\n conflicts.push({\n id: `conflict_${++this.conflictIdCounter}`,\n type: 'resource',\n severity: 'critical', // Resource conflicts are always critical\n eventId: event1.id,\n conflictingEventId: event2.id,\n description: `Resource conflict: ${resource1.name} is double-booked`,\n conflictingResource: resource1.email,\n metadata: {\n resourceName: resource1.name,\n resourceEmail: resource1.email\n }\n });\n }\n }\n }\n\n return conflicts;\n }\n\n /**\n * Check for location conflicts\n * @private\n */\n _checkLocationConflict(event1, event2) {\n if (!event1.location || !event2.location) {\n return null;\n }\n\n // Normalize locations for comparison\n const loc1 = event1.location.trim().toLowerCase();\n const loc2 = event2.location.trim().toLowerCase();\n\n if (loc1 === loc2) {\n return {\n id: `conflict_${++this.conflictIdCounter}`,\n type: 'location',\n severity: 'high', // Location conflicts are typically high severity\n eventId: event1.id,\n conflictingEventId: event2.id,\n description: `Location conflict: ${event1.location} is double-booked`,\n metadata: {\n location: event1.location\n }\n };\n }\n\n return null;\n }\n\n /**\n * Build conflict summary\n * @private\n */\n _buildConflictSummary(conflicts, affectedEventIds, affectedAttendees) {\n const conflictsByType = {};\n const conflictsBySeverity = {};\n\n // Count by type and severity\n for (const conflict of conflicts) {\n conflictsByType[conflict.type] = (conflictsByType[conflict.type] || 0) + 1;\n conflictsBySeverity[conflict.severity] = (conflictsBySeverity[conflict.severity] || 0) + 1;\n }\n\n return {\n hasConflicts: conflicts.length > 0,\n totalConflicts: conflicts.length,\n conflicts,\n conflictsByType,\n conflictsBySeverity,\n affectedEventIds: Array.from(affectedEventIds),\n affectedAttendees: Array.from(affectedAttendees)\n };\n }\n\n /**\n * Merge overlapping busy periods\n * @private\n */\n _mergeBusyPeriods(periods) {\n if (periods.length <= 1) return periods;\n\n // Sort by start time\n periods.sort((a, b) => a.start - b.start);\n\n const merged = [periods[0]];\n\n for (let i = 1; i < periods.length; i++) {\n const current = periods[i];\n const last = merged[merged.length - 1];\n\n if (current.start <= last.end) {\n // Overlapping or adjacent, merge them\n last.end = new Date(Math.max(last.end.getTime(), current.end.getTime()));\n last.eventIds.push(...current.eventIds);\n } else {\n // No overlap, add as new period\n merged.push(current);\n }\n }\n\n return merged;\n }\n\n /**\n * Get all busy periods\n * @private\n */\n _getAllBusyPeriods(start, end) {\n const events = this.eventStore.getEventsInRange(start, end, false)\n .filter(e => e.status !== 'cancelled');\n\n return events.map(event => ({\n start: event.start,\n end: event.end,\n eventIds: [event.id]\n })).sort((a, b) => a.start - b.start);\n }\n\n /**\n * Check if time period is within business hours\n * @private\n */\n _isWithinBusinessHours(start, end, options) {\n // Simple implementation - can be enhanced\n const startHour = start.getHours();\n const endHour = end.getHours();\n\n const businessStart = parseInt(options.businessHours.start.split(':')[0]);\n const businessEnd = parseInt(options.businessHours.end.split(':')[0]);\n\n return startHour >= businessStart && endHour <= businessEnd;\n }\n}","import { Event } from './Event.js';\nimport { DateUtils } from '../calendar/DateUtils.js';\nimport { RecurrenceEngine } from './RecurrenceEngine.js';\nimport { PerformanceOptimizer } from '../performance/PerformanceOptimizer.js';\nimport { ConflictDetector } from '../conflicts/ConflictDetector.js';\nimport { TimezoneManager } from '../timezone/TimezoneManager.js';\n\n/**\n * EventStore - Manages calendar events with efficient querying\n * Uses Map for O(1) lookups and spatial indexing concepts for date queries\n * Now with performance optimizations for large datasets\n */\nexport class EventStore {\n constructor(config = {}) {\n // Primary storage - Map for O(1) ID lookups\n /** @type {Map<string, Event>} */\n this.events = new Map();\n\n // Indices for efficient queries (using UTC for consistent indexing)\n this.indices = {\n /** @type {Map<string, Set<string>>} UTC Date string -> Set of event IDs */\n byDate: new Map(),\n /** @type {Map<string, Set<string>>} YYYY-MM (UTC) -> Set of event IDs */\n byMonth: new Map(),\n /** @type {Set<string>} Set of recurring event IDs */\n recurring: new Set(),\n /** @type {Map<string, Set<string>>} Category -> Set of event IDs */\n byCategory: new Map(),\n /** @type {Map<string, Set<string>>} Status -> Set of event IDs */\n byStatus: new Map()\n };\n\n // Timezone manager for conversions\n this.timezoneManager = new TimezoneManager();\n\n // Default timezone for the store (can be overridden)\n this.defaultTimezone = config.timezone || this.timezoneManager.getSystemTimezone();\n\n // Performance optimizer\n this.optimizer = new PerformanceOptimizer(config.performance);\n\n // Conflict detector\n this.conflictDetector = new ConflictDetector(this);\n\n // Batch operation state\n this.isBatchMode = false;\n this.batchNotifications = [];\n this.batchBackup = null; // For rollback support\n\n // Change tracking\n /** @type {number} */\n this.version = 0;\n /** @type {Set<import('../../types.js').EventListener>} */\n this.listeners = new Set();\n }\n\n /**\n * Add an event to the store\n * @param {Event|import('../../types.js').EventData} event - The event to add\n * @returns {Event} The added event\n * @throws {Error} If event with same ID already exists\n */\n addEvent(event) {\n return this.optimizer.measure('addEvent', () => {\n if (!(event instanceof Event)) {\n event = new Event(event);\n }\n\n if (this.events.has(event.id)) {\n throw new Error(`Event with id ${event.id} already exists`);\n }\n\n // Store the event\n this.events.set(event.id, event);\n\n // Cache the event\n this.optimizer.cache(event.id, event, 'event');\n\n // Update indices\n this._indexEvent(event);\n\n // Notify listeners (batch if in batch mode)\n if (this.isBatchMode) {\n this.batchNotifications.push({\n type: 'add',\n event,\n version: ++this.version\n });\n } else {\n this._notifyChange({\n type: 'add',\n event,\n version: ++this.version\n });\n }\n\n return event;\n });\n }\n\n /**\n * Update an existing event\n * @param {string} eventId - The event ID\n * @param {Partial<import('../../types.js').EventData>} updates - Properties to update\n * @returns {Event} The updated event\n * @throws {Error} If event not found\n */\n updateEvent(eventId, updates) {\n const existingEvent = this.events.get(eventId);\n if (!existingEvent) {\n throw new Error(`Event with id ${eventId} not found`);\n }\n\n // Remove old indices\n this._unindexEvent(existingEvent);\n\n // Create updated event\n const updatedEvent = existingEvent.clone(updates);\n\n // Store updated event\n this.events.set(eventId, updatedEvent);\n\n // Re-index\n this._indexEvent(updatedEvent);\n\n // Notify listeners\n this._notifyChange({\n type: 'update',\n event: updatedEvent,\n oldEvent: existingEvent,\n version: ++this.version\n });\n\n return updatedEvent;\n }\n\n /**\n * Remove an event from the store\n * @param {string} eventId - The event ID to remove\n * @returns {boolean} True if removed, false if not found\n */\n removeEvent(eventId) {\n const event = this.events.get(eventId);\n if (!event) {\n return false;\n }\n\n // Remove from primary storage\n this.events.delete(eventId);\n\n // Remove from indices\n this._unindexEvent(event);\n\n // Notify listeners\n this._notifyChange({\n type: 'remove',\n event,\n version: ++this.version\n });\n\n return true;\n }\n\n /**\n * Get an event by ID\n * @param {string} eventId - The event ID\n * @returns {Event|null} The event or null if not found\n */\n getEvent(eventId) {\n // Check cache first\n const cached = this.optimizer.getFromCache(eventId, 'event');\n if (cached) {\n return cached;\n }\n\n // Get from store\n const event = this.events.get(eventId) || null;\n\n // Cache if found\n if (event) {\n this.optimizer.cache(eventId, event, 'event');\n }\n\n return event;\n }\n\n /**\n * Get all events\n * @returns {Event[]} Array of all events\n */\n getAllEvents() {\n return Array.from(this.events.values());\n }\n\n /**\n * Query events with filters\n * @param {import('../../types.js').QueryFilters} [filters={}] - Query filters\n * @returns {Event[]} Filtered events\n */\n queryEvents(filters = {}) {\n let results = Array.from(this.events.values());\n\n // Filter by date range\n if (filters.start || filters.end) {\n const start = filters.start ? new Date(filters.start) : null;\n const end = filters.end ? new Date(filters.end) : null;\n\n results = results.filter(event => {\n if (start && event.end < start) return false;\n if (end && event.start > end) return false;\n return true;\n });\n }\n\n // Filter by specific date\n if (filters.date) {\n const date = new Date(filters.date);\n results = results.filter(event => event.occursOn(date));\n }\n\n // Filter by month\n if (filters.month && filters.year) {\n const monthKey = `${filters.year}-${String(filters.month).padStart(2, '0')}`;\n const eventIds = this.indices.byMonth.get(monthKey) || new Set();\n results = results.filter(event => eventIds.has(event.id));\n }\n\n // Filter by all-day events\n if (filters.hasOwnProperty('allDay')) {\n results = results.filter(event => event.allDay === filters.allDay);\n }\n\n // Filter by recurring\n if (filters.hasOwnProperty('recurring')) {\n results = results.filter(event => event.recurring === filters.recurring);\n }\n\n // Filter by status\n if (filters.status) {\n results = results.filter(event => event.status === filters.status);\n }\n\n // Filter by categories\n if (filters.categories && filters.categories.length > 0) {\n results = results.filter(event =>\n filters.matchAllCategories\n ? event.hasAllCategories(filters.categories)\n : event.hasAnyCategory(filters.categories)\n );\n }\n\n // Filter by having attendees\n if (filters.hasOwnProperty('hasAttendees')) {\n results = results.filter(event => filters.hasAttendees ? event.hasAttendees : !event.hasAttendees);\n }\n\n // Filter by organizer email\n if (filters.organizerEmail) {\n results = results.filter(event =>\n event.organizer && event.organizer.email === filters.organizerEmail\n );\n }\n\n // Sort results\n if (filters.sort) {\n results.sort((a, b) => {\n switch (filters.sort) {\n case 'start':\n return a.start - b.start;\n case 'end':\n return a.end - b.end;\n case 'duration':\n return a.duration - b.duration;\n case 'title':\n return a.title.localeCompare(b.title);\n default:\n return 0;\n }\n });\n }\n\n return results;\n }\n\n /**\n * Get events for a specific date\n * @param {Date} date - The date to query\n * @param {string} [timezone] - Timezone for the query (defaults to store timezone)\n * @returns {Event[]} Events occurring on the date, sorted by start time\n */\n getEventsForDate(date, timezone = null) {\n timezone = timezone || this.defaultTimezone;\n\n // Use local date string for the query date (in the calendar's timezone)\n const dateStr = DateUtils.getLocalDateString(date);\n\n // Collect candidate event IDs from indices\n const candidateIds = new Set();\n\n // Check byDate index for nearby dates (handles most events)\n const checkDate = new Date(date);\n for (let offset = -1; offset <= 1; offset++) {\n const tempDate = new Date(checkDate);\n tempDate.setDate(tempDate.getDate() + offset);\n const tempDateStr = DateUtils.getLocalDateString(tempDate);\n const eventIds = this.indices.byDate.get(tempDateStr);\n if (eventIds) {\n eventIds.forEach(id => candidateIds.add(id));\n }\n }\n\n // Also check byMonth index to catch long-running events that might not be\n // indexed in byDate for this specific date (lazy indexing only indexes\n // first/last week of multi-week events)\n const monthKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n const monthEventIds = this.indices.byMonth.get(monthKey);\n if (monthEventIds) {\n monthEventIds.forEach(id => candidateIds.add(id));\n }\n\n // Filter candidates to events that actually overlap with the requested date\n const allEvents = [];\n const startOfDay = new Date(date);\n startOfDay.setHours(0, 0, 0, 0);\n const endOfDay = new Date(date);\n endOfDay.setHours(23, 59, 59, 999);\n\n for (const id of candidateIds) {\n const event = this.events.get(id);\n if (event) {\n // Check if event actually occurs on the requested date in the given timezone\n const eventStartLocal = event.getStartInTimezone(timezone);\n const eventEndLocal = event.getEndInTimezone(timezone);\n\n // Event overlaps with this day if it starts before end of day and ends after start of day\n if (eventStartLocal <= endOfDay && eventEndLocal >= startOfDay) {\n allEvents.push(event);\n }\n }\n }\n\n return allEvents.sort((a, b) => {\n // Sort by start time in the specified timezone\n const aStart = a.getStartInTimezone(timezone);\n const bStart = b.getStartInTimezone(timezone);\n const timeCompare = aStart - bStart;\n if (timeCompare !== 0) return timeCompare;\n return b.duration - a.duration; // Longer events first\n });\n }\n\n /**\n * Get events that overlap with a given time range\n * @param {Date} start - Start time\n * @param {Date} end - End time\n * @param {string} [excludeId=null] - Optional event ID to exclude (useful when checking for conflicts)\n * @returns {Event[]} Array of overlapping events\n */\n getOverlappingEvents(start, end, excludeId = null) {\n const overlapping = [];\n\n // Get all events in the date range\n const startDate = DateUtils.startOfDay(start);\n const endDate = DateUtils.endOfDay(end);\n const dates = DateUtils.getDateRange(startDate, endDate);\n\n // Collect all events from those dates\n const checkedIds = new Set();\n dates.forEach(date => {\n const dateStr = date.toDateString();\n const eventIds = this.indices.byDate.get(dateStr) || new Set();\n\n eventIds.forEach(id => {\n if (!checkedIds.has(id) && id !== excludeId) {\n checkedIds.add(id);\n const event = this.events.get(id);\n\n if (event && event.overlaps({ start, end })) {\n overlapping.push(event);\n }\n }\n });\n });\n\n return overlapping.sort((a, b) => a.start - b.start);\n }\n\n /**\n * Check if an event would conflict with existing events\n * @param {Date} start - Start time\n * @param {Date} end - End time\n * @param {string} excludeId - Optional event ID to exclude\n * @returns {boolean} True if there are conflicts\n */\n hasConflicts(start, end, excludeId = null) {\n return this.getOverlappingEvents(start, end, excludeId).length > 0;\n }\n\n /**\n * Get events grouped by overlapping time slots\n * Useful for calculating event positions in week/day views\n * @param {Date} date - The date to analyze\n * @param {boolean} timedOnly - Only include timed events (not all-day)\n * @returns {Array<Event[]>} Array of event groups that overlap\n */\n getOverlapGroups(date, timedOnly = true) {\n let events = this.getEventsForDate(date);\n\n if (timedOnly) {\n events = events.filter(e => !e.allDay);\n }\n\n const groups = [];\n const processed = new Set();\n\n events.forEach(event => {\n if (processed.has(event.id)) return;\n\n // Start a new group with this event\n const group = [event];\n processed.add(event.id);\n\n // Find all events that overlap with any event in this group\n let i = 0;\n while (i < group.length) {\n const currentEvent = group[i];\n\n events.forEach(otherEvent => {\n if (!processed.has(otherEvent.id) && currentEvent.overlaps(otherEvent)) {\n group.push(otherEvent);\n processed.add(otherEvent.id);\n }\n });\n\n i++;\n }\n\n groups.push(group);\n });\n\n return groups;\n }\n\n /**\n * Calculate positions for overlapping events (for rendering)\n * @param {Event[]} events - Array of overlapping events\n * @returns {Map<string, {column: number, totalColumns: number}>} Position data for each event\n */\n calculateEventPositions(events) {\n const positions = new Map();\n\n if (events.length === 0) return positions;\n\n // Sort by start time, then by duration (longer events first)\n events.sort((a, b) => {\n const startDiff = a.start - b.start;\n if (startDiff !== 0) return startDiff;\n return (b.end - b.start) - (a.end - a.start);\n });\n\n // Track which columns are occupied at each time\n const columns = [];\n\n events.forEach(event => {\n // Find the first available column\n let column = 0;\n while (column < columns.length) {\n const columnEvents = columns[column];\n const hasConflict = columnEvents.some(e => e.overlaps(event));\n\n if (!hasConflict) {\n break;\n }\n column++;\n }\n\n // Add event to the column\n if (!columns[column]) {\n columns[column] = [];\n }\n columns[column].push(event);\n\n positions.set(event.id, {\n column: column,\n totalColumns: 0 // Will be updated after all events are placed\n });\n });\n\n // Update total columns for all events\n const totalColumns = columns.length;\n positions.forEach(pos => {\n pos.totalColumns = totalColumns;\n });\n\n return positions;\n }\n\n /**\n * Get events for a date range\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @param {boolean|string} expandRecurring - Whether to expand recurring events, or timezone string\n * @param {string} [timezone] - Timezone for the query (if expandRecurring is boolean)\n * @returns {Event[]}\n */\n getEventsInRange(start, end, expandRecurring = true, timezone = null) {\n // Handle overloaded parameters\n if (typeof expandRecurring === 'string') {\n timezone = expandRecurring;\n expandRecurring = true;\n }\n\n timezone = timezone || this.defaultTimezone;\n\n // Convert range to UTC for querying\n const startUTC = this.timezoneManager.toUTC(start, timezone);\n const endUTC = this.timezoneManager.toUTC(end, timezone);\n\n // Query using UTC times\n const baseEvents = this.queryEvents({\n start: startUTC,\n end: endUTC,\n sort: 'start'\n });\n\n if (!expandRecurring) {\n return baseEvents;\n }\n\n // Expand recurring events\n const expandedEvents = [];\n baseEvents.forEach(event => {\n if (event.recurring && event.recurrenceRule) {\n const occurrences = this.expandRecurringEvent(event, start, end, timezone);\n expandedEvents.push(...occurrences);\n } else {\n expandedEvents.push(event);\n }\n });\n\n return expandedEvents.sort((a, b) => {\n // Sort by start time in the specified timezone\n const aStart = a.getStartInTimezone(timezone);\n const bStart = b.getStartInTimezone(timezone);\n return aStart - bStart;\n });\n }\n\n /**\n * Expand a recurring event into individual occurrences\n * @param {Event} event - The recurring event\n * @param {Date} rangeStart - Start of the expansion range\n * @param {Date} rangeEnd - End of the expansion range\n * @param {string} [timezone] - Timezone for the expansion\n * @returns {Event[]} Array of event occurrences\n */\n expandRecurringEvent(event, rangeStart, rangeEnd, timezone = null) {\n if (!event.recurring || !event.recurrenceRule) {\n return [event];\n }\n\n timezone = timezone || this.defaultTimezone;\n\n // Expand in the event's timezone for accurate recurrence calculation\n const eventTimezone = event.timeZone || timezone;\n const occurrences = RecurrenceEngine.expandEvent(event, rangeStart, rangeEnd);\n\n return occurrences.map((occurrence, index) => {\n // Create a new event instance for each occurrence\n const occurrenceEvent = event.clone({\n id: `${event.id}_occurrence_${index}`,\n start: occurrence.start,\n end: occurrence.end,\n timeZone: eventTimezone,\n metadata: {\n ...event.metadata,\n recurringEventId: event.id,\n occurrenceIndex: index\n }\n });\n\n return occurrenceEvent;\n });\n }\n\n /**\n * Clear all events\n */\n clear() {\n const oldEvents = this.getAllEvents();\n\n this.events.clear();\n this.indices.byDate.clear();\n this.indices.byMonth.clear();\n this.indices.recurring.clear();\n\n this._notifyChange({\n type: 'clear',\n oldEvents,\n version: ++this.version\n });\n }\n\n /**\n * Bulk load events\n * @param {Event[]} events - Array of events or event data\n */\n loadEvents(events) {\n this.clear();\n\n for (const eventData of events) {\n this.addEvent(eventData);\n }\n }\n\n /**\n * Subscribe to store changes\n * @param {Function} callback - Callback function\n * @returns {Function} Unsubscribe function\n */\n subscribe(callback) {\n this.listeners.add(callback);\n\n return () => {\n this.listeners.delete(callback);\n };\n }\n\n /**\n * Index an event for efficient queries\n * @private\n */\n _indexEvent(event) {\n // Check if should use lazy indexing for large date ranges\n if (this.optimizer.shouldUseLazyIndexing(event)) {\n this._indexEventLazy(event);\n return;\n }\n\n // Index by local dates in the event's timezone\n // This ensures events appear on the correct calendar day\n const eventStartLocal = event.getStartInTimezone(event.timeZone);\n const eventEndLocal = event.getEndInTimezone(event.endTimeZone || event.timeZone);\n\n const startDate = DateUtils.startOfDay(eventStartLocal);\n const endDate = DateUtils.endOfDay(eventEndLocal);\n\n // For each day the event spans (in local time), add to date index\n const dates = DateUtils.getDateRange(startDate, endDate);\n\n dates.forEach(date => {\n const dateStr = DateUtils.getLocalDateString(date);\n\n if (!this.indices.byDate.has(dateStr)) {\n this.indices.byDate.set(dateStr, new Set());\n }\n this.indices.byDate.get(dateStr).add(event.id);\n });\n\n // Index by month(s) using UTC\n const startMonth = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}`;\n const endMonth = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}`;\n\n // Add to all months the event spans\n const currentMonth = new Date(startDate.getFullYear(), startDate.getMonth(), 1);\n while (currentMonth <= endDate) {\n const monthKey = `${currentMonth.getFullYear()}-${String(currentMonth.getMonth() + 1).padStart(2, '0')}`;\n\n if (!this.indices.byMonth.has(monthKey)) {\n this.indices.byMonth.set(monthKey, new Set());\n }\n this.indices.byMonth.get(monthKey).add(event.id);\n\n currentMonth.setMonth(currentMonth.getMonth() + 1);\n }\n\n // Index by categories\n if (event.categories && event.categories.length > 0) {\n event.categories.forEach(category => {\n if (!this.indices.byCategory.has(category)) {\n this.indices.byCategory.set(category, new Set());\n }\n this.indices.byCategory.get(category).add(event.id);\n });\n }\n\n // Index by status\n if (event.status) {\n if (!this.indices.byStatus.has(event.status)) {\n this.indices.byStatus.set(event.status, new Set());\n }\n this.indices.byStatus.get(event.status).add(event.id);\n }\n\n // Index recurring events\n if (event.recurring) {\n this.indices.recurring.add(event.id);\n }\n }\n\n /**\n * Lazy index for events with large date ranges\n * @private\n */\n _indexEventLazy(event) {\n // Create lazy index markers\n const markers = this.optimizer.createLazyIndexMarkers(event);\n\n // Index only the boundaries initially (in event's local timezone)\n const eventStartLocal = event.getStartInTimezone(event.timeZone);\n const eventEndLocal = event.getEndInTimezone(event.endTimeZone || event.timeZone);\n\n const startDate = DateUtils.startOfDay(eventStartLocal);\n const endDate = DateUtils.endOfDay(eventEndLocal);\n\n // Index first week\n const firstWeekEnd = new Date(startDate);\n firstWeekEnd.setDate(firstWeekEnd.getDate() + 7);\n const firstWeekDates = DateUtils.getDateRange(startDate,\n firstWeekEnd < endDate ? firstWeekEnd : endDate);\n\n firstWeekDates.forEach(date => {\n const dateStr = DateUtils.getLocalDateString(date);\n if (!this.indices.byDate.has(dateStr)) {\n this.indices.byDate.set(dateStr, new Set());\n }\n this.indices.byDate.get(dateStr).add(event.id);\n });\n\n // Index last week if different from first\n if (endDate > firstWeekEnd) {\n const lastWeekStart = new Date(endDate);\n lastWeekStart.setDate(lastWeekStart.getDate() - 7);\n const lastWeekDates = DateUtils.getDateRange(\n lastWeekStart > startDate ? lastWeekStart : startDate,\n endDate\n );\n\n lastWeekDates.forEach(date => {\n const dateStr = DateUtils.getLocalDateString(date);\n if (!this.indices.byDate.has(dateStr)) {\n this.indices.byDate.set(dateStr, new Set());\n }\n this.indices.byDate.get(dateStr).add(event.id);\n });\n }\n\n // Index months as normal\n const currentMonth = new Date(startDate.getFullYear(), startDate.getMonth(), 1);\n while (currentMonth <= endDate) {\n const monthKey = `${currentMonth.getFullYear()}-${String(currentMonth.getMonth() + 1).padStart(2, '0')}`;\n if (!this.indices.byMonth.has(monthKey)) {\n this.indices.byMonth.set(monthKey, new Set());\n }\n this.indices.byMonth.get(monthKey).add(event.id);\n currentMonth.setMonth(currentMonth.getMonth() + 1);\n }\n\n // Index other properties normally\n if (event.categories && event.categories.length > 0) {\n event.categories.forEach(category => {\n if (!this.indices.byCategory.has(category)) {\n this.indices.byCategory.set(category, new Set());\n }\n this.indices.byCategory.get(category).add(event.id);\n });\n }\n\n if (event.status) {\n if (!this.indices.byStatus.has(event.status)) {\n this.indices.byStatus.set(event.status, new Set());\n }\n this.indices.byStatus.get(event.status).add(event.id);\n }\n\n if (event.recurring) {\n this.indices.recurring.add(event.id);\n }\n }\n\n /**\n * Remove event from indices\n * @private\n */\n _unindexEvent(event) {\n // Remove from date indices\n for (const [dateStr, eventIds] of this.indices.byDate) {\n eventIds.delete(event.id);\n if (eventIds.size === 0) {\n this.indices.byDate.delete(dateStr);\n }\n }\n\n // Remove from month indices\n for (const [monthKey, eventIds] of this.indices.byMonth) {\n eventIds.delete(event.id);\n if (eventIds.size === 0) {\n this.indices.byMonth.delete(monthKey);\n }\n }\n\n // Remove from recurring index\n this.indices.recurring.delete(event.id);\n }\n\n /**\n * Notify listeners of changes\n * @private\n */\n _notifyChange(change) {\n for (const listener of this.listeners) {\n try {\n listener(change);\n } catch (error) {\n console.error('Error in EventStore listener:', error);\n }\n }\n }\n\n /**\n * Get store statistics\n * @returns {Object}\n */\n getStats() {\n return {\n totalEvents: this.events.size,\n recurringEvents: this.indices.recurring.size,\n indexedDates: this.indices.byDate.size,\n indexedMonths: this.indices.byMonth.size,\n indexedCategories: this.indices.byCategory.size,\n indexedStatuses: this.indices.byStatus.size,\n version: this.version,\n performanceMetrics: this.optimizer.getMetrics()\n };\n }\n\n // ============ Batch Operations ============\n\n /**\n * Start batch mode for bulk operations\n * Delays notifications until batch is committed\n * @param {boolean} [enableRollback=false] - Enable rollback support (creates backup)\n */\n startBatch(enableRollback = false) {\n this.isBatchMode = true;\n this.batchNotifications = [];\n\n // Create backup for rollback if requested\n if (enableRollback) {\n this.batchBackup = {\n events: new Map(this.events),\n indices: {\n byDate: new Map(Array.from(this.indices.byDate.entries()).map(([k, v]) => [k, new Set(v)])),\n byMonth: new Map(Array.from(this.indices.byMonth.entries()).map(([k, v]) => [k, new Set(v)])),\n recurring: new Set(this.indices.recurring),\n byCategory: new Map(Array.from(this.indices.byCategory.entries()).map(([k, v]) => [k, new Set(v)])),\n byStatus: new Map(Array.from(this.indices.byStatus.entries()).map(([k, v]) => [k, new Set(v)]))\n },\n version: this.version\n };\n }\n }\n\n /**\n * Commit batch operations\n * Sends all notifications at once\n */\n commitBatch() {\n if (!this.isBatchMode) return;\n\n this.isBatchMode = false;\n\n // Clear backup after successful commit\n this.batchBackup = null;\n\n // Send a single bulk notification\n if (this.batchNotifications.length > 0) {\n this._notifyChange({\n type: 'batch',\n changes: this.batchNotifications,\n count: this.batchNotifications.length,\n version: ++this.version\n });\n }\n\n this.batchNotifications = [];\n }\n\n /**\n * Rollback batch operations\n * Restores state to before batch started\n */\n rollbackBatch() {\n if (!this.isBatchMode) return;\n\n this.isBatchMode = false;\n\n // Restore backup if available\n if (this.batchBackup) {\n this.events = this.batchBackup.events;\n this.indices = this.batchBackup.indices;\n this.version = this.batchBackup.version;\n this.batchBackup = null;\n\n // Clear cache\n this.optimizer.clearCache();\n }\n\n this.batchNotifications = [];\n }\n\n /**\n * Execute batch operation with automatic rollback on error\n * @param {Function} operation - Operation to execute\n * @param {boolean} [enableRollback=true] - Enable automatic rollback on error\n * @returns {*} Result of operation\n * @throws {Error} If operation fails\n */\n async executeBatch(operation, enableRollback = true) {\n this.startBatch(enableRollback);\n\n try {\n const result = await operation();\n this.commitBatch();\n return result;\n } catch (error) {\n if (enableRollback) {\n this.rollbackBatch();\n }\n throw error;\n }\n }\n\n /**\n * Add multiple events in batch\n * @param {Array<Event|import('../../types.js').EventData>} events - Events to add\n * @returns {Event[]} Added events\n */\n addEvents(events) {\n return this.optimizer.measure('addEvents', () => {\n this.startBatch();\n const results = [];\n const errors = [];\n\n for (const eventData of events) {\n try {\n results.push(this.addEvent(eventData));\n } catch (error) {\n errors.push({ event: eventData, error: error.message });\n }\n }\n\n this.commitBatch();\n\n if (errors.length > 0) {\n console.warn(`Failed to add ${errors.length} events:`, errors);\n }\n\n return results;\n });\n }\n\n /**\n * Update multiple events in batch\n * @param {Array<{id: string, updates: Object}>} updates - Update operations\n * @returns {Event[]} Updated events\n */\n updateEvents(updates) {\n return this.optimizer.measure('updateEvents', () => {\n this.startBatch();\n const results = [];\n const errors = [];\n\n for (const { id, updates: eventUpdates } of updates) {\n try {\n results.push(this.updateEvent(id, eventUpdates));\n } catch (error) {\n errors.push({ id, error: error.message });\n }\n }\n\n this.commitBatch();\n\n if (errors.length > 0) {\n console.warn(`Failed to update ${errors.length} events:`, errors);\n }\n\n return results;\n });\n }\n\n /**\n * Remove multiple events in batch\n * @param {string[]} eventIds - Event IDs to remove\n * @returns {number} Number of events removed\n */\n removeEvents(eventIds) {\n return this.optimizer.measure('removeEvents', () => {\n this.startBatch();\n let removed = 0;\n\n for (const id of eventIds) {\n if (this.removeEvent(id)) {\n removed++;\n }\n }\n\n this.commitBatch();\n return removed;\n });\n }\n\n // ============ Performance Methods ============\n\n /**\n * Get performance metrics\n * @returns {Object} Performance metrics\n */\n getPerformanceMetrics() {\n return this.optimizer.getMetrics();\n }\n\n /**\n * Clear all caches\n */\n clearCaches() {\n this.optimizer.eventCache.clear();\n this.optimizer.queryCache.clear();\n this.optimizer.dateRangeCache.clear();\n }\n\n /**\n * Optimize indices by removing old or irrelevant entries\n * @param {Date} [cutoffDate] - Remove indices older than this date\n */\n optimizeIndices(cutoffDate) {\n if (!cutoffDate) {\n cutoffDate = new Date();\n cutoffDate.setMonth(cutoffDate.getMonth() - 6); // Default: 6 months ago\n }\n\n const cutoffStr = cutoffDate.toDateString();\n let removed = 0;\n\n // Clean up date indices\n for (const [dateStr, eventIds] of this.indices.byDate) {\n const date = new Date(dateStr);\n if (date < cutoffDate) {\n // Check if any events still need this index\n let stillNeeded = false;\n for (const eventId of eventIds) {\n const event = this.events.get(eventId);\n if (event && event.end >= cutoffDate) {\n stillNeeded = true;\n break;\n }\n }\n\n if (!stillNeeded) {\n this.indices.byDate.delete(dateStr);\n removed++;\n }\n }\n }\n\n console.log(`Optimized indices: removed ${removed} old date entries`);\n return removed;\n }\n\n /**\n * Destroy the store and clean up resources\n */\n destroy() {\n this.clear();\n this.optimizer.destroy();\n this.listeners.clear();\n }\n\n // ============ Conflict Detection Methods ============\n\n /**\n * Check for conflicts for an event\n * @param {Event|import('../../types.js').EventData} event - Event to check\n * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options\n * @returns {import('../../types.js').ConflictSummary} Conflict summary\n */\n checkConflicts(event, options = {}) {\n return this.conflictDetector.checkConflicts(event, options);\n }\n\n /**\n * Check conflicts between two events\n * @param {string} eventId1 - First event ID\n * @param {string} eventId2 - Second event ID\n * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options\n * @returns {import('../../types.js').ConflictDetails[]} Conflicts between events\n */\n checkEventPairConflicts(eventId1, eventId2, options = {}) {\n const event1 = this.getEvent(eventId1);\n const event2 = this.getEvent(eventId2);\n\n if (!event1 || !event2) {\n throw new Error('One or both events not found');\n }\n\n return this.conflictDetector.checkEventPairConflicts(event1, event2, options);\n }\n\n /**\n * Get all conflicts in a date range\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options\n * @returns {import('../../types.js').ConflictSummary} All conflicts in range\n */\n getAllConflicts(start, end, options = {}) {\n const events = this.getEventsInRange(start, end, false);\n const allConflicts = [];\n const checkedPairs = new Set();\n\n for (let i = 0; i < events.length; i++) {\n for (let j = i + 1; j < events.length; j++) {\n const pairKey = `${events[i].id}-${events[j].id}`;\n if (!checkedPairs.has(pairKey)) {\n checkedPairs.add(pairKey);\n const conflicts = this.conflictDetector.checkEventPairConflicts(\n events[i],\n events[j],\n options\n );\n allConflicts.push(...conflicts);\n }\n }\n }\n\n return this.conflictDetector._buildConflictSummary(\n allConflicts,\n new Set(events.map(e => e.id)),\n new Set()\n );\n }\n\n /**\n * Get busy periods for attendees\n * @param {string[]} attendeeEmails - Attendee emails\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @param {Object} [options={}] - Options\n * @returns {Array<{start: Date, end: Date, eventIds: string[]}>} Busy periods\n */\n getBusyPeriods(attendeeEmails, start, end, options = {}) {\n return this.conflictDetector.getBusyPeriods(attendeeEmails, start, end, options);\n }\n\n /**\n * Get free periods for scheduling\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @param {number} durationMinutes - Required duration in minutes\n * @param {Object} [options={}] - Options\n * @returns {Array<{start: Date, end: Date}>} Free periods\n */\n getFreePeriods(start, end, durationMinutes, options = {}) {\n return this.conflictDetector.getFreePeriods(start, end, durationMinutes, options);\n }\n\n /**\n * Add event with conflict checking\n * @param {Event|import('../../types.js').EventData} event - Event to add\n * @param {boolean} [allowConflicts=true] - Whether to allow adding with conflicts\n * @returns {{event: Event, conflicts: import('../../types.js').ConflictSummary}} Result\n */\n addEventWithConflictCheck(event, allowConflicts = true) {\n // Check conflicts before adding\n const conflicts = this.checkConflicts(event);\n\n if (!allowConflicts && conflicts.hasConflicts) {\n throw new Error(`Cannot add event: ${conflicts.totalConflicts} conflicts detected`);\n }\n\n // Add the event\n const addedEvent = this.addEvent(event);\n\n return {\n event: addedEvent,\n conflicts\n };\n }\n\n /**\n * Find events with conflicts\n * @param {Object} [options={}] - Options\n * @returns {Array<{event: Event, conflicts: import('../../types.js').ConflictDetails[]}>} Events with conflicts\n */\n findEventsWithConflicts(options = {}) {\n const eventsWithConflicts = [];\n const allEvents = this.getAllEvents();\n\n for (const event of allEvents) {\n const conflicts = this.checkConflicts(event, options);\n if (conflicts.hasConflicts) {\n eventsWithConflicts.push({\n event,\n conflicts: conflicts.conflicts\n });\n }\n }\n\n return eventsWithConflicts;\n }\n}","/**\n * StateManager - Central state management for the calendar\n * Implements an immutable state pattern with change notifications\n */\nexport class StateManager {\n /**\n * Create a new StateManager instance\n * @param {Partial<import('../../types.js').CalendarState>} [initialState={}] - Initial state values\n */\n constructor(initialState = {}) {\n this.state = {\n // Current view configuration\n view: 'month', // 'month', 'week', 'day', 'list'\n currentDate: new Date(),\n\n // UI state\n selectedEventId: null,\n selectedDate: null,\n hoveredEventId: null,\n hoveredDate: null,\n\n // Display options\n weekStartsOn: 0, // 0 = Sunday, 1 = Monday, etc.\n showWeekNumbers: false,\n showWeekends: true,\n fixedWeekCount: true, // Always show 6 weeks in month view\n\n // Time configuration\n timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n locale: 'en-US',\n hourFormat: '12h', // '12h' or '24h'\n\n // Business hours (for week/day views)\n businessHours: {\n start: '09:00',\n end: '17:00'\n },\n\n // Filters\n filters: {\n searchTerm: '',\n categories: [],\n showAllDay: true,\n showTimed: true\n },\n\n // Interaction flags\n isDragging: false,\n isResizing: false,\n isCreating: false,\n\n // Loading states\n isLoading: false,\n loadingMessage: '',\n\n // Error state\n error: null,\n\n // Custom metadata\n metadata: {},\n\n // Apply initial state overrides\n ...initialState\n };\n\n // Observers for state changes\n this.listeners = new Map();\n this.globalListeners = new Set();\n\n // History for undo/redo (optional)\n this.history = [];\n this.historyIndex = -1;\n this.maxHistorySize = 50;\n }\n\n /**\n * Get the current state\n * @returns {import('../../types.js').CalendarState} Current state (frozen)\n */\n getState() {\n return Object.freeze({ ...this.state });\n }\n\n /**\n * Get a specific state value\n * @param {keyof import('../../types.js').CalendarState} key - The state key\n * @returns {any} The state value\n */\n get(key) {\n return this.state[key];\n }\n\n /**\n * Update state with partial updates\n * @param {Object|Function} updates - Object with updates or updater function\n */\n setState(updates) {\n const oldState = this.state;\n\n // Support function updater pattern\n if (typeof updates === 'function') {\n updates = updates(oldState);\n }\n\n // Create new state with updates\n const newState = {\n ...oldState,\n ...updates,\n // Preserve nested objects\n filters: updates.filters ? { ...oldState.filters, ...updates.filters } : oldState.filters,\n businessHours: updates.businessHours ? { ...oldState.businessHours, ...updates.businessHours } : oldState.businessHours,\n metadata: updates.metadata ? { ...oldState.metadata, ...updates.metadata } : oldState.metadata\n };\n\n // Check if state actually changed\n if (this._hasChanged(oldState, newState)) {\n this.state = newState;\n\n // Add to history (store the new state)\n this._addToHistory(newState);\n\n // Notify listeners\n this._notifyListeners(oldState, newState);\n }\n }\n\n /**\n * Set the current view\n * @param {string} view - The view type\n */\n setView(view) {\n const validViews = ['month', 'week', 'day', 'list'];\n if (!validViews.includes(view)) {\n throw new Error(`Invalid view: ${view}. Must be one of: ${validViews.join(', ')}`);\n }\n this.setState({ view });\n }\n\n /**\n * Set the current date\n * @param {Date} date - The date to set\n */\n setCurrentDate(date) {\n if (!(date instanceof Date)) {\n date = new Date(date);\n }\n if (isNaN(date.getTime())) {\n throw new Error('Invalid date');\n }\n this.setState({ currentDate: date });\n }\n\n /**\n * Navigate to the next period (month/week/day based on view)\n */\n navigateNext() {\n const { view, currentDate } = this.state;\n const newDate = new Date(currentDate);\n\n switch (view) {\n case 'month':\n newDate.setMonth(newDate.getMonth() + 1);\n break;\n case 'week':\n newDate.setDate(newDate.getDate() + 7);\n break;\n case 'day':\n newDate.setDate(newDate.getDate() + 1);\n break;\n }\n\n this.setCurrentDate(newDate);\n }\n\n /**\n * Navigate to the previous period\n */\n navigatePrevious() {\n const { view, currentDate } = this.state;\n const newDate = new Date(currentDate);\n\n switch (view) {\n case 'month':\n newDate.setMonth(newDate.getMonth() - 1);\n break;\n case 'week':\n newDate.setDate(newDate.getDate() - 7);\n break;\n case 'day':\n newDate.setDate(newDate.getDate() - 1);\n break;\n }\n\n this.setCurrentDate(newDate);\n }\n\n /**\n * Navigate to today\n */\n navigateToday() {\n this.setCurrentDate(new Date());\n }\n\n /**\n * Select an event\n * @param {string} eventId - The event ID to select\n */\n selectEvent(eventId) {\n this.setState({ selectedEventId: eventId });\n }\n\n /**\n * Clear event selection\n */\n clearEventSelection() {\n this.setState({ selectedEventId: null });\n }\n\n /**\n * Select a date\n * @param {Date} date - The date to select\n */\n selectDate(date) {\n if (!(date instanceof Date)) {\n date = new Date(date);\n }\n this.setState({ selectedDate: date });\n }\n\n /**\n * Clear date selection\n */\n clearDateSelection() {\n this.setState({ selectedDate: null });\n }\n\n /**\n * Set loading state\n * @param {boolean} isLoading - Loading state\n * @param {string} message - Optional loading message\n */\n setLoading(isLoading, message = '') {\n this.setState({\n isLoading,\n loadingMessage: message\n });\n }\n\n /**\n * Set error state\n * @param {Error|string|null} error - The error\n */\n setError(error) {\n this.setState({\n error: error ? (error instanceof Error ? error.message : error) : null\n });\n }\n\n /**\n * Update filters\n * @param {Object} filters - Filter updates\n */\n updateFilters(filters) {\n this.setState({\n filters: {\n ...this.state.filters,\n ...filters\n }\n });\n }\n\n /**\n * Subscribe to all state changes\n * @param {Function} callback - Callback function\n * @returns {Function} Unsubscribe function\n */\n subscribe(callback) {\n this.globalListeners.add(callback);\n\n return () => {\n this.globalListeners.delete(callback);\n };\n }\n\n /**\n * Subscribe to specific state key changes\n * @param {string|string[]} keys - State key(s) to watch\n * @param {Function} callback - Callback function\n * @returns {Function} Unsubscribe function\n */\n watch(keys, callback) {\n const keyArray = Array.isArray(keys) ? keys : [keys];\n\n keyArray.forEach(key => {\n if (!this.listeners.has(key)) {\n this.listeners.set(key, new Set());\n }\n this.listeners.get(key).add(callback);\n });\n\n return () => {\n keyArray.forEach(key => {\n const callbacks = this.listeners.get(key);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) {\n this.listeners.delete(key);\n }\n }\n });\n };\n }\n\n /**\n * Check if undo is available\n * @returns {boolean} True if undo is available\n */\n canUndo() {\n return this.historyIndex > 0;\n }\n\n /**\n * Check if redo is available\n * @returns {boolean} True if redo is available\n */\n canRedo() {\n return this.historyIndex < this.history.length - 1;\n }\n\n /**\n * Get the number of undo operations available\n * @returns {number} Number of undo operations\n */\n getUndoCount() {\n return this.historyIndex;\n }\n\n /**\n * Get the number of redo operations available\n * @returns {number} Number of redo operations\n */\n getRedoCount() {\n return this.history.length - 1 - this.historyIndex;\n }\n\n /**\n * Undo the last state change\n * @returns {boolean} True if undo was performed\n */\n undo() {\n if (!this.canUndo()) {\n return false;\n }\n\n this.historyIndex--;\n const previousState = this.history[this.historyIndex];\n const currentState = this.state;\n\n // Update state without adding to history\n this.state = { ...previousState };\n\n // Notify listeners\n this._notifyListeners(currentState, this.state);\n\n return true;\n }\n\n /**\n * Redo the next state change\n * @returns {boolean} True if redo was performed\n */\n redo() {\n if (!this.canRedo()) {\n return false;\n }\n\n this.historyIndex++;\n const nextState = this.history[this.historyIndex];\n const currentState = this.state;\n\n // Update state without adding to history\n this.state = { ...nextState };\n\n // Notify listeners\n this._notifyListeners(currentState, this.state);\n\n return true;\n }\n\n /**\n * Reset state to initial values\n */\n reset() {\n const initialState = this.history[0] || {};\n this.setState(initialState);\n this.history = [initialState];\n this.historyIndex = 0;\n }\n\n /**\n * Check if state has changed\n * @private\n */\n _hasChanged(oldState, newState) {\n return !this._deepEqual(oldState, newState);\n }\n\n /**\n * Deep equality check optimized for state comparison\n * @private\n * @param {*} a - First value\n * @param {*} b - Second value\n * @param {Set} seen - Track circular references\n * @returns {boolean} True if values are deeply equal\n */\n _deepEqual(a, b, seen = new Set()) {\n // Same reference\n if (a === b) return true;\n\n // Different types or null/undefined\n if (a == null || b == null) return a === b;\n if (typeof a !== typeof b) return false;\n\n // Primitives\n if (typeof a !== 'object') return a === b;\n\n // Check for circular references\n if (seen.has(a) || seen.has(b)) return false;\n seen.add(a);\n seen.add(b);\n\n // Arrays\n if (Array.isArray(a)) {\n if (!Array.isArray(b) || a.length !== b.length) {\n seen.delete(a);\n seen.delete(b);\n return false;\n }\n\n for (let i = 0; i < a.length; i++) {\n if (!this._deepEqual(a[i], b[i], seen)) {\n seen.delete(a);\n seen.delete(b);\n return false;\n }\n }\n\n seen.delete(a);\n seen.delete(b);\n return true;\n }\n\n // Dates\n if (a instanceof Date && b instanceof Date) {\n const result = a.getTime() === b.getTime();\n seen.delete(a);\n seen.delete(b);\n return result;\n }\n\n // Objects\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n if (aKeys.length !== bKeys.length) {\n seen.delete(a);\n seen.delete(b);\n return false;\n }\n\n // Sort keys for consistent comparison\n aKeys.sort();\n bKeys.sort();\n\n // Compare keys\n for (let i = 0; i < aKeys.length; i++) {\n if (aKeys[i] !== bKeys[i]) {\n seen.delete(a);\n seen.delete(b);\n return false;\n }\n }\n\n // Compare values\n for (const key of aKeys) {\n if (!this._deepEqual(a[key], b[key], seen)) {\n seen.delete(a);\n seen.delete(b);\n return false;\n }\n }\n\n seen.delete(a);\n seen.delete(b);\n return true;\n }\n\n /**\n * Add state to history\n * @private\n */\n _addToHistory(state) {\n // Remove any future history if we're not at the end\n if (this.historyIndex < this.history.length - 1) {\n this.history = this.history.slice(0, this.historyIndex + 1);\n }\n\n // Add new state\n this.history.push({ ...state });\n this.historyIndex++;\n\n // Limit history size\n if (this.history.length > this.maxHistorySize) {\n this.history.shift();\n this.historyIndex--;\n }\n }\n\n /**\n * Notify listeners of state changes\n * @private\n */\n _notifyListeners(oldState, newState) {\n // Notify global listeners\n for (const callback of this.globalListeners) {\n try {\n callback(newState, oldState);\n } catch (error) {\n console.error('Error in state listener:', error);\n }\n }\n\n // Notify specific key listeners\n for (const [key, callbacks] of this.listeners) {\n if (oldState[key] !== newState[key]) {\n for (const callback of callbacks) {\n try {\n callback(newState[key], oldState[key], newState, oldState);\n } catch (error) {\n console.error(`Error in state listener for key \"${key}\":`, error);\n }\n }\n }\n }\n }\n}","import { EventStore } from '../events/EventStore.js';\nimport { Event } from '../events/Event.js';\nimport { StateManager } from '../state/StateManager.js';\nimport { DateUtils } from './DateUtils.js';\nimport { TimezoneManager } from '../timezone/TimezoneManager.js';\n\n/**\n * Calendar - Main calendar class with full timezone support\n * Pure JavaScript, no DOM dependencies\n * Framework agnostic, Locker Service compatible\n */\nexport class Calendar {\n /**\n * Create a new Calendar instance\n * @param {import('../../types.js').CalendarConfig} [config={}] - Configuration options\n */\n constructor(config = {}) {\n // Initialize timezone manager first\n this.timezoneManager = new TimezoneManager();\n\n // Initialize configuration\n this.config = {\n view: 'month',\n date: new Date(),\n weekStartsOn: 0, // 0 = Sunday\n locale: 'en-US',\n timeZone: config.timeZone || this.timezoneManager.getSystemTimezone(),\n showWeekNumbers: false,\n showWeekends: true,\n fixedWeekCount: true,\n businessHours: {\n start: '09:00',\n end: '17:00'\n },\n ...config\n };\n\n // Initialize core components with timezone support\n this.eventStore = new EventStore({ timezone: this.config.timeZone });\n this.state = new StateManager({\n view: this.config.view,\n currentDate: this.config.date,\n weekStartsOn: this.config.weekStartsOn,\n locale: this.config.locale,\n timeZone: this.config.timeZone,\n showWeekNumbers: this.config.showWeekNumbers,\n showWeekends: this.config.showWeekends,\n fixedWeekCount: this.config.fixedWeekCount,\n businessHours: this.config.businessHours\n });\n\n // Event emitter for calendar events\n this.listeners = new Map();\n\n // Plugins\n this.plugins = new Set();\n\n // View instances (lazy loaded)\n this.views = new Map();\n\n // Set up internal listeners\n this._setupInternalListeners();\n\n // Load initial events if provided\n if (config.events) {\n this.setEvents(config.events);\n }\n }\n\n /**\n * Set the calendar view\n * @param {import('../../types.js').ViewType} viewType - The view type ('month', 'week', 'day', 'list')\n * @param {Date} [date=null] - Optional date to navigate to\n */\n setView(viewType, date = null) {\n this.state.setView(viewType);\n\n if (date) {\n this.state.setCurrentDate(date);\n }\n\n this._emit('viewChange', {\n view: viewType,\n date: date || this.state.get('currentDate')\n });\n }\n\n /**\n * Get the current view type\n * @returns {import('../../types.js').ViewType} The current view type\n */\n getView() {\n return this.state.get('view');\n }\n\n /**\n * Navigate to the next period\n */\n next() {\n this.state.navigateNext();\n this._emit('navigate', {\n direction: 'next',\n date: this.state.get('currentDate'),\n view: this.state.get('view')\n });\n }\n\n /**\n * Navigate to the previous period\n */\n previous() {\n this.state.navigatePrevious();\n this._emit('navigate', {\n direction: 'previous',\n date: this.state.get('currentDate'),\n view: this.state.get('view')\n });\n }\n\n /**\n * Navigate to today\n */\n today() {\n this.state.navigateToday();\n this._emit('navigate', {\n direction: 'today',\n date: this.state.get('currentDate'),\n view: this.state.get('view')\n });\n }\n\n /**\n * Navigate to a specific date\n * @param {Date} date - The date to navigate to\n */\n goToDate(date) {\n this.state.setCurrentDate(date);\n this._emit('navigate', {\n direction: 'goto',\n date: date,\n view: this.state.get('view')\n });\n }\n\n /**\n * Alias for goToDate (compat)\n * @param {Date} date - The date to navigate to\n */\n setDate(date) {\n this.goToDate(date);\n }\n\n /**\n * Get the current date\n * @returns {Date}\n */\n getCurrentDate() {\n return new Date(this.state.get('currentDate'));\n }\n\n /**\n * Add an event\n * @param {import('../events/Event.js').Event|import('../../types.js').EventData} eventData - Event data or Event instance\n * @returns {import('../events/Event.js').Event} The added event\n */\n addEvent(eventData) {\n // If eventData is not an Event instance and doesn't have a timezone, use calendar's timezone\n if (!(eventData instanceof Event) && !eventData.timeZone) {\n eventData = { ...eventData, timeZone: this.config.timeZone };\n }\n\n const event = this.eventStore.addEvent(eventData);\n\n this._emit('eventAdd', { event });\n\n return event;\n }\n\n /**\n * Update an event\n * @param {string} eventId - The event ID\n * @param {Object} updates - Properties to update\n * @returns {Event} The updated event\n */\n updateEvent(eventId, updates) {\n const oldEvent = this.eventStore.getEvent(eventId);\n const event = this.eventStore.updateEvent(eventId, updates);\n\n this._emit('eventUpdate', { event, oldEvent });\n\n return event;\n }\n\n /**\n * Remove an event\n * @param {string} eventId - The event ID\n * @returns {boolean} True if removed\n */\n removeEvent(eventId) {\n const event = this.eventStore.getEvent(eventId);\n const removed = this.eventStore.removeEvent(eventId);\n\n if (removed) {\n this._emit('eventRemove', { event });\n }\n\n return removed;\n }\n\n /**\n * Alias for removeEvent (compat)\n * @param {string} eventId - The event ID\n * @returns {boolean} True if removed\n */\n deleteEvent(eventId) {\n return this.removeEvent(eventId);\n }\n\n /**\n * Get an event by ID\n * @param {string} eventId - The event ID\n * @returns {Event|null}\n */\n getEvent(eventId) {\n return this.eventStore.getEvent(eventId);\n }\n\n /**\n * Get all events\n * @returns {Event[]}\n */\n getEvents() {\n return this.eventStore.getAllEvents();\n }\n\n /**\n * Set all events (replaces existing)\n * @param {Event[]} events - Array of events\n */\n setEvents(events) {\n this.eventStore.loadEvents(events);\n this._emit('eventsSet', { events: this.getEvents() });\n }\n\n /**\n * Query events with filters\n * @param {Object} filters - Query filters\n * @returns {Event[]}\n */\n queryEvents(filters) {\n return this.eventStore.queryEvents(filters);\n }\n\n /**\n * Get events for a specific date\n * @param {Date} date - The date\n * @param {string} [timezone] - Timezone for the query (defaults to calendar timezone)\n * @returns {Event[]}\n */\n getEventsForDate(date, timezone = null) {\n return this.eventStore.getEventsForDate(date, timezone || this.config.timeZone);\n }\n\n /**\n * Get events in a date range\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @param {string} [timezone] - Timezone for the query (defaults to calendar timezone)\n * @returns {Event[]}\n */\n getEventsInRange(start, end, timezone = null) {\n return this.eventStore.getEventsInRange(start, end, true, timezone || this.config.timeZone);\n }\n\n /**\n * Set the calendar's timezone\n * @param {string} timezone - IANA timezone identifier\n */\n setTimezone(timezone) {\n const parsedTimezone = this.timezoneManager.parseTimezone(timezone);\n const previousTimezone = this.config.timeZone;\n\n this.config.timeZone = parsedTimezone;\n this.eventStore.defaultTimezone = parsedTimezone;\n this.state.setState({ timeZone: parsedTimezone });\n\n this._emit('timezoneChange', {\n timezone: parsedTimezone,\n previousTimezone: previousTimezone\n });\n }\n\n /**\n * Get the current timezone\n * @returns {string} Current timezone\n */\n getTimezone() {\n return this.config.timeZone;\n }\n\n /**\n * Set the calendar locale\n * @param {string} locale - Locale identifier (e.g. 'en-US')\n */\n setLocale(locale) {\n this.config.locale = locale;\n this.state.setState({ locale });\n this._emit('localeChange', { locale });\n }\n\n /**\n * Set the week start day\n * @param {number} weekStartsOn - 0 = Sunday, 1 = Monday, etc.\n */\n setWeekStartsOn(weekStartsOn) {\n this.config.weekStartsOn = weekStartsOn;\n this.state.setState({ weekStartsOn });\n this._emit('weekStartsOnChange', { weekStartsOn });\n }\n\n /**\n * Convert a date from one timezone to another\n * @param {Date} date - Date to convert\n * @param {string} fromTimezone - Source timezone\n * @param {string} toTimezone - Target timezone\n * @returns {Date} Converted date\n */\n convertTimezone(date, fromTimezone, toTimezone) {\n return this.timezoneManager.convertTimezone(date, fromTimezone, toTimezone);\n }\n\n /**\n * Convert a date to the calendar's timezone\n * @param {Date} date - Date to convert\n * @param {string} fromTimezone - Source timezone\n * @returns {Date} Date in calendar timezone\n */\n toCalendarTimezone(date, fromTimezone) {\n return this.timezoneManager.convertTimezone(date, fromTimezone, this.config.timeZone);\n }\n\n /**\n * Convert a date from the calendar's timezone\n * @param {Date} date - Date in calendar timezone\n * @param {string} toTimezone - Target timezone\n * @returns {Date} Converted date\n */\n fromCalendarTimezone(date, toTimezone) {\n return this.timezoneManager.convertTimezone(date, this.config.timeZone, toTimezone);\n }\n\n /**\n * Format a date in a specific timezone\n * @param {Date} date - Date to format\n * @param {string} [timezone] - Timezone for formatting (defaults to calendar timezone)\n * @param {Object} [options] - Formatting options\n * @returns {string} Formatted date string\n */\n formatInTimezone(date, timezone = null, options = {}) {\n return this.timezoneManager.formatInTimezone(\n date,\n timezone || this.config.timeZone,\n options\n );\n }\n\n /**\n * Get list of common timezones with offsets\n * @returns {Array<{value: string, label: string, offset: string}>} Timezone list\n */\n getTimezones() {\n return this.timezoneManager.getCommonTimezones();\n }\n\n /**\n * Get overlapping event groups for a date\n * @param {Date} date - The date to check\n * @param {boolean} timedOnly - Only include timed events\n * @returns {Array<Event[]>} Array of event groups that overlap\n */\n getOverlapGroups(date, timedOnly = true) {\n return this.eventStore.getOverlapGroups(date, timedOnly);\n }\n\n /**\n * Calculate event positions for rendering\n * @param {Event[]} events - Array of overlapping events\n * @returns {Map<string, {column: number, totalColumns: number}>} Position data\n */\n calculateEventPositions(events) {\n return this.eventStore.calculateEventPositions(events);\n }\n\n /**\n * Get the current view's data\n * @returns {import('../../types.js').MonthViewData|import('../../types.js').WeekViewData|import('../../types.js').DayViewData|import('../../types.js').ListViewData|null} View-specific data\n */\n getViewData() {\n const view = this.state.get('view');\n const currentDate = this.state.get('currentDate');\n\n switch (view) {\n case 'month':\n return this._getMonthViewData(currentDate);\n case 'week':\n return this._getWeekViewData(currentDate);\n case 'day':\n return this._getDayViewData(currentDate);\n case 'list':\n return this._getListViewData(currentDate);\n default:\n return null;\n }\n }\n\n /**\n * Get month view data\n * @private\n */\n _getMonthViewData(date) {\n const year = date.getFullYear();\n const month = date.getMonth();\n const weekStartsOn = this.state.get('weekStartsOn');\n const fixedWeekCount = this.state.get('fixedWeekCount');\n\n // Get the first day of the month\n const firstDay = new Date(year, month, 1);\n\n // Get the last day of the month\n const lastDay = new Date(year, month + 1, 0);\n\n // Calculate the start date (beginning of the week containing the first day)\n const startDate = DateUtils.startOfWeek(firstDay, weekStartsOn);\n\n // Calculate weeks\n const weeks = [];\n let currentDate = new Date(startDate);\n\n // Generate weeks\n const maxWeeks = fixedWeekCount ? 6 : Math.ceil((lastDay.getDate() + DateUtils.getDayOfWeek(firstDay, weekStartsOn)) / 7);\n\n for (let weekIndex = 0; weekIndex < maxWeeks; weekIndex++) {\n const week = {\n weekNumber: DateUtils.getWeekNumber(currentDate),\n days: []\n };\n\n for (let dayIndex = 0; dayIndex < 7; dayIndex++) {\n const dayDate = new Date(currentDate);\n const isCurrentMonth = dayDate.getMonth() === month;\n const isToday = DateUtils.isToday(dayDate);\n const isWeekend = dayDate.getDay() === 0 || dayDate.getDay() === 6;\n\n week.days.push({\n date: dayDate,\n dayOfMonth: dayDate.getDate(),\n isCurrentMonth,\n isToday,\n isWeekend,\n events: this.getEventsForDate(dayDate)\n });\n\n // Use DateUtils.addDays to handle month boundaries correctly\n currentDate = DateUtils.addDays(currentDate, 1);\n }\n\n weeks.push(week);\n }\n\n return {\n type: 'month',\n year,\n month,\n monthName: DateUtils.getMonthName(date, this.state.get('locale')),\n weeks,\n startDate,\n endDate: new Date(currentDate.getTime() - 1) // Last moment of the view\n };\n }\n\n /**\n * Get week view data\n * @private\n */\n _getWeekViewData(date) {\n const weekStartsOn = this.state.get('weekStartsOn');\n const startDate = DateUtils.startOfWeek(date, weekStartsOn);\n const endDate = DateUtils.endOfWeek(date, weekStartsOn);\n\n const days = [];\n const currentDate = new Date(startDate);\n\n for (let i = 0; i < 7; i++) {\n const dayDate = new Date(currentDate);\n days.push({\n date: dayDate,\n dayOfMonth: dayDate.getDate(),\n dayOfWeek: dayDate.getDay(),\n dayName: DateUtils.getDayName(dayDate, this.state.get('locale')),\n isToday: DateUtils.isToday(dayDate),\n isWeekend: dayDate.getDay() === 0 || dayDate.getDay() === 6,\n events: this.getEventsForDate(dayDate),\n // Add overlap groups for positioning overlapping events\n overlapGroups: this.eventStore.getOverlapGroups(dayDate, true),\n getEventPositions: (events) => this.eventStore.calculateEventPositions(events)\n });\n // Move to next day\n currentDate.setDate(currentDate.getDate() + 1);\n }\n\n return {\n type: 'week',\n weekNumber: DateUtils.getWeekNumber(startDate),\n startDate,\n endDate,\n days\n };\n }\n\n /**\n * Get day view data\n * @private\n */\n _getDayViewData(date) {\n const events = this.getEventsForDate(date);\n\n // Separate all-day and timed events\n const allDayEvents = events.filter(e => e.allDay);\n const timedEvents = events.filter(e => !e.allDay);\n\n // Create hourly slots for timed events\n const hours = [];\n for (let hour = 0; hour < 24; hour++) {\n const hourDate = new Date(date);\n hourDate.setHours(hour, 0, 0, 0);\n const hourEnd = new Date(date);\n hourEnd.setHours(hour + 1, 0, 0, 0);\n\n hours.push({\n hour,\n time: DateUtils.formatTime(hourDate, this.state.get('locale')),\n events: timedEvents.filter(event => {\n // Check if event occurs during this hour (not just starts)\n // Event occurs in this hour if it overlaps with the hour slot\n return event.start < hourEnd && event.end > hourDate;\n })\n });\n }\n\n return {\n type: 'day',\n date,\n dayName: DateUtils.getDayName(date, this.state.get('locale')),\n isToday: DateUtils.isToday(date),\n allDayEvents,\n hours\n };\n }\n\n /**\n * Get list view data\n * @private\n */\n _getListViewData(date) {\n // Get events for the next 30 days\n const startDate = new Date(date);\n startDate.setHours(0, 0, 0, 0);\n\n const endDate = new Date(startDate);\n endDate.setDate(endDate.getDate() + 30);\n\n const events = this.getEventsInRange(startDate, endDate);\n\n // Group events by day\n const groupedEvents = new Map();\n\n events.forEach(event => {\n const dateKey = event.start.toDateString();\n if (!groupedEvents.has(dateKey)) {\n groupedEvents.set(dateKey, {\n date: new Date(event.start),\n events: []\n });\n }\n groupedEvents.get(dateKey).events.push(event);\n });\n\n // Convert to sorted array\n const days = Array.from(groupedEvents.values())\n .sort((a, b) => a.date - b.date)\n .map(day => ({\n ...day,\n dayName: DateUtils.getDayName(day.date, this.state.get('locale')),\n isToday: DateUtils.isToday(day.date)\n }));\n\n return {\n type: 'list',\n startDate,\n endDate,\n days,\n totalEvents: events.length\n };\n }\n\n /**\n * Select an event\n * @param {string} eventId - Event ID to select\n */\n selectEvent(eventId) {\n const event = this.getEvent(eventId);\n if (event) {\n this.state.selectEvent(eventId);\n this._emit('eventSelect', { event });\n }\n }\n\n /**\n * Clear event selection\n */\n clearEventSelection() {\n const eventId = this.state.get('selectedEventId');\n this.state.clearEventSelection();\n\n if (eventId) {\n this._emit('eventDeselect', { eventId });\n }\n }\n\n /**\n * Select a date\n * @param {Date} date - Date to select\n */\n selectDate(date) {\n this.state.selectDate(date);\n this._emit('dateSelect', { date });\n }\n\n /**\n * Clear date selection\n */\n clearDateSelection() {\n const date = this.state.get('selectedDate');\n this.state.clearDateSelection();\n\n if (date) {\n this._emit('dateDeselect', { date });\n }\n }\n\n /**\n * Subscribe to calendar events\n * @param {string} eventName - Event name\n * @param {Function} callback - Callback function\n * @returns {Function} Unsubscribe function\n */\n on(eventName, callback) {\n if (!this.listeners.has(eventName)) {\n this.listeners.set(eventName, new Set());\n }\n this.listeners.get(eventName).add(callback);\n\n return () => this.off(eventName, callback);\n }\n\n /**\n * Unsubscribe from calendar events\n * @param {string} eventName - Event name\n * @param {Function} callback - Callback function\n */\n off(eventName, callback) {\n const callbacks = this.listeners.get(eventName);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) {\n this.listeners.delete(eventName);\n }\n }\n }\n\n /**\n * Emit an event\n * @private\n */\n _emit(eventName, data) {\n const callbacks = this.listeners.get(eventName);\n if (callbacks) {\n callbacks.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error(`Error in event listener for \"${eventName}\":`, error);\n }\n });\n }\n }\n\n /**\n * Set up internal listeners\n * @private\n */\n _setupInternalListeners() {\n // Listen to state changes\n this.state.subscribe((newState, oldState) => {\n this._emit('stateChange', { newState, oldState });\n });\n\n // Listen to event store changes\n this.eventStore.subscribe((change) => {\n this._emit('eventStoreChange', change);\n });\n }\n\n /**\n * Install a plugin\n * @param {Object} plugin - Plugin object with install method\n */\n use(plugin) {\n if (this.plugins.has(plugin)) {\n console.warn('Plugin already installed');\n return;\n }\n\n if (typeof plugin.install === 'function') {\n plugin.install(this);\n this.plugins.add(plugin);\n } else {\n throw new Error('Plugin must have an install method');\n }\n }\n\n /**\n * Destroy the calendar and clean up\n */\n destroy() {\n // Clear all listeners\n this.listeners.clear();\n\n // Clear stores\n this.eventStore.clear();\n\n // Clear plugins\n this.plugins.forEach(plugin => {\n if (typeof plugin.uninstall === 'function') {\n plugin.uninstall(this);\n }\n });\n this.plugins.clear();\n\n this._emit('destroy');\n }\n}// Test workflow\n","/**\n * EventBus - Central event communication system\n *\n * Enables decoupled communication between components\n * Supports event namespacing and wildcard subscriptions\n */\n\nclass EventBus {\n constructor() {\n this.events = new Map();\n this.wildcardHandlers = new Set();\n }\n\n /**\n * Subscribe to an event\n * @param {string} eventName - Event name or pattern (supports wildcards)\n * @param {Function} handler - Event handler function\n * @param {Object} options - Subscription options\n * @returns {Function} Unsubscribe function\n */\n on(eventName, handler, options = {}) {\n const { once = false, priority = 0 } = options;\n\n // Handle wildcard subscriptions\n if (eventName.includes('*')) {\n const subscription = { pattern: eventName, handler, once, priority };\n this.wildcardHandlers.add(subscription);\n return () => this.wildcardHandlers.delete(subscription);\n }\n\n // Regular event subscription\n if (!this.events.has(eventName)) {\n this.events.set(eventName, []);\n }\n\n const subscription = { handler, once, priority };\n const handlers = this.events.get(eventName);\n handlers.push(subscription);\n handlers.sort((a, b) => b.priority - a.priority);\n\n // Return unsubscribe function\n return () => {\n const index = handlers.indexOf(subscription);\n if (index > -1) {\n handlers.splice(index, 1);\n }\n };\n }\n\n /**\n * Subscribe to an event that fires only once\n */\n once(eventName, handler, options = {}) {\n return this.on(eventName, handler, { ...options, once: true });\n }\n\n /**\n * Unsubscribe from an event\n */\n off(eventName, handler) {\n if (!this.events.has(eventName)) return;\n\n const handlers = this.events.get(eventName);\n const index = handlers.findIndex(sub => sub.handler === handler);\n if (index > -1) {\n handlers.splice(index, 1);\n }\n\n if (handlers.length === 0) {\n this.events.delete(eventName);\n }\n }\n\n /**\n * Emit an event\n * @param {string} eventName - Event name\n * @param {*} data - Event data\n * @returns {Promise} Resolves when all handlers complete\n */\n async emit(eventName, data) {\n const promises = [];\n\n // Handle direct subscriptions\n if (this.events.has(eventName)) {\n const handlers = [...this.events.get(eventName)];\n\n for (const subscription of handlers) {\n const { handler, once } = subscription;\n\n if (once) {\n this.off(eventName, handler);\n }\n\n try {\n const result = handler(data, eventName);\n if (result instanceof Promise) {\n promises.push(result);\n }\n } catch (error) {\n console.error(`Error in event handler for ${eventName}:`, error);\n }\n }\n }\n\n // Handle wildcard subscriptions (copy Set to avoid mutation during iteration)\n const toRemove = [];\n for (const subscription of [...this.wildcardHandlers]) {\n if (this.matchesPattern(eventName, subscription.pattern)) {\n const { handler, once } = subscription;\n\n if (once) {\n toRemove.push(subscription);\n }\n\n try {\n const result = handler(data, eventName);\n if (result instanceof Promise) {\n promises.push(result);\n }\n } catch (error) {\n console.error(`Error in wildcard handler for ${eventName}:`, error);\n }\n }\n }\n // Remove one-time handlers after iteration\n toRemove.forEach(sub => this.wildcardHandlers.delete(sub));\n\n return Promise.all(promises);\n }\n\n /**\n * Check if event name matches a pattern\n */\n matchesPattern(eventName, pattern) {\n const regex = new RegExp('^' + pattern.replace(/\\*/g, '.*') + '$');\n return regex.test(eventName);\n }\n\n /**\n * Clear all event subscriptions\n */\n clear() {\n this.events.clear();\n this.wildcardHandlers.clear();\n }\n\n /**\n * Get all registered event names\n */\n getEventNames() {\n return Array.from(this.events.keys());\n }\n\n /**\n * Get handler count for an event\n */\n getHandlerCount(eventName) {\n return this.events.has(eventName) ? this.events.get(eventName).length : 0;\n }\n}\n\n// Create singleton instance\nconst eventBus = new EventBus();\n\n// Export both the class and singleton\nexport { EventBus, eventBus as default };","/**\n * StateManager - Centralized state management for Force Calendar\n *\n * Wraps the @forcecalendar/core Calendar instance\n * Provides reactive state updates and component synchronization\n */\n\nimport { Calendar } from '@forcecalendar/core';\nimport eventBus from './EventBus.js';\n\nclass StateManager {\n constructor(config = {}) {\n // Initialize Core Calendar instance\n this.calendar = new Calendar({\n view: config.view || 'month',\n date: config.date || new Date(),\n weekStartsOn: config.weekStartsOn ?? 0,\n locale: config.locale || 'en-US',\n timeZone: config.timeZone || Intl.DateTimeFormat().resolvedOptions().timeZone,\n ...config\n });\n\n // Internal state\n this.state = {\n view: this.calendar.getView(),\n currentDate: this.calendar.getCurrentDate(),\n events: [],\n selectedEvent: null,\n selectedDate: null,\n loading: false,\n error: null,\n config: { ...config }\n };\n\n // State change subscribers\n this.subscribers = new Set();\n\n // Bind methods\n this.subscribe = this.subscribe.bind(this);\n this.unsubscribe = this.unsubscribe.bind(this);\n this.setState = this.setState.bind(this);\n }\n\n // State management\n getState() {\n return { ...this.state };\n }\n\n setState(updates, options = {}) {\n const { silent = false } = options;\n const oldState = { ...this.state };\n this.state = { ...this.state, ...updates };\n\n if (!silent) {\n this.notifySubscribers(oldState, this.state);\n this.emitStateChange(oldState, this.state);\n }\n\n return this.state;\n }\n\n subscribe(callback) {\n this.subscribers.add(callback);\n return () => this.unsubscribe(callback);\n }\n\n unsubscribe(callback) {\n this.subscribers.delete(callback);\n }\n\n notifySubscribers(oldState, newState) {\n this.subscribers.forEach(callback => {\n try {\n callback(newState, oldState);\n } catch (error) {\n console.error('Error in state subscriber:', error);\n }\n });\n }\n\n emitStateChange(oldState, newState) {\n const changedKeys = Object.keys(newState).filter(\n key => oldState[key] !== newState[key]\n );\n\n changedKeys.forEach(key => {\n eventBus.emit(`state:${key}:changed`, {\n oldValue: oldState[key],\n newValue: newState[key],\n state: newState\n });\n });\n\n if (changedKeys.length > 0) {\n eventBus.emit('state:changed', { oldState, newState, changedKeys });\n }\n }\n\n // Calendar operations\n setView(view) {\n this.calendar.setView(view);\n this.setState({ view });\n eventBus.emit('view:changed', { view });\n }\n\n getView() {\n return this.state.view;\n }\n\n setDate(date) {\n this.calendar.goToDate(date);\n this.setState({ currentDate: this.calendar.getCurrentDate() });\n eventBus.emit('date:changed', { date: this.state.currentDate });\n }\n\n getCurrentDate() {\n return this.state.currentDate;\n }\n\n // Navigation\n next() {\n this.calendar.next();\n this.setState({ currentDate: this.calendar.getCurrentDate() });\n eventBus.emit('navigation:next', { date: this.state.currentDate });\n }\n\n previous() {\n this.calendar.previous();\n this.setState({ currentDate: this.calendar.getCurrentDate() });\n eventBus.emit('navigation:previous', { date: this.state.currentDate });\n }\n\n today() {\n this.calendar.today();\n this.setState({ currentDate: this.calendar.getCurrentDate() });\n eventBus.emit('navigation:today', { date: this.state.currentDate });\n }\n\n goToDate(date) {\n this.calendar.goToDate(date);\n this.setState({ currentDate: this.calendar.getCurrentDate() });\n eventBus.emit('navigation:goto', { date: this.state.currentDate });\n }\n\n // Event management\n addEvent(event) {\n const addedEvent = this.calendar.addEvent(event);\n if (!addedEvent) {\n console.error('Failed to add event to calendar');\n eventBus.emit('event:error', { action: 'add', event, error: 'Failed to add event' });\n return null;\n }\n // Create new array to avoid mutation before setState\n const newEvents = [...this.state.events, addedEvent];\n this.setState({ events: newEvents });\n eventBus.emit('event:added', { event: addedEvent });\n return addedEvent;\n }\n\n updateEvent(eventId, updates) {\n const event = this.calendar.updateEvent(eventId, updates);\n if (!event) {\n console.error(`Failed to update event: ${eventId}`);\n eventBus.emit('event:error', { action: 'update', eventId, updates, error: 'Event not found in calendar' });\n return null;\n }\n\n const index = this.state.events.findIndex(e => e.id === eventId);\n if (index === -1) {\n console.error(`Event ${eventId} not found in state`);\n eventBus.emit('event:error', { action: 'update', eventId, error: 'Event not found in state' });\n return null;\n }\n\n // Create new array to avoid mutation before setState\n const newEvents = [...this.state.events];\n newEvents[index] = event;\n this.setState({ events: newEvents });\n eventBus.emit('event:updated', { event });\n return event;\n }\n\n deleteEvent(eventId) {\n const deleted = this.calendar.removeEvent(eventId);\n if (!deleted) {\n console.error(`Failed to delete event: ${eventId}`);\n eventBus.emit('event:error', { action: 'delete', eventId, error: 'Event not found' });\n return false;\n }\n // Create new array to avoid mutation before setState\n const newEvents = this.state.events.filter(e => e.id !== eventId);\n this.setState({ events: newEvents });\n eventBus.emit('event:deleted', { eventId });\n return true;\n }\n\n getEvents() {\n return this.calendar.getEvents();\n }\n\n getEventsForDate(date) {\n return this.calendar.getEventsForDate(date);\n }\n\n getEventsInRange(start, end) {\n return this.calendar.getEventsInRange(start, end);\n }\n\n // View data\n getViewData() {\n const viewData = this.calendar.getViewData();\n return this.enrichViewData(viewData);\n }\n\n enrichViewData(viewData) {\n const selectedDateString = this.state.selectedDate?.toDateString();\n\n // Strategy 1: Multi-week structure (Month view)\n if (viewData.weeks) {\n viewData.weeks = viewData.weeks.map(week => ({\n ...week,\n days: week.days.map(day => {\n const dayDate = new Date(day.date);\n return {\n ...day,\n isSelected: dayDate.toDateString() === selectedDateString,\n events: day.events || this.getEventsForDate(dayDate)\n };\n })\n }));\n }\n\n // Strategy 2: Flat days structure (Week view or list view)\n if (viewData.days) {\n viewData.days = viewData.days.map(day => {\n const dayDate = new Date(day.date);\n return {\n ...day,\n isSelected: dayDate.toDateString() === selectedDateString,\n events: day.events || this.getEventsForDate(dayDate)\n };\n });\n }\n\n // Strategy 3: Single day structure (Day view)\n if (viewData.date && !viewData.days && !viewData.weeks) {\n const dayDate = new Date(viewData.date);\n viewData.isSelected = dayDate.toDateString() === selectedDateString;\n viewData.events = viewData.events || this.getEventsForDate(dayDate);\n }\n\n return viewData;\n }\n\n // Selection management\n selectEvent(event) {\n this.setState({ selectedEvent: event });\n eventBus.emit('event:selected', { event });\n }\n\n selectEventById(eventId) {\n const event = this.state.events.find(e => e.id === eventId);\n if (event) {\n this.selectEvent(event);\n }\n }\n\n deselectEvent() {\n this.setState({ selectedEvent: null });\n eventBus.emit('event:deselected', {});\n }\n\n selectDate(date) {\n this.setState({ selectedDate: date });\n eventBus.emit('date:selected', { date });\n }\n\n deselectDate() {\n this.setState({ selectedDate: null });\n eventBus.emit('date:deselected', {});\n }\n\n // Utility methods\n isToday(date) {\n const today = new Date();\n return date.toDateString() === today.toDateString();\n }\n\n isSelectedDate(date) {\n return this.state.selectedDate &&\n date.toDateString() === this.state.selectedDate.toDateString();\n }\n\n isWeekend(date) {\n const day = date.getDay();\n return day === 0 || day === 6;\n }\n\n // Loading state\n setLoading(loading) {\n this.setState({ loading });\n }\n\n // Error handling\n setError(error) {\n this.setState({ error });\n if (error) {\n eventBus.emit('error', { error });\n }\n }\n\n clearError() {\n this.setState({ error: null });\n }\n\n // Configuration\n updateConfig(config) {\n this.setState({ config: { ...this.state.config, ...config } });\n\n // Update calendar configuration if needed\n if (config.weekStartsOn !== undefined) {\n this.calendar.setWeekStartsOn(config.weekStartsOn);\n }\n if (config.locale !== undefined) {\n this.calendar.setLocale(config.locale);\n }\n if (config.timeZone !== undefined) {\n this.calendar.setTimezone(config.timeZone);\n }\n }\n\n // Destroy\n destroy() {\n this.subscribers.clear();\n this.state = null;\n this.calendar = null;\n }\n}\n\n// Export StateManager\nexport default StateManager;","/**\n * DateUtils - Date formatting and manipulation utilities\n *\n * Extends Core DateUtils with UI-specific formatting\n */\n\nimport { DateUtils as CoreDateUtils } from '@forcecalendar/core';\n\nexport class DateUtils extends CoreDateUtils {\n /**\n * Format date for display\n */\n static formatDate(date, format = 'default', locale = 'en-US') {\n if (!date) return '';\n\n const formats = {\n default: { year: 'numeric', month: 'long', day: 'numeric' },\n short: { year: 'numeric', month: 'short', day: 'numeric' },\n long: { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' },\n month: { year: 'numeric', month: 'long' },\n monthShort: { year: 'numeric', month: 'short' },\n day: { weekday: 'long', day: 'numeric' },\n dayShort: { weekday: 'short', day: 'numeric' },\n time: { hour: 'numeric', minute: '2-digit' },\n timeShort: { hour: 'numeric' },\n datetime: {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit'\n }\n };\n\n const options = formats[format] || formats.default;\n return new Intl.DateTimeFormat(locale, options).format(date);\n }\n\n /**\n * Format time for display\n */\n static formatTime(date, showMinutes = true, use24Hour = false, locale = 'en-US') {\n if (!date) return '';\n\n const options = {\n hour: 'numeric',\n minute: showMinutes ? '2-digit' : undefined,\n hour12: !use24Hour\n };\n\n return new Intl.DateTimeFormat(locale, options).format(date);\n }\n\n /**\n * Format date range for display\n */\n static formatDateRange(start, end, locale = 'en-US') {\n if (!start) return '';\n if (!end || this.isSameDay(start, end)) {\n return this.formatDate(start, 'default', locale);\n }\n\n const startFormat = this.isSameYear(start, end) ? 'short' : 'default';\n return `${this.formatDate(start, startFormat, locale)} - ${this.formatDate(end, 'default', locale)}`;\n }\n\n /**\n * Format time range for display\n */\n static formatTimeRange(start, end, locale = 'en-US') {\n if (!start) return '';\n\n const startTime = this.formatTime(start, true, false, locale);\n if (!end) return startTime;\n\n const endTime = this.formatTime(end, true, false, locale);\n return `${startTime} - ${endTime}`;\n }\n\n /**\n * Get relative time string (e.g., \"2 hours ago\", \"in 3 days\")\n */\n static getRelativeTime(date, baseDate = new Date(), locale = 'en-US') {\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n const diff = date - baseDate;\n const diffInSeconds = Math.floor(diff / 1000);\n const diffInMinutes = Math.floor(diffInSeconds / 60);\n const diffInHours = Math.floor(diffInMinutes / 60);\n const diffInDays = Math.floor(diffInHours / 24);\n const diffInWeeks = Math.floor(diffInDays / 7);\n const diffInMonths = Math.floor(diffInDays / 30);\n const diffInYears = Math.floor(diffInDays / 365);\n\n if (Math.abs(diffInSeconds) < 60) {\n return rtf.format(diffInSeconds, 'second');\n } else if (Math.abs(diffInMinutes) < 60) {\n return rtf.format(diffInMinutes, 'minute');\n } else if (Math.abs(diffInHours) < 24) {\n return rtf.format(diffInHours, 'hour');\n } else if (Math.abs(diffInDays) < 7) {\n return rtf.format(diffInDays, 'day');\n } else if (Math.abs(diffInWeeks) < 4) {\n return rtf.format(diffInWeeks, 'week');\n } else if (Math.abs(diffInMonths) < 12) {\n return rtf.format(diffInMonths, 'month');\n } else {\n return rtf.format(diffInYears, 'year');\n }\n }\n\n /**\n * Check if date is today\n */\n static isToday(date) {\n const today = new Date();\n return this.isSameDay(date, today);\n }\n\n /**\n * Check if date is in the past\n */\n static isPast(date) {\n return date < new Date();\n }\n\n /**\n * Check if date is in the future\n */\n static isFuture(date) {\n return date > new Date();\n }\n\n /**\n * Get calendar week number\n */\n static getWeekNumber(date) {\n const firstDayOfYear = new Date(date.getFullYear(), 0, 1);\n const pastDaysOfYear = (date - firstDayOfYear) / 86400000;\n return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);\n }\n\n /**\n * Get day abbreviation\n */\n static getDayAbbreviation(dayIndex, locale = 'en-US') {\n const date = new Date(2024, 0, 7 + dayIndex); // Jan 7, 2024 is a Sunday\n return new Intl.DateTimeFormat(locale, { weekday: 'short' }).format(date);\n }\n\n /**\n * Get month name\n */\n static getMonthName(monthIndex, format = 'long', locale = 'en-US') {\n const date = new Date(2024, monthIndex, 1);\n return new Intl.DateTimeFormat(locale, { month: format }).format(date);\n }\n\n /**\n * Parse time string (e.g., \"14:30\" or \"2:30 PM\")\n */\n static parseTimeString(timeStr, baseDate = new Date()) {\n const date = new Date(baseDate);\n const [time, period] = timeStr.split(/\\s+/);\n const [hours, minutes] = time.split(':').map(Number);\n\n let adjustedHours = hours;\n if (period) {\n if (period.toLowerCase() === 'pm' && hours < 12) {\n adjustedHours = hours + 12;\n } else if (period.toLowerCase() === 'am' && hours === 12) {\n adjustedHours = 0;\n }\n }\n\n date.setHours(adjustedHours, minutes || 0, 0, 0);\n return date;\n }\n}\n\nexport default DateUtils;","/**\n * DOMUtils - DOM manipulation and event utilities\n */\n\nexport class DOMUtils {\n /**\n * Create element with attributes and children\n */\n static createElement(tag, attributes = {}, children = []) {\n const element = document.createElement(tag);\n\n // Set attributes\n Object.entries(attributes).forEach(([key, value]) => {\n if (key === 'className') {\n element.className = value;\n } else if (key === 'style' && typeof value === 'object') {\n Object.assign(element.style, value);\n } else if (key.startsWith('data-')) {\n element.setAttribute(key, value);\n } else if (key.startsWith('on') && typeof value === 'function') {\n const eventName = key.slice(2).toLowerCase();\n element.addEventListener(eventName, value);\n } else {\n element[key] = value;\n }\n });\n\n // Add children\n children.forEach(child => {\n if (typeof child === 'string') {\n element.appendChild(document.createTextNode(child));\n } else if (child instanceof Node) {\n element.appendChild(child);\n }\n });\n\n return element;\n }\n\n /**\n * Add multiple event listeners\n */\n static addEventListeners(element, events) {\n Object.entries(events).forEach(([event, handler]) => {\n element.addEventListener(event, handler);\n });\n\n // Return cleanup function\n return () => {\n Object.entries(events).forEach(([event, handler]) => {\n element.removeEventListener(event, handler);\n });\n };\n }\n\n /**\n * Delegate event handling\n */\n static delegate(element, selector, event, handler) {\n const delegatedHandler = (e) => {\n const target = e.target.closest(selector);\n if (target && element.contains(target)) {\n handler.call(target, e);\n }\n };\n\n element.addEventListener(event, delegatedHandler);\n return () => element.removeEventListener(event, delegatedHandler);\n }\n\n /**\n * Get element position relative to viewport\n */\n static getPosition(element) {\n const rect = element.getBoundingClientRect();\n return {\n top: rect.top + window.scrollY,\n left: rect.left + window.scrollX,\n bottom: rect.bottom + window.scrollY,\n right: rect.right + window.scrollX,\n width: rect.width,\n height: rect.height\n };\n }\n\n /**\n * Check if element is in viewport\n */\n static isInViewport(element, threshold = 0) {\n const rect = element.getBoundingClientRect();\n return (\n rect.top >= -threshold &&\n rect.left >= -threshold &&\n rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) + threshold &&\n rect.right <= (window.innerWidth || document.documentElement.clientWidth) + threshold\n );\n }\n\n /**\n * Smooth scroll to element\n */\n static scrollToElement(element, options = {}) {\n const { behavior = 'smooth', block = 'start', inline = 'nearest' } = options;\n element.scrollIntoView({ behavior, block, inline });\n }\n\n /**\n * Get computed style value\n */\n static getStyle(element, property) {\n return window.getComputedStyle(element).getPropertyValue(property);\n }\n\n /**\n * Set multiple styles\n */\n static setStyles(element, styles) {\n Object.assign(element.style, styles);\n }\n\n /**\n * Add/remove classes with animation support\n */\n static async animateClass(element, className, duration = 300) {\n element.classList.add(className);\n await this.wait(duration);\n element.classList.remove(className);\n }\n\n /**\n * Wait for animation/transition to complete\n */\n static waitForAnimation(element, eventType = 'animationend') {\n return new Promise(resolve => {\n const handler = () => {\n element.removeEventListener(eventType, handler);\n resolve();\n };\n element.addEventListener(eventType, handler);\n });\n }\n\n /**\n * Utility wait function\n */\n static wait(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n /**\n * Parse HTML string safely\n */\n static parseHTML(htmlString) {\n const template = document.createElement('template');\n template.innerHTML = htmlString.trim();\n return template.content.firstChild;\n }\n\n /**\n * Escape HTML to prevent XSS\n */\n static escapeHTML(str) {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n /**\n * Debounce function calls\n */\n static debounce(func, wait = 250) {\n let timeout;\n return function executedFunction(...args) {\n const later = () => {\n clearTimeout(timeout);\n func(...args);\n };\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n };\n }\n\n /**\n * Throttle function calls\n */\n static throttle(func, limit = 250) {\n let inThrottle;\n return function(...args) {\n if (!inThrottle) {\n func.apply(this, args);\n inThrottle = true;\n setTimeout(() => inThrottle = false, limit);\n }\n };\n }\n\n /**\n * Get closest parent matching selector\n */\n static closest(element, selector) {\n return element.closest(selector);\n }\n\n /**\n * Get all parents matching selector\n */\n static parents(element, selector) {\n const parents = [];\n let parent = element.parentElement;\n\n while (parent) {\n if (parent.matches(selector)) {\n parents.push(parent);\n }\n parent = parent.parentElement;\n }\n\n return parents;\n }\n\n /**\n * Measure element dimensions including margins\n */\n static getOuterDimensions(element) {\n const styles = window.getComputedStyle(element);\n const margin = {\n top: parseInt(styles.marginTop),\n right: parseInt(styles.marginRight),\n bottom: parseInt(styles.marginBottom),\n left: parseInt(styles.marginLeft)\n };\n\n return {\n width: element.offsetWidth + margin.left + margin.right,\n height: element.offsetHeight + margin.top + margin.bottom,\n margin\n };\n }\n\n /**\n * Clone element with event listeners\n */\n static cloneWithEvents(element, deep = true) {\n const clone = element.cloneNode(deep);\n\n // Copy event listeners (Note: This is a simplified version)\n // In production, you'd need a more robust event copying mechanism\n return clone;\n }\n\n /**\n * Focus trap for modals/dialogs\n */\n static trapFocus(container) {\n const focusableElements = container.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n\n // Handle case where there are no focusable elements\n if (focusableElements.length === 0) {\n // Make container focusable as fallback\n container.setAttribute('tabindex', '-1');\n container.focus();\n return () => container.removeAttribute('tabindex');\n }\n\n const firstFocusable = focusableElements[0];\n const lastFocusable = focusableElements[focusableElements.length - 1];\n\n const handleKeyDown = (e) => {\n if (e.key !== 'Tab') return;\n\n if (e.shiftKey) {\n if (document.activeElement === firstFocusable) {\n lastFocusable?.focus();\n e.preventDefault();\n }\n } else {\n if (document.activeElement === lastFocusable) {\n firstFocusable?.focus();\n e.preventDefault();\n }\n }\n };\n\n container.addEventListener('keydown', handleKeyDown);\n firstFocusable?.focus();\n\n return () => container.removeEventListener('keydown', handleKeyDown);\n }\n}\n\nexport default DOMUtils;","/**\n * StyleUtils - Styling utilities and theme management\n */\n\nexport class StyleUtils {\n /**\n * Default theme colors\n */\n static colors = {\n primary: '#3B82F6', // Modern Blue\n secondary: '#64748B', // Slate\n accent: '#F59E0B', // Amber\n danger: '#EF4444', // Red\n warning: '#F97316', // Orange\n info: '#06B6D4', // Cyan\n success: '#22C55E', // Green\n light: '#F8FAFC',\n dark: '#0F172A',\n white: '#FFFFFF',\n gray: {\n 50: '#F8FAFC',\n 100: '#F1F5F9',\n 200: '#E2E8F0',\n 300: '#CBD5E1',\n 400: '#94A3B8',\n 500: '#64748B',\n 600: '#475569',\n 700: '#334155',\n 800: '#1E293B',\n 900: '#0F172A'\n }\n };\n\n /**\n * Common CSS variables\n */\n static cssVariables = {\n // \"Pro\" Palette - Functional & Sharp\n '--fc-primary-color': '#2563EB', // International Blue (Focus)\n '--fc-primary-hover': '#1D4ED8',\n '--fc-primary-light': '#EFF6FF',\n \n // Neutral Scale (Slate/Gray for structure)\n '--fc-text-color': '#111827', // Almost Black\n '--fc-text-secondary': '#6B7280', // Cool Gray\n '--fc-text-light': '#9CA3AF',\n \n '--fc-border-color': '#E5E7EB', // Crisp Light Gray\n '--fc-border-color-hover': '#D1D5DB',\n \n '--fc-background': '#FFFFFF',\n '--fc-background-alt': '#FAFAFA', // Very subtle off-white\n '--fc-background-hover': '#F3F4F6',\n '--fc-background-active': '#E5E7EB',\n\n // Semantic Colors\n '--fc-accent-color': '#F59E0B',\n '--fc-danger-color': '#EF4444',\n '--fc-success-color': '#10B981',\n\n // Typography - optimized for UI density\n '--fc-font-family': 'Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n '--fc-font-size-xs': '11px',\n '--fc-font-size-sm': '12px',\n '--fc-font-size-base': '13px', // Slightly smaller for density\n '--fc-font-size-lg': '15px',\n '--fc-font-size-xl': '18px',\n '--fc-font-size-2xl': '24px',\n '--fc-line-height': '1.4',\n '--fc-font-weight-normal': '400',\n '--fc-font-weight-medium': '500',\n '--fc-font-weight-semibold': '600',\n '--fc-font-weight-bold': '700',\n\n // Spacing - Tighter\n '--fc-spacing-xs': '2px',\n '--fc-spacing-sm': '6px',\n '--fc-spacing-md': '10px',\n '--fc-spacing-lg': '14px',\n '--fc-spacing-xl': '20px',\n '--fc-spacing-2xl': '28px',\n\n // Border\n '--fc-border-width': '1px',\n '--fc-border-radius-sm': '3px', // Micro rounding\n '--fc-border-radius': '5px',\n '--fc-border-radius-lg': '8px',\n '--fc-border-radius-full': '9999px',\n\n // Shadows - Minimal/Functional\n '--fc-shadow-sm': '0 1px 1px rgba(0,0,0,0.05)',\n '--fc-shadow': '0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06)',\n '--fc-shadow-md': '0 4px 6px -1px rgba(0, 0, 0, 0.1)',\n '--fc-shadow-lg': '0 10px 15px -3px rgba(0, 0, 0, 0.1)',\n\n // Transitions - Snappy\n '--fc-transition-fast': '100ms ease-out',\n '--fc-transition': '150ms ease-out',\n '--fc-transition-slow': '250ms ease-out',\n\n // Z-index\n '--fc-z-dropdown': '1000',\n '--fc-z-modal': '2000',\n '--fc-z-tooltip': '3000'\n };\n\n /**\n * Get CSS variable value\n */\n static getCSSVariable(name, element = document.documentElement) {\n return getComputedStyle(element).getPropertyValue(name).trim();\n }\n\n /**\n * Set CSS variables\n */\n static setCSSVariables(variables, element = document.documentElement) {\n Object.entries(variables).forEach(([key, value]) => {\n element.style.setProperty(key, value);\n });\n }\n\n /**\n * Generate base styles\n */\n static getBaseStyles() {\n return `\n :host {\n /* Apply CSS variables */\n ${Object.entries(this.cssVariables)\n .map(([key, value]) => `${key}: ${value};`)\n .join('\\n ')}\n\n /* Base styles */\n display: block;\n box-sizing: border-box;\n font-family: var(--fc-font-family);\n font-size: var(--fc-font-size-base);\n line-height: var(--fc-line-height);\n color: var(--fc-text-color);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n\n *, *::before, *::after {\n box-sizing: inherit;\n }\n\n /* Reset styles */\n h1, h2, h3, h4, h5, h6, p {\n margin: 0;\n font-weight: normal;\n }\n\n button {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n margin: 0;\n }\n\n /* Accessibility */\n .visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n /* Focus styles */\n :focus-visible {\n outline: 2px solid var(--fc-primary-color);\n outline-offset: 2px;\n }\n `;\n }\n\n /**\n * Generate button styles\n */\n static getButtonStyles() {\n return `\n .fc-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 8px 16px;\n font-size: var(--fc-font-size-sm);\n font-weight: var(--fc-font-weight-medium);\n line-height: 1.25rem;\n border-radius: var(--fc-border-radius);\n border: 1px solid transparent;\n cursor: pointer;\n transition: all var(--fc-transition-fast);\n outline: none;\n user-select: none;\n gap: var(--fc-spacing-sm);\n white-space: nowrap;\n }\n\n .fc-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .fc-btn-primary {\n background: var(--fc-primary-color);\n color: white;\n box-shadow: var(--fc-shadow-sm);\n }\n\n .fc-btn-primary:hover:not(:disabled) {\n background: var(--fc-primary-hover);\n box-shadow: var(--fc-shadow);\n }\n\n .fc-btn-secondary {\n background: white;\n border-color: var(--fc-border-color);\n color: var(--fc-text-color);\n box-shadow: var(--fc-shadow-sm);\n }\n\n .fc-btn-secondary:hover:not(:disabled) {\n background: var(--fc-background-hover);\n border-color: var(--fc-border-color-hover);\n }\n\n .fc-btn-outline {\n background: transparent;\n border-color: var(--fc-border-color);\n color: var(--fc-text-secondary);\n }\n\n .fc-btn-outline:hover:not(:disabled) {\n background: var(--fc-background-hover);\n color: var(--fc-text-color);\n border-color: var(--fc-border-color-hover);\n }\n\n .fc-btn-ghost {\n background: transparent;\n color: var(--fc-text-secondary);\n }\n\n .fc-btn-ghost:hover:not(:disabled) {\n background: var(--fc-background-hover);\n color: var(--fc-text-color);\n }\n\n .fc-btn-sm {\n padding: 6px 12px;\n font-size: var(--fc-font-size-xs);\n }\n\n .fc-btn-lg {\n padding: 10px 20px;\n font-size: var(--fc-font-size-base);\n }\n\n .fc-btn-icon {\n width: 32px;\n height: 32px;\n padding: 0;\n border-radius: var(--fc-border-radius-full);\n }\n `;\n }\n\n /**\n * Darken color by percentage\n */\n static darken(color, percent) {\n const num = parseInt(color.replace('#', ''), 16);\n const amt = Math.round(2.55 * percent);\n const R = (num >> 16) - amt;\n const G = (num >> 8 & 0x00FF) - amt;\n const B = (num & 0x0000FF) - amt;\n return '#' + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +\n (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +\n (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);\n }\n\n /**\n * Lighten color by percentage\n */\n static lighten(color, percent) {\n const num = parseInt(color.replace('#', ''), 16);\n const amt = Math.round(2.55 * percent);\n const R = (num >> 16) + amt;\n const G = (num >> 8 & 0x00FF) + amt;\n const B = (num & 0x0000FF) + amt;\n return '#' + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +\n (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +\n (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);\n }\n\n /**\n * Get contrast color (black or white) for background\n */\n static getContrastColor(bgColor) {\n const color = bgColor.replace('#', '');\n const r = parseInt(color.substr(0, 2), 16);\n const g = parseInt(color.substr(2, 2), 16);\n const b = parseInt(color.substr(4, 2), 16);\n const yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;\n return yiq >= 128 ? '#000000' : '#FFFFFF';\n }\n\n /**\n * Sanitize color value to prevent CSS injection\n * Returns the color if valid, or a fallback color if invalid\n */\n static sanitizeColor(color, fallback = 'var(--fc-primary-color)') {\n if (!color || typeof color !== 'string') {\n return fallback;\n }\n\n // Trim and check for dangerous characters that could break out of CSS\n const trimmed = color.trim();\n if (/[;{}()<>\\\"\\'\\\\]/.test(trimmed)) {\n return fallback;\n }\n\n // Allow hex colors (#RGB, #RRGGBB, #RRGGBBAA)\n if (/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(trimmed)) {\n return trimmed;\n }\n\n // Allow CSS variables\n if (/^var\\(--[a-zA-Z0-9-]+\\)$/.test(trimmed)) {\n return trimmed;\n }\n\n // Allow rgb/rgba with numbers only\n if (/^rgba?\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*(,\\s*(0|1|0?\\.\\d+))?\\s*\\)$/.test(trimmed)) {\n return trimmed;\n }\n\n // Allow safe CSS color keywords\n const safeKeywords = [\n 'transparent', 'currentColor', 'inherit',\n 'black', 'white', 'red', 'green', 'blue', 'yellow', 'orange', 'purple',\n 'pink', 'brown', 'gray', 'grey', 'cyan', 'magenta', 'lime', 'navy',\n 'teal', 'aqua', 'maroon', 'olive', 'silver', 'fuchsia'\n ];\n if (safeKeywords.includes(trimmed.toLowerCase())) {\n return trimmed;\n }\n\n return fallback;\n }\n\n /**\n * Convert hex to rgba\n */\n static hexToRgba(hex, alpha = 1) {\n const color = hex.replace('#', '');\n const r = parseInt(color.substr(0, 2), 16);\n const g = parseInt(color.substr(2, 2), 16);\n const b = parseInt(color.substr(4, 2), 16);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n }\n\n /**\n * Generate grid styles\n */\n static getGridStyles() {\n return `\n .fc-grid {\n display: grid;\n gap: 1px;\n background: var(--fc-border-color);\n border: 1px solid var(--fc-border-color);\n border-radius: var(--fc-border-radius);\n overflow: hidden;\n }\n\n .fc-grid-cell {\n background: var(--fc-background);\n padding: var(--fc-spacing-sm);\n min-height: 100px;\n position: relative;\n }\n\n .fc-grid-cell:hover {\n background: var(--fc-background-hover);\n }\n\n .fc-grid-header {\n background: var(--fc-background-alt);\n padding: var(--fc-spacing-sm);\n font-weight: var(--fc-font-weight-semibold);\n text-align: center;\n color: var(--fc-text-secondary);\n font-size: var(--fc-font-size-xs);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n `;\n }\n\n /**\n * Get responsive breakpoints\n */\n static breakpoints = {\n xs: '320px',\n sm: '576px',\n md: '768px',\n lg: '992px',\n xl: '1200px',\n '2xl': '1400px'\n };\n\n /**\n * Generate media query\n */\n static mediaQuery(breakpoint, styles) {\n const size = this.breakpoints[breakpoint];\n if (!size) return '';\n return `@media (min-width: ${size}) { ${styles} }`;\n }\n\n /**\n * Animation keyframes\n */\n static getAnimations() {\n return `\n @keyframes fc-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n @keyframes fc-slide-in-up {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n @keyframes fc-slide-in-down {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n @keyframes fc-scale-in {\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n @keyframes fc-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n .fc-fade-in {\n animation: fc-fade-in var(--fc-transition);\n }\n\n .fc-slide-in-up {\n animation: fc-slide-in-up var(--fc-transition);\n }\n\n .fc-scale-in {\n animation: fc-scale-in var(--fc-transition);\n }\n `;\n }\n}\n\nexport default StyleUtils;","/**\n * MonthView - Month grid view component\n *\n * Displays a traditional month calendar grid with events\n */\n\nimport { BaseComponent } from '../../core/BaseComponent.js';\nimport { DOMUtils } from '../../utils/DOMUtils.js';\nimport { DateUtils } from '../../utils/DateUtils.js';\nimport { StyleUtils } from '../../utils/StyleUtils.js';\n\nexport class MonthView extends BaseComponent {\n constructor() {\n super();\n this._stateManager = null;\n this.viewData = null;\n this.config = {\n maxEventsToShow: 3,\n };\n this._registryCheckInterval = null;\n }\n\n connectedCallback() {\n super.connectedCallback();\n console.log('[MonthView] connectedCallback - starting registry polling');\n // Poll for registry since attributeChangedCallback doesn't work in Locker Service\n this._startRegistryPolling();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this._stopRegistryPolling();\n }\n\n _startRegistryPolling() {\n // Check immediately\n this._checkRegistry();\n\n // Then poll every 100ms until we find it (max 5 seconds)\n let attempts = 0;\n this._registryCheckInterval = setInterval(() => {\n attempts++;\n if (this._stateManager || attempts > 50) {\n this._stopRegistryPolling();\n return;\n }\n this._checkRegistry();\n }, 100);\n }\n\n _stopRegistryPolling() {\n if (this._registryCheckInterval) {\n clearInterval(this._registryCheckInterval);\n this._registryCheckInterval = null;\n }\n }\n\n _checkRegistry() {\n const registryId = this.getAttribute('data-state-registry');\n console.log('[MonthView] Checking registry for ID:', registryId);\n if (registryId && window.__forceCalendarRegistry && window.__forceCalendarRegistry[registryId]) {\n const manager = window.__forceCalendarRegistry[registryId];\n console.log('[MonthView] Found stateManager in registry');\n this._stopRegistryPolling();\n this.setStateManager(manager);\n }\n }\n\n set stateManager(manager) {\n console.log('[MonthView] stateManager setter called with:', !!manager);\n this.setStateManager(manager);\n }\n\n // Method alternative for Salesforce Locker Service compatibility\n setStateManager(manager) {\n console.log('[MonthView] setStateManager method called with:', !!manager);\n // Prevent re-initialization if same manager\n if (this._stateManager === manager) {\n console.log('[MonthView] stateManager already set, skipping');\n return;\n }\n this._stateManager = manager;\n if (manager) {\n console.log('[MonthView] Subscribing to state changes and loading view data');\n // Subscribe to state changes\n this.unsubscribe = manager.subscribe(this.handleStateUpdate.bind(this));\n this.loadViewData();\n }\n }\n\n get stateManager() {\n return this._stateManager;\n }\n\n handleStateUpdate(newState, oldState) {\n if (newState.currentDate !== oldState.currentDate) {\n this.loadViewData(); // Full reload if the month/year changes\n return;\n }\n\n if (newState.events !== oldState.events) {\n this.updateEvents();\n }\n\n if (newState.selectedDate !== oldState.selectedDate) {\n this.updateSelection(newState.selectedDate, oldState.selectedDate);\n }\n }\n\n updateEvents() {\n this.loadViewData(); // For now, we still do a full reload. A more granular update would be more complex.\n }\n\n updateSelection(newDate, oldDate) {\n if (oldDate) {\n const oldDateEl = this.shadowRoot.querySelector(`[data-date^=\"${oldDate.toISOString().split('T')[0]}\"]`);\n if (oldDateEl) {\n oldDateEl.classList.remove('selected');\n }\n }\n if (newDate) {\n const newDateEl = this.shadowRoot.querySelector(`[data-date^=\"${newDate.toISOString().split('T')[0]}\"]`);\n if (newDateEl) {\n newDateEl.classList.add('selected');\n }\n }\n }\n\n loadViewData() {\n console.log('[MonthView] loadViewData called, stateManager:', !!this.stateManager);\n if (!this.stateManager) return;\n\n const viewData = this.stateManager.getViewData();\n console.log('[MonthView] viewData from stateManager:', viewData);\n this.viewData = this.processViewData(viewData);\n console.log('[MonthView] processed viewData:', this.viewData);\n this.render();\n console.log('[MonthView] render completed');\n }\n\n processViewData(viewData) {\n if (!viewData || !viewData.weeks) return null;\n\n const selectedDate = this.stateManager?.getState()?.selectedDate;\n\n const weeks = viewData.weeks.map(week => {\n return week.days.map(day => {\n const dayDate = new Date(day.date);\n const isSelected = selectedDate && dayDate.toDateString() === selectedDate.toDateString();\n \n const processedEvents = day.events.map(event => ({\n ...event,\n textColor: this.getContrastingTextColor(event.backgroundColor)\n }));\n\n return {\n ...day,\n date: dayDate,\n isOtherMonth: !day.isCurrentMonth,\n isSelected,\n events: processedEvents,\n };\n });\n });\n\n return {\n ...viewData,\n weeks,\n month: viewData.month,\n year: viewData.year\n };\n }\n\n getContrastingTextColor(bgColor) {\n if (!bgColor || typeof bgColor !== 'string') return 'white';\n\n // Extract hex color, removing # if present\n const color = (bgColor.charAt(0) === '#') ? bgColor.substring(1) : bgColor;\n\n // Validate hex format (3 or 6 characters)\n if (!/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(color)) {\n return 'white'; // Fallback for invalid format\n }\n\n // Expand 3-char hex to 6-char\n const fullColor = color.length === 3\n ? color[0] + color[0] + color[1] + color[1] + color[2] + color[2]\n : color;\n\n const r = parseInt(fullColor.substring(0, 2), 16);\n const g = parseInt(fullColor.substring(2, 4), 16);\n const b = parseInt(fullColor.substring(4, 6), 16);\n\n // Check for NaN (shouldn't happen with validation, but just in case)\n if (isNaN(r) || isNaN(g) || isNaN(b)) {\n return 'white';\n }\n\n const uicolors = [r / 255, g / 255, b / 255];\n const c = uicolors.map((col) => {\n if (col <= 0.03928) {\n return col / 12.92;\n }\n return Math.pow((col + 0.055) / 1.055, 2.4);\n });\n const L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]);\n return (L > 0.179) ? 'black' : 'white';\n }\n\n isSelectedDate(date) {\n const selectedDate = this.stateManager?.getState()?.selectedDate;\n return selectedDate && date.toDateString() === selectedDate.toDateString();\n }\n\n getStyles() {\n return `\n :host {\n display: block;\n height: 100%;\n }\n\n .month-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n }\n\n .month-header {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n background: var(--fc-background);\n border-bottom: 1px solid var(--fc-border-color);\n z-index: 5;\n }\n\n .month-header-cell {\n padding: var(--fc-spacing-sm);\n text-align: left; /* Align with dates */\n font-weight: var(--fc-font-weight-bold);\n font-size: 10px;\n color: var(--fc-text-light);\n text-transform: uppercase;\n letter-spacing: 0.1em;\n border-left: 1px solid transparent; /* Alignment hack */\n padding-left: 8px;\n }\n\n .month-body {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n .month-week {\n flex: 1;\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n border-bottom: 1px solid var(--fc-border-color);\n }\n \n .month-week:last-child {\n border-bottom: none;\n }\n\n .month-day {\n background: var(--fc-background);\n padding: 4px;\n position: relative;\n cursor: default;\n overflow: hidden;\n min-height: 80px;\n border-right: 1px solid var(--fc-border-color);\n display: flex;\n flex-direction: column;\n min-width: 0; /* Critical for Grid Item shrinking */\n }\n\n .month-day:last-child {\n border-right: none;\n }\n\n .month-day:hover {\n background: var(--fc-background-alt);\n }\n\n .month-day.other-month {\n background: var(--fc-background-alt);\n background-image: linear-gradient(45deg, #f9fafb 25%, transparent 25%, transparent 50%, #f9fafb 50%, #f9fafb 75%, transparent 75%, transparent);\n background-size: 10px 10px;\n }\n\n .month-day.other-month .day-number {\n color: var(--fc-text-light);\n opacity: 0.5;\n }\n\n .month-day.selected {\n background: var(--fc-background-hover);\n }\n\n .day-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px;\n margin-bottom: 2px;\n }\n \n .day-number {\n font-size: 12px;\n font-family: var(--fc-font-family); /* Ensure monospaced feel if available */\n font-weight: var(--fc-font-weight-medium);\n color: var(--fc-text-color);\n line-height: 1;\n }\n \n .month-day.today .day-number {\n color: white;\n background: var(--fc-danger-color); /* Red for Today (Calendar standard) */\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n margin-left: -4px; /* Optical adjustment */\n }\n\n .day-events {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n overflow: hidden;\n }\n\n /* Precision Event Style */\n .event-item {\n font-size: 11px;\n padding: 2px 6px;\n border-radius: 2px; /* Micro rounding */\n \n /* High Contrast */\n background: var(--fc-primary-color);\n color: white;\n \n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n line-height: 1.3;\n font-weight: var(--fc-font-weight-medium);\n margin: 0 1px;\n border: 1px solid rgba(0,0,0,0.05); /* Subtle border for definition */\n }\n\n .event-item:hover {\n opacity: 0.9;\n }\n\n .event-time {\n font-weight: var(--fc-font-weight-bold);\n margin-right: 4px;\n opacity: 0.9;\n font-size: 10px;\n }\n\n .more-events {\n font-size: 10px;\n color: var(--fc-text-secondary);\n cursor: pointer;\n padding: 1px 4px;\n font-weight: var(--fc-font-weight-medium);\n text-align: right;\n }\n\n .more-events:hover {\n color: var(--fc-text-color);\n text-decoration: underline;\n }\n\n /* Responsive adjustments */\n @media (max-width: 768px) {\n .month-day {\n min-height: 60px;\n padding: 2px;\n }\n\n .day-number {\n font-size: 11px;\n }\n\n .event-item {\n font-size: 10px;\n padding: 1px 3px;\n }\n\n .month-header-cell {\n font-size: 9px;\n padding: 4px;\n }\n }\n\n /* Loading state */\n .month-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--fc-text-secondary);\n font-weight: var(--fc-font-weight-medium);\n }\n\n /* Empty state */\n .month-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--fc-text-secondary);\n gap: var(--fc-spacing-md);\n }\n\n .empty-icon {\n width: 48px;\n height: 48px;\n opacity: 0.3;\n }\n `;\n }\n\n template() {\n if (!this.viewData) {\n return `\n <div class=\"month-view\">\n <div class=\"month-loading\">Loading calendar...</div>\n </div>\n `;\n }\n\n return `\n <div class=\"month-view\">\n ${this.renderHeader()}\n ${this.renderBody()}\n </div>\n `;\n }\n\n renderHeader() {\n const { config } = this.stateManager.getState();\n const days = [];\n const weekStartsOn = config.weekStartsOn || 0;\n\n for (let i = 0; i < 7; i++) {\n const dayIndex = (weekStartsOn + i) % 7;\n const dayName = DateUtils.getDayAbbreviation(dayIndex, config.locale);\n days.push(`<div class=\"month-header-cell\">${dayName}</div>`);\n }\n\n return `\n <div class=\"month-header\">\n ${days.join('')}\n </div>\n `;\n }\n\n renderBody() {\n if (!this.viewData.weeks || this.viewData.weeks.length === 0) {\n return `\n <div class=\"month-body\">\n <div class=\"month-empty\">\n <svg class=\"empty-icon\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11z\"/>\n </svg>\n <p>No calendar data available</p>\n </div>\n </div>\n `;\n }\n\n const weeks = this.viewData.weeks.map(week => this.renderWeek(week));\n\n return `\n <div class=\"month-body\">\n ${weeks.join('')}\n </div>\n `;\n }\n\n renderWeek(weekDays) {\n const days = weekDays.map(day => this.renderDay(day));\n\n return `\n <div class=\"month-week\">\n ${days.join('')}\n </div>\n `;\n }\n\n renderDay(dayData) {\n const { date, dayOfMonth, isOtherMonth, isToday, isSelected, isWeekend, events = [] } = dayData;\n const dayNumber = dayOfMonth;\n\n // Build classes\n const classes = ['month-day'];\n if (isOtherMonth) classes.push('other-month');\n if (isToday) classes.push('today');\n if (isSelected) classes.push('selected');\n if (isWeekend) classes.push('weekend');\n\n // Render events\n const visibleEvents = events.slice(0, this.config.maxEventsToShow);\n const remainingCount = events.length - this.config.maxEventsToShow;\n\n const eventsHtml = visibleEvents.map(event => this.renderEvent(event)).join('');\n const moreHtml = remainingCount > 0 ?\n `<div class=\"more-events\">+${remainingCount} more</div>` : '';\n\n return `\n <div class=\"${classes.join(' ')}\"\n data-date=\"${date.toISOString()}\"\n data-day=\"${dayNumber}\">\n <div class=\"day-header\">\n <span class=\"day-number\">${dayNumber}</span>\n </div>\n <div class=\"day-events\">\n ${eventsHtml}\n ${moreHtml}\n </div>\n </div>\n `;\n }\n\n renderEvent(event) {\n const { title, start, allDay, backgroundColor, textColor } = event;\n\n let style = '';\n if (backgroundColor) {\n const safeColor = StyleUtils.sanitizeColor(backgroundColor);\n const safeTextColor = StyleUtils.sanitizeColor(textColor, 'white');\n style += `background-color: ${safeColor}; color: ${safeTextColor};`;\n }\n\n let timeStr = '';\n if (!allDay && start) {\n timeStr = DateUtils.formatTime(new Date(start), false, false);\n }\n\n const classes = ['event-item'];\n if (allDay) classes.push('all-day');\n\n return `\n <div class=\"${classes.join(' ')}\"\n style=\"${style}\"\n data-event-id=\"${event.id}\"\n title=\"${DOMUtils.escapeHTML(title)}\">\n ${timeStr ? `<span class=\"event-time\">${timeStr}</span>` : ''}\n <span class=\"event-title\">${DOMUtils.escapeHTML(title)}</span>\n </div>\n `;\n }\n\n afterRender() {\n // Add click handlers for days\n this.$$('.month-day').forEach(dayEl => {\n this.addListener(dayEl, 'click', this.handleDayClick);\n });\n\n // Add click handlers for events\n this.$$('.event-item').forEach(eventEl => {\n this.addListener(eventEl, 'click', this.handleEventClick);\n });\n\n // Add click handlers for \"more events\"\n this.$$('.more-events').forEach(moreEl => {\n this.addListener(moreEl, 'click', this.handleMoreClick);\n });\n }\n\n handleDayClick(event) {\n event.stopPropagation();\n const dayEl = event.currentTarget;\n const date = new Date(dayEl.dataset.date);\n\n this.stateManager.selectDate(date);\n this.emit('day-click', { date });\n }\n\n handleEventClick(event) {\n event.stopPropagation();\n const eventEl = event.currentTarget;\n const eventId = eventEl.dataset.eventId;\n const calendarEvent = this.stateManager.getEvents().find(e => e.id === eventId);\n\n if (calendarEvent) {\n this.stateManager.selectEvent(calendarEvent);\n this.emit('event-click', { event: calendarEvent });\n }\n }\n\n handleMoreClick(event) {\n event.stopPropagation();\n const dayEl = event.currentTarget.closest('.month-day');\n const date = new Date(dayEl.dataset.date);\n const events = this.stateManager.getEventsForDate(date);\n\n this.emit('more-events-click', { date, events });\n }\n\n unmount() {\n if (this.unsubscribe) {\n this.unsubscribe();\n }\n }\n}\n\n// Export both the class and as default\nexport default MonthView;","/**\n * WeekView - Professional Time-Grid Week View\n * \n * Displays a 7-day schedule with a time axis and event positioning.\n */\n\nimport { BaseComponent } from '../../core/BaseComponent.js';\nimport { DateUtils } from '../../utils/DateUtils.js';\nimport { StyleUtils } from '../../utils/StyleUtils.js';\nimport { DOMUtils } from '../../utils/DOMUtils.js';\n\nexport class WeekView extends BaseComponent {\n constructor() {\n super();\n this._stateManager = null;\n this.viewData = null;\n this.hours = Array.from({ length: 24 }, (_, i) => i); // 0-23\n this._registryCheckInterval = null;\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._startRegistryPolling();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n if (this._registryCheckInterval) {\n clearInterval(this._registryCheckInterval);\n }\n }\n\n _startRegistryPolling() {\n this._checkRegistry();\n let attempts = 0;\n this._registryCheckInterval = setInterval(() => {\n attempts++;\n if (this._stateManager || attempts > 50) {\n clearInterval(this._registryCheckInterval);\n return;\n }\n this._checkRegistry();\n }, 100);\n }\n\n _checkRegistry() {\n const registryId = this.getAttribute('data-state-registry');\n if (registryId && window.__forceCalendarRegistry && window.__forceCalendarRegistry[registryId]) {\n clearInterval(this._registryCheckInterval);\n this.setStateManager(window.__forceCalendarRegistry[registryId]);\n }\n }\n\n set stateManager(manager) {\n this.setStateManager(manager);\n }\n\n setStateManager(manager) {\n if (this._stateManager === manager) return;\n this._stateManager = manager;\n if (manager) {\n this.unsubscribe = manager.subscribe(this.handleStateUpdate.bind(this));\n this.loadViewData();\n }\n }\n\n get stateManager() {\n return this._stateManager;\n }\n\n handleStateUpdate(newState, oldState) {\n // Granular updates\n if (newState.currentDate !== oldState?.currentDate || newState.view !== oldState?.view) {\n this.loadViewData();\n return;\n }\n\n if (newState.events !== oldState?.events) {\n this.loadViewData(); // Simple reload for now\n }\n\n if (newState.selectedDate !== oldState?.selectedDate) {\n this.updateSelection(newState.selectedDate, oldState?.selectedDate);\n }\n }\n\n updateSelection(newDate, oldDate) {\n // Selection in WeekView is often visual on the column\n if (oldDate) {\n const oldDayEl = this.shadowRoot.querySelector(`[data-date^=\"${oldDate.toISOString().split('T')[0]}\"]`);\n if (oldDayEl) oldDayEl.classList.remove('selected');\n }\n if (newDate) {\n const newDayEl = this.shadowRoot.querySelector(`[data-date^=\"${newDate.toISOString().split('T')[0]}\"]`);\n if (newDayEl) newDayEl.classList.add('selected');\n }\n }\n\n loadViewData() {\n if (!this.stateManager) return;\n const viewData = this.stateManager.getViewData();\n this.viewData = this.processViewData(viewData);\n this.render();\n }\n\n processViewData(viewData) {\n if (!viewData) return null;\n\n let days = [];\n if (viewData.weeks && viewData.weeks.length > 0) {\n days = viewData.weeks[0].days;\n } else if (viewData.days) {\n days = viewData.days;\n }\n\n if (!days || days.length === 0) return null;\n\n return {\n ...viewData,\n days: days.map(day => {\n const dayDate = new Date(day.date);\n return {\n ...day,\n date: dayDate,\n isToday: DateUtils.isToday(dayDate),\n timedEvents: (day.events || []).filter(e => !e.allDay),\n allDayEvents: (day.events || []).filter(e => e.allDay)\n };\n })\n };\n }\n\n getStyles() {\n return `\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n }\n\n .week-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n min-height: 0;\n overflow: hidden;\n }\n\n /* Header Section */\n .week-header {\n display: grid;\n grid-template-columns: 60px repeat(7, 1fr);\n border-bottom: 1px solid var(--fc-border-color);\n background: var(--fc-background);\n z-index: 20;\n flex-shrink: 0;\n }\n\n .day-column-header {\n padding: 12px 8px;\n text-align: center;\n border-right: 1px solid var(--fc-border-color);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n }\n\n .day-name {\n font-size: 10px;\n font-weight: 700;\n color: var(--fc-text-light);\n text-transform: uppercase;\n letter-spacing: 0.1em;\n }\n\n .day-number {\n font-size: 16px;\n font-weight: 500;\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n color: var(--fc-text-color);\n }\n\n .is-today .day-number {\n background: var(--fc-danger-color);\n color: white;\n font-weight: 700;\n }\n\n /* All Day Events Row */\n .all-day-row {\n display: grid;\n grid-template-columns: 60px repeat(7, 1fr);\n border-bottom: 1px solid var(--fc-border-color);\n background: var(--fc-background-alt);\n min-height: 32px;\n flex-shrink: 0;\n }\n\n .all-day-label {\n font-size: 9px;\n color: var(--fc-text-light);\n display: flex;\n align-items: center;\n justify-content: center;\n border-right: 1px solid var(--fc-border-color);\n text-transform: uppercase;\n font-weight: 700;\n }\n\n .all-day-cell {\n border-right: 1px solid var(--fc-border-color);\n padding: 4px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n /* Body Section */\n .week-body {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n position: relative;\n display: grid;\n grid-template-columns: 60px repeat(7, 1fr);\n background: var(--fc-background);\n }\n\n .time-gutter {\n border-right: 1px solid var(--fc-border-color);\n background: var(--fc-background-alt);\n height: 1440px;\n }\n\n .time-slot-label {\n height: 60px;\n font-size: 10px;\n color: var(--fc-text-light);\n text-align: right;\n padding-right: 8px;\n font-weight: 500;\n }\n\n .day-column {\n border-right: 1px solid var(--fc-border-color);\n position: relative;\n height: 1440px;\n }\n\n .day-column.selected {\n background: var(--fc-background-hover);\n }\n\n /* Grid Lines Layer */\n .grid-lines {\n position: absolute;\n top: 0;\n left: 60px;\n right: 0;\n bottom: 0;\n pointer-events: none;\n }\n\n .grid-line {\n height: 60px;\n border-bottom: 1px solid var(--fc-border-color);\n width: 100%;\n }\n \n .grid-line:last-child {\n border-bottom: none;\n }\n\n .event-container {\n position: absolute;\n left: 2px;\n right: 2px;\n border-radius: 4px;\n padding: 4px 8px;\n font-size: 11px;\n font-weight: 500;\n color: white;\n background: var(--fc-primary-color);\n border: 1px solid rgba(0,0,0,0.1);\n overflow: hidden;\n box-shadow: var(--fc-shadow-sm);\n cursor: pointer;\n transition: transform 0.1s;\n z-index: 5;\n }\n\n .event-container:hover {\n z-index: 10;\n transform: scale(1.02);\n }\n\n .now-indicator {\n position: absolute;\n left: 0;\n right: 0;\n height: 2px;\n background: var(--fc-danger-color);\n z-index: 15;\n pointer-events: none;\n }\n `;\n }\n\n template() {\n if (!this.viewData) return '<div class=\"week-view\">Loading...</div>';\n\n return `\n <div class=\"week-view\">\n <div class=\"week-header\">\n <div class=\"time-gutter-header\"></div>\n ${this.viewData.days.map(day => `\n <div class=\"day-column-header ${day.isToday ? 'is-today' : ''}\">\n <span class=\"day-name\">${DateUtils.getDayAbbreviation(day.date.getDay())}</span>\n <span class=\"day-number\">${day.date.getDate()}</span>\n </div>\n `).join('')}\n </div>\n\n <div class=\"all-day-row\">\n <div class=\"all-day-label\">All day</div>\n ${this.viewData.days.map(day => `\n <div class=\"all-day-cell\">\n ${day.allDayEvents.map(e => this.renderAllDayEvent(e)).join('')}\n </div>\n `).join('')}\n </div>\n\n <div class=\"week-body\" id=\"scroll-container\">\n <div class=\"grid-lines\">\n ${this.hours.map(() => `<div class=\"grid-line\"></div>`).join('')}\n </div>\n\n <div class=\"time-gutter\">\n ${this.hours.map(h => `\n <div class=\"time-slot-label\">\n ${h === 0 ? '' : DateUtils.formatTime(new Date().setHours(h, 0), false)}\n </div>\n `).join('')}\n </div>\n\n ${this.viewData.days.map(day => `\n <div class=\"day-column\" data-date=\"${day.date.toISOString()}\">\n ${day.isToday ? this.renderNowIndicator() : ''}\n ${day.timedEvents.map(e => this.renderTimedEvent(e)).join('')}\n </div>\n `).join('')}\n </div>\n </div>\n `;\n }\n\n renderTimedEvent(event) {\n const start = new Date(event.start);\n const end = new Date(event.end);\n\n const startMinutes = start.getHours() * 60 + start.getMinutes();\n const durationMinutes = (end - start) / (1000 * 60);\n\n const top = startMinutes;\n const height = Math.max(durationMinutes, 20);\n\n const color = StyleUtils.sanitizeColor(event.backgroundColor);\n const textColor = StyleUtils.sanitizeColor(StyleUtils.getContrastColor(color), 'white');\n\n return `\n <div class=\"event-container\"\n style=\"top: ${top}px; height: ${height}px; background-color: ${color}; color: ${textColor};\"\n data-event-id=\"${event.id}\">\n <span class=\"event-title\">${DOMUtils.escapeHTML(event.title)}</span>\n <span class=\"event-time\">${DateUtils.formatTime(start)}</span>\n </div>\n `;\n }\n\n renderAllDayEvent(event) {\n const color = StyleUtils.sanitizeColor(event.backgroundColor);\n const textColor = StyleUtils.sanitizeColor(StyleUtils.getContrastColor(color), 'white');\n\n return `\n <div class=\"event-item\"\n style=\"background-color: ${color}; color: ${textColor}; font-size: 10px; padding: 2px 4px; border-radius: 2px; cursor: pointer; margin-bottom: 2px;\"\n data-event-id=\"${event.id}\">\n ${DOMUtils.escapeHTML(event.title)}\n </div>\n `;\n }\n\n renderNowIndicator() {\n const now = new Date();\n const minutes = now.getHours() * 60 + now.getMinutes();\n return `<div class=\"now-indicator\" style=\"top: ${minutes}px\"></div>`;\n }\n\n afterRender() {\n const container = this.$('#scroll-container');\n if (container && !this._scrolled) {\n container.scrollTop = 8 * 60 - 50;\n this._scrolled = true;\n }\n\n this.$$('[data-event-id]').forEach(el => {\n this.addListener(el, 'click', (e) => {\n e.stopPropagation();\n const eventId = e.currentTarget.dataset.eventId;\n const event = this.stateManager.getEvents().find(ev => ev.id === eventId);\n if (event) this.emit('event-click', { event });\n });\n });\n\n this.$$('.day-column').forEach(el => {\n this.addListener(el, 'click', (e) => {\n const col = e.currentTarget;\n const container = this.$('#scroll-container');\n const rect = col.getBoundingClientRect();\n const y = e.clientY - rect.top + (container ? container.scrollTop : 0);\n \n const date = new Date(col.dataset.date);\n date.setHours(Math.floor(y / 60), Math.floor(y % 60), 0, 0);\n \n this.stateManager.selectDate(date);\n this.emit('day-click', { date });\n });\n });\n }\n\n unmount() {\n if (this.unsubscribe) this.unsubscribe();\n }\n}\n\nexport default WeekView;\n","/**\n * DayView - Professional Time-Grid Day View\n * \n * Displays a single day schedule with a time axis and event positioning.\n */\n\nimport { BaseComponent } from '../../core/BaseComponent.js';\nimport { DateUtils } from '../../utils/DateUtils.js';\nimport { StyleUtils } from '../../utils/StyleUtils.js';\nimport { DOMUtils } from '../../utils/DOMUtils.js';\n\nexport class DayView extends BaseComponent {\n constructor() {\n super();\n this._stateManager = null;\n this.viewData = null;\n this.hours = Array.from({ length: 24 }, (_, i) => i);\n this._registryCheckInterval = null;\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._startRegistryPolling();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n if (this._registryCheckInterval) {\n clearInterval(this._registryCheckInterval);\n }\n }\n\n _startRegistryPolling() {\n this._checkRegistry();\n let attempts = 0;\n this._registryCheckInterval = setInterval(() => {\n attempts++;\n if (this._stateManager || attempts > 50) {\n clearInterval(this._registryCheckInterval);\n return;\n }\n this._checkRegistry();\n }, 100);\n }\n\n _checkRegistry() {\n const registryId = this.getAttribute('data-state-registry');\n if (registryId && window.__forceCalendarRegistry && window.__forceCalendarRegistry[registryId]) {\n clearInterval(this._registryCheckInterval);\n this.setStateManager(window.__forceCalendarRegistry[registryId]);\n }\n }\n\n set stateManager(manager) {\n this.setStateManager(manager);\n }\n\n setStateManager(manager) {\n if (this._stateManager === manager) return;\n this._stateManager = manager;\n if (manager) {\n this.unsubscribe = manager.subscribe(this.handleStateUpdate.bind(this));\n this.loadViewData();\n }\n }\n\n get stateManager() {\n return this._stateManager;\n }\n\n handleStateUpdate(newState, oldState) {\n // Granular updates\n if (newState.currentDate !== oldState?.currentDate || newState.view !== oldState?.view) {\n this.loadViewData();\n return;\n }\n\n if (newState.events !== oldState?.events) {\n this.loadViewData(); // Simple reload for now\n }\n\n if (newState.selectedDate !== oldState?.selectedDate) {\n this.updateSelection(newState.selectedDate, oldState?.selectedDate);\n }\n }\n\n updateSelection(newDate, oldDate) {\n const dayCol = this.shadowRoot.querySelector('.day-column');\n if (!dayCol) return;\n\n const isMatch = (date) => date && DateUtils.isSameDay(date, new Date(dayCol.dataset.date));\n \n if (isMatch(newDate)) {\n dayCol.classList.add('selected');\n } else {\n dayCol.classList.remove('selected');\n }\n }\n\n loadViewData() {\n if (!this.stateManager) return;\n const viewData = this.stateManager.getViewData();\n this.viewData = this.processViewData(viewData);\n this.render();\n }\n\n processViewData(viewData) {\n if (!viewData) return null;\n\n let dayData = null;\n const currentState = this.stateManager?.getState();\n const currentDate = currentState?.currentDate || new Date();\n\n if (viewData.days && Array.isArray(viewData.days) && viewData.days.length > 0) {\n dayData = viewData.days.find(d => DateUtils.isSameDay(new Date(d.date), currentDate)) || viewData.days[0];\n } \n else if (viewData.weeks && Array.isArray(viewData.weeks) && viewData.weeks.length > 0) {\n const allDays = viewData.weeks.flatMap(w => w.days || []);\n dayData = allDays.find(d => DateUtils.isSameDay(new Date(d.date), currentDate)) || allDays[0];\n }\n else if (viewData.date) {\n dayData = viewData;\n }\n\n if (!dayData) return null;\n\n const dayDate = new Date(dayData.date);\n return {\n ...viewData,\n day: {\n ...dayData,\n date: dayDate,\n isToday: DateUtils.isToday(dayDate),\n timedEvents: (dayData.events || []).filter(e => !e.allDay),\n allDayEvents: (dayData.events || []).filter(e => e.allDay)\n }\n };\n }\n\n getStyles() {\n return `\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n }\n\n .day-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n min-height: 0;\n overflow: hidden;\n }\n\n /* Header */\n .day-header {\n display: grid;\n grid-template-columns: 60px 1fr;\n border-bottom: 1px solid var(--fc-border-color);\n background: var(--fc-background);\n z-index: 20;\n flex-shrink: 0;\n }\n\n .day-column-header {\n padding: 16px 24px;\n text-align: left;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .day-name {\n font-size: 12px;\n font-weight: 700;\n color: var(--fc-text-light);\n text-transform: uppercase;\n letter-spacing: 0.1em;\n }\n\n .day-number {\n font-size: 24px;\n font-weight: 600;\n color: var(--fc-text-color);\n }\n\n .is-today .day-number {\n color: var(--fc-danger-color);\n }\n\n /* All Day Events */\n .all-day-row {\n display: grid;\n grid-template-columns: 60px 1fr;\n border-bottom: 1px solid var(--fc-border-color);\n background: var(--fc-background-alt);\n min-height: 36px;\n flex-shrink: 0;\n }\n\n .all-day-label {\n font-size: 9px;\n color: var(--fc-text-light);\n display: flex;\n align-items: center;\n justify-content: center;\n border-right: 1px solid var(--fc-border-color);\n text-transform: uppercase;\n font-weight: 700;\n }\n\n .all-day-cell {\n padding: 6px 12px;\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n\n /* Body */\n .day-body {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n position: relative;\n display: grid;\n grid-template-columns: 60px 1fr;\n background: var(--fc-background);\n }\n\n .time-gutter {\n border-right: 1px solid var(--fc-border-color);\n background: var(--fc-background-alt);\n height: 1440px;\n }\n\n .time-slot-label {\n height: 60px;\n font-size: 11px;\n color: var(--fc-text-light);\n text-align: right;\n padding-right: 12px;\n font-weight: 500;\n }\n\n .day-column {\n position: relative;\n height: 1440px;\n }\n\n .day-column.selected {\n background: var(--fc-background-hover);\n }\n\n /* Grid Lines */\n .grid-lines {\n position: absolute;\n top: 0;\n left: 60px;\n right: 0;\n bottom: 0;\n pointer-events: none;\n }\n\n .grid-line {\n height: 60px;\n border-bottom: 1px solid var(--fc-border-color);\n width: 100%;\n }\n\n /* Event Style */\n .event-container {\n position: absolute;\n left: 12px;\n right: 24px;\n border-radius: 6px;\n padding: 8px 12px;\n font-size: 13px;\n font-weight: 500;\n color: white;\n background: var(--fc-primary-color);\n border: 1px solid rgba(0,0,0,0.1);\n overflow: hidden;\n box-shadow: var(--fc-shadow);\n cursor: pointer;\n transition: all 0.15s ease;\n z-index: 5;\n }\n\n .event-container:hover {\n z-index: 10;\n transform: translateX(4px);\n }\n\n .now-indicator {\n position: absolute;\n left: 0;\n right: 0;\n height: 2px;\n background: var(--fc-danger-color);\n z-index: 15;\n pointer-events: none;\n }\n `;\n }\n\n template() {\n if (!this.viewData || !this.viewData.day) {\n return '<div class=\"day-view\" style=\"padding: 20px; color: var(--fc-text-light);\">No data available.</div>';\n }\n\n const { day } = this.viewData;\n const locale = this.stateManager?.state?.config?.locale || 'en-US';\n const dayName = DateUtils.formatDate(day.date, 'day', locale).split(' ')[0];\n\n return `\n <div class=\"day-view\">\n <div class=\"day-header\">\n <div class=\"time-gutter-header\"></div>\n <div class=\"day-column-header ${day.isToday ? 'is-today' : ''}\">\n <span class=\"day-name\">${dayName}</span>\n <span class=\"day-number\">${day.date.getDate()}</span>\n </div>\n </div>\n\n <div class=\"all-day-row\">\n <div class=\"all-day-label\">All day</div>\n <div class=\"all-day-cell\">\n ${day.allDayEvents.map(e => this.renderAllDayEvent(e)).join('')}\n </div>\n </div>\n\n <div class=\"day-body\" id=\"scroll-container\">\n <div class=\"grid-lines\">\n ${this.hours.map(() => `<div class=\"grid-line\"></div>`).join('')}\n </div>\n\n <div class=\"time-gutter\">\n ${this.hours.map(h => `\n <div class=\"time-slot-label\">\n ${h === 0 ? '' : DateUtils.formatTime(new Date().setHours(h, 0), false)}\n </div>\n `).join('')}\n </div>\n\n <div class=\"day-column\" data-date=\"${day.date.toISOString()}\">\n ${day.isToday ? this.renderNowIndicator() : ''}\n ${day.timedEvents.map(e => this.renderTimedEvent(e)).join('')}\n </div>\n </div>\n </div>\n `;\n }\n\n renderTimedEvent(event) {\n const start = new Date(event.start);\n const end = new Date(event.end);\n\n const startMinutes = start.getHours() * 60 + start.getMinutes();\n const durationMinutes = (end - start) / (1000 * 60);\n\n const top = startMinutes;\n const height = Math.max(durationMinutes, 30);\n\n const color = StyleUtils.sanitizeColor(event.backgroundColor);\n const textColor = StyleUtils.sanitizeColor(StyleUtils.getContrastColor(color), 'white');\n\n return `\n <div class=\"event-container\"\n style=\"top: ${top}px; height: ${height}px; background-color: ${color}; color: ${textColor};\"\n data-event-id=\"${event.id}\">\n <span class=\"event-title\">${DOMUtils.escapeHTML(event.title)}</span>\n <span class=\"event-time\">${DateUtils.formatTime(start)} - ${DateUtils.formatTime(end)}</span>\n </div>\n `;\n }\n\n renderAllDayEvent(event) {\n const color = StyleUtils.sanitizeColor(event.backgroundColor);\n const textColor = StyleUtils.sanitizeColor(StyleUtils.getContrastColor(color), 'white');\n\n return `\n <div class=\"event-item\"\n style=\"background-color: ${color}; color: ${textColor}; font-size: 12px; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-weight: 500; margin-bottom: 2px;\"\n data-event-id=\"${event.id}\">\n ${DOMUtils.escapeHTML(event.title)}\n </div>\n `;\n }\n\n renderNowIndicator() {\n const now = new Date();\n const minutes = now.getHours() * 60 + now.getMinutes();\n return `<div class=\"now-indicator\" style=\"top: ${minutes}px\"></div>`;\n }\n\n afterRender() {\n const container = this.$('#scroll-container');\n if (container && !this._scrolled) {\n container.scrollTop = 8 * 60 - 50;\n this._scrolled = true;\n }\n\n this.$$('[data-event-id]').forEach(el => {\n this.addListener(el, 'click', (e) => {\n e.stopPropagation();\n const eventId = e.currentTarget.dataset.eventId;\n const event = this.stateManager.getEvents().find(ev => ev.id === eventId);\n if (event) this.emit('event-click', { event });\n });\n });\n\n const dayCol = this.$('.day-column');\n if (dayCol) {\n this.addListener(dayCol, 'click', (e) => {\n const col = e.currentTarget;\n const container = this.$('#scroll-container');\n const rect = col.getBoundingClientRect();\n const y = e.clientY - rect.top + (container ? container.scrollTop : 0);\n \n const date = new Date(col.dataset.date);\n date.setHours(Math.floor(y / 60), Math.floor(y % 60), 0, 0);\n \n this.stateManager.selectDate(date);\n this.emit('day-click', { date });\n });\n }\n }\n\n unmount() {\n if (this.unsubscribe) this.unsubscribe();\n }\n}\n\nexport default DayView;\n","import { BaseComponent } from '../core/BaseComponent.js';\nimport { StyleUtils } from '../utils/StyleUtils.js';\nimport { DOMUtils } from '../utils/DOMUtils.js';\n\nexport class EventForm extends BaseComponent {\n constructor() {\n super();\n this._isVisible = false;\n this._cleanupFocusTrap = null;\n this.config = {\n title: 'New Event',\n defaultDuration: 60, // minutes\n colors: [\n { color: '#2563EB', label: 'Blue' },\n { color: '#10B981', label: 'Green' },\n { color: '#F59E0B', label: 'Amber' },\n { color: '#EF4444', label: 'Red' },\n { color: '#8B5CF6', label: 'Purple' },\n { color: '#6B7280', label: 'Gray' }\n ]\n };\n this._formData = {\n title: '',\n start: new Date(),\n end: new Date(),\n allDay: false,\n color: this.config.colors[0].color\n };\n }\n\n static get observedAttributes() {\n return ['open'];\n }\n\n attributeChangedCallback(name, oldValue, newValue) {\n if (name === 'open') {\n if (newValue !== null) {\n this.open();\n } else {\n this.close();\n }\n }\n }\n\n getStyles() {\n return `\n ${StyleUtils.getBaseStyles()}\n ${StyleUtils.getButtonStyles()}\n\n :host {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: var(--fc-z-modal);\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(2px);\n }\n\n :host([open]) {\n display: flex;\n }\n\n .modal-content {\n background: var(--fc-background);\n width: 400px;\n max-width: 90vw;\n border-radius: var(--fc-border-radius-lg);\n box-shadow: var(--fc-shadow-lg);\n border: 1px solid var(--fc-border-color);\n display: flex;\n flex-direction: column;\n animation: fc-scale-in var(--fc-transition);\n }\n\n .modal-header {\n padding: var(--fc-spacing-lg);\n border-bottom: 1px solid var(--fc-border-color);\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .modal-title {\n font-size: var(--fc-font-size-lg);\n font-weight: var(--fc-font-weight-semibold);\n color: var(--fc-text-color);\n }\n\n .close-btn {\n background: transparent;\n border: none;\n color: var(--fc-text-secondary);\n cursor: pointer;\n padding: 4px;\n border-radius: var(--fc-border-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .close-btn:hover {\n background: var(--fc-background-hover);\n color: var(--fc-text-color);\n }\n\n .modal-body {\n padding: var(--fc-spacing-lg);\n display: flex;\n flex-direction: column;\n gap: var(--fc-spacing-md);\n }\n\n .form-group {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n label {\n font-size: var(--fc-font-size-sm);\n font-weight: var(--fc-font-weight-medium);\n color: var(--fc-text-secondary);\n }\n\n input[type=\"text\"],\n input[type=\"datetime-local\"],\n select {\n padding: 8px 12px;\n border: 1px solid var(--fc-border-color);\n border-radius: var(--fc-border-radius);\n font-family: var(--fc-font-family);\n font-size: var(--fc-font-size-base);\n color: var(--fc-text-color);\n background: var(--fc-background);\n transition: border-color var(--fc-transition-fast);\n }\n\n input:focus,\n select:focus {\n outline: none;\n border-color: var(--fc-primary-color);\n box-shadow: 0 0 0 2px var(--fc-primary-light);\n }\n\n .row {\n display: flex;\n gap: var(--fc-spacing-md);\n }\n \n .row .form-group {\n flex: 1;\n }\n\n .modal-footer {\n padding: var(--fc-spacing-lg);\n border-top: 1px solid var(--fc-border-color);\n display: flex;\n justify-content: flex-end;\n gap: var(--fc-spacing-md);\n background: var(--fc-background-alt);\n border-bottom-left-radius: var(--fc-border-radius-lg);\n border-bottom-right-radius: var(--fc-border-radius-lg);\n }\n\n /* Color picker style */\n .color-options {\n display: flex;\n gap: 8px;\n margin-top: 4px;\n }\n\n .color-btn {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n cursor: pointer;\n border: 2px solid transparent;\n transition: transform var(--fc-transition-fast), border-color var(--fc-transition-fast);\n padding: 0;\n position: relative;\n }\n\n .color-btn:hover {\n transform: scale(1.1);\n }\n\n .color-btn.selected {\n border-color: var(--fc-text-color);\n box-shadow: 0 0 0 2px var(--fc-background), 0 0 0 4px var(--fc-primary-color);\n }\n\n .color-btn:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--fc-background), 0 0 0 4px var(--fc-primary-color);\n }\n\n .error-message {\n color: var(--fc-danger-color);\n font-size: 11px;\n margin-top: 2px;\n display: none;\n }\n\n .form-group.has-error .error-message {\n display: block;\n }\n\n .form-group.has-error input {\n border-color: var(--fc-danger-color);\n }\n `;\n }\n\n template() {\n return `\n <div class=\"modal-content\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"modal-title\">\n <header class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"modal-title\">${this.config.title}</h3>\n <button class=\"close-btn\" id=\"close-x\" aria-label=\"Close modal\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\"></path>\n </svg>\n </button>\n </header>\n \n <div class=\"modal-body\">\n <div class=\"form-group\" id=\"title-group\">\n <label for=\"event-title\">Title</label>\n <input type=\"text\" id=\"event-title\" placeholder=\"Event name\" autofocus required>\n <span class=\"error-message\">Title is required</span>\n </div>\n\n <div class=\"row\">\n <div class=\"form-group\" id=\"start-group\">\n <label for=\"event-start\">Start</label>\n <input type=\"datetime-local\" id=\"event-start\" required>\n </div>\n <div class=\"form-group\" id=\"end-group\">\n <label for=\"event-end\">End</label>\n <input type=\"datetime-local\" id=\"event-end\" required>\n <span class=\"error-message\">End time must be after start time</span>\n </div>\n </div>\n\n <div class=\"form-group\">\n <label id=\"color-label\">Color</label>\n <div class=\"color-options\" id=\"color-picker\" role=\"radiogroup\" aria-labelledby=\"color-label\">\n ${this.config.colors.map(c => `\n <button type=\"button\" \n class=\"color-btn ${c.color === this._formData.color ? 'selected' : ''}\" \n style=\"background-color: ${c.color}\" \n data-color=\"${c.color}\"\n title=\"${c.label}\"\n aria-label=\"${c.label}\"\n aria-checked=\"${c.color === this._formData.color ? 'true' : 'false'}\"\n role=\"radio\"></button>\n `).join('')}\n </div>\n </div>\n </div>\n\n <footer class=\"modal-footer\">\n <button class=\"fc-btn fc-btn-secondary\" id=\"cancel-btn\">Cancel</button>\n <button class=\"fc-btn fc-btn-primary\" id=\"save-btn\">Save Event</button>\n </footer>\n </div>\n `;\n }\n\n afterRender() {\n // Bind elements\n this.modalContent = this.$('.modal-content');\n this.titleInput = this.$('#event-title');\n this.startInput = this.$('#event-start');\n this.endInput = this.$('#event-end');\n this.colorContainer = this.$('#color-picker');\n \n this.titleGroup = this.$('#title-group');\n this.endGroup = this.$('#end-group');\n\n // Event Listeners using addListener for automatic cleanup\n this.addListener(this.$('#close-x'), 'click', () => this.close());\n this.addListener(this.$('#cancel-btn'), 'click', () => this.close());\n this.addListener(this.$('#save-btn'), 'click', () => this.save());\n\n this.colorContainer.querySelectorAll('.color-btn').forEach(btn => {\n this.addListener(btn, 'click', (e) => {\n this._formData.color = e.currentTarget.dataset.color;\n this.updateColorSelection();\n });\n });\n\n // Close on backdrop click\n this.addListener(this, 'click', (e) => {\n if (e.target === this) this.close();\n });\n\n // Close on Escape key - remove old listener before adding new one\n if (this._handleKeyDown) {\n window.removeEventListener('keydown', this._handleKeyDown);\n }\n this._handleKeyDown = (e) => {\n if (e.key === 'Escape' && this.hasAttribute('open')) {\n this.close();\n }\n };\n window.addEventListener('keydown', this._handleKeyDown);\n }\n\n updateColorSelection() {\n const buttons = this.colorContainer.querySelectorAll('.color-btn');\n buttons.forEach(btn => {\n const isSelected = btn.dataset.color === this._formData.color;\n btn.classList.toggle('selected', isSelected);\n btn.setAttribute('aria-checked', isSelected ? 'true' : 'false');\n });\n }\n\n open(initialDate = new Date()) {\n if (!this.hasAttribute('open')) {\n this.setAttribute('open', '');\n }\n \n // Reset errors\n this.titleGroup.classList.remove('has-error');\n this.endGroup.classList.remove('has-error');\n\n // Initialize form data\n this._formData.start = initialDate;\n this._formData.end = new Date(initialDate.getTime() + this.config.defaultDuration * 60 * 1000);\n this._formData.title = '';\n this._formData.color = this.config.colors[0].color;\n \n // Update inputs\n if (this.startInput) {\n this.titleInput.value = '';\n this.startInput.value = this.formatDateForInput(this._formData.start);\n this.endInput.value = this.formatDateForInput(this._formData.end);\n this.updateColorSelection();\n \n // Focus trapping\n this._cleanupFocusTrap = DOMUtils.trapFocus(this.modalContent);\n }\n }\n\n close() {\n this.removeAttribute('open');\n if (this._cleanupFocusTrap) {\n this._cleanupFocusTrap();\n this._cleanupFocusTrap = null;\n }\n }\n\n validate() {\n let isValid = true;\n \n // Reset errors\n this.titleGroup.classList.remove('has-error');\n this.endGroup.classList.remove('has-error');\n\n // Check title\n if (!this.titleInput.value.trim()) {\n this.titleGroup.classList.add('has-error');\n isValid = false;\n }\n\n // Check date range\n const start = new Date(this.startInput.value);\n const end = new Date(this.endInput.value);\n if (end <= start) {\n this.endGroup.classList.add('has-error');\n isValid = false;\n }\n\n return isValid;\n }\n\n save() {\n if (!this.validate()) return;\n\n const event = {\n title: this.titleInput.value.trim(),\n start: new Date(this.startInput.value),\n end: new Date(this.endInput.value),\n backgroundColor: this._formData.color\n };\n\n this.emit('save', event);\n this.close();\n }\n\n formatDateForInput(date) {\n // Handle local date string for datetime-local input\n const pad = (num) => String(num).padStart(2, '0');\n const year = date.getFullYear();\n const month = pad(date.getMonth() + 1);\n const day = pad(date.getDate());\n const hours = pad(date.getHours());\n const minutes = pad(date.getMinutes());\n \n return `${year}-${month}-${day}T${hours}:${minutes}`;\n }\n\n unmount() {\n if (this._cleanupFocusTrap) {\n this._cleanupFocusTrap();\n }\n window.removeEventListener('keydown', this._handleKeyDown);\n }\n}\n\nif (!customElements.get('forcecal-event-form')) {\n customElements.define('forcecal-event-form', EventForm);\n}\n","/**\n * ForceCalendar - Main calendar component\n *\n * The primary interface component that integrates all views and features\n */\n\nimport { BaseComponent } from '../core/BaseComponent.js';\nimport StateManager from '../core/StateManager.js';\nimport eventBus from '../core/EventBus.js';\nimport { StyleUtils } from '../utils/StyleUtils.js';\nimport { DateUtils } from '../utils/DateUtils.js';\n\n// Import view components\nimport { MonthView } from './views/MonthView.js';\nimport { WeekView } from './views/WeekView.js';\nimport { DayView } from './views/DayView.js';\nimport { EventForm } from './EventForm.js'; // Import EventForm\n\n// Register view components\nif (!customElements.get('forcecal-month')) {\n customElements.define('forcecal-month', MonthView);\n}\nif (!customElements.get('forcecal-week')) {\n customElements.define('forcecal-week', WeekView);\n}\nif (!customElements.get('forcecal-day')) {\n customElements.define('forcecal-day', DayView);\n}\n// EventForm is self-registering in its file\n\n\nexport class ForceCalendar extends BaseComponent {\n static get observedAttributes() {\n return ['view', 'date', 'locale', 'timezone', 'week-starts-on', 'height'];\n }\n\n constructor() {\n super();\n this.stateManager = null;\n this.currentView = null;\n }\n\n initialize() {\n // Initialize state manager with config from attributes\n const config = {\n view: this.getAttribute('view') || 'month',\n date: this.getAttribute('date') ? new Date(this.getAttribute('date')) : new Date(),\n locale: this.getAttribute('locale') || 'en-US',\n timeZone: this.getAttribute('timezone') || Intl.DateTimeFormat().resolvedOptions().timeZone,\n weekStartsOn: parseInt(this.getAttribute('week-starts-on') || '0')\n };\n\n this.stateManager = new StateManager(config);\n\n // Subscribe to state changes\n this.stateManager.subscribe(this.handleStateChange.bind(this));\n\n // Listen for events\n this.setupEventListeners();\n }\n\n setupEventListeners() {\n // Navigation events\n eventBus.on('navigation:*', (data, event) => {\n this.emit('calendar-navigate', { action: event.split(':')[1], ...data });\n });\n\n // View change events\n eventBus.on('view:changed', (data) => {\n this.emit('calendar-view-change', data);\n });\n\n // Event management events\n eventBus.on('event:*', (data, event) => {\n this.emit(`calendar-event-${event.split(':')[1]}`, data);\n });\n\n // Date selection events\n eventBus.on('date:selected', (data) => {\n this.emit('calendar-date-select', data);\n });\n }\n\n handleStateChange(newState, oldState) {\n // Update local view reference if needed\n if (newState.view !== oldState?.view) {\n this.currentView = newState.view;\n }\n\n // Re-render to update header title, active buttons, and child view\n this.render();\n }\n\n mount() {\n super.mount();\n this.loadView(this.stateManager.getView());\n }\n\n loadView(viewType) {\n // Views are already registered at the top of the file\n this.currentView = viewType;\n this.render();\n }\n\n getStyles() {\n const height = this.getAttribute('height') || '800px';\n\n return `\n ${StyleUtils.getBaseStyles()}\n ${StyleUtils.getButtonStyles()}\n ${StyleUtils.getGridStyles()}\n ${StyleUtils.getAnimations()}\n\n :host {\n --calendar-height: ${height};\n display: block;\n font-family: var(--fc-font-family);\n }\n\n .force-calendar {\n display: flex;\n flex-direction: column;\n height: var(--calendar-height);\n background: var(--fc-background);\n border: 1px solid var(--fc-border-color);\n border-radius: var(--fc-border-radius-lg);\n overflow: hidden;\n box-shadow: var(--fc-shadow);\n }\n\n .fc-header {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n align-items: center;\n padding: var(--fc-spacing-md) var(--fc-spacing-lg);\n background: rgba(255, 255, 255, 0.95);\n -webkit-backdrop-filter: blur(8px); /* Safari support */\n backdrop-filter: blur(8px);\n border-bottom: 1px solid var(--fc-border-color);\n z-index: 10;\n position: sticky;\n top: 0;\n }\n\n .fc-header-left {\n display: flex;\n align-items: center;\n gap: var(--fc-spacing-md);\n justify-self: start;\n flex-basis: 0; /* Force Safari to distribute space */\n }\n\n .fc-header-center {\n display: flex;\n align-items: center;\n gap: var(--fc-spacing-lg);\n justify-self: center;\n }\n\n .fc-header-right {\n display: flex;\n align-items: center;\n gap: var(--fc-spacing-md);\n justify-self: end;\n flex-basis: 0; /* Force Safari to distribute space */\n }\n\n .fc-title {\n font-size: 14px;\n font-weight: var(--fc-font-weight-semibold);\n color: var(--fc-text-color);\n white-space: nowrap;\n letter-spacing: -0.01em;\n min-width: 140px;\n text-align: center;\n }\n\n .fc-btn-today {\n border-radius: var(--fc-border-radius-sm);\n padding: 0 12px;\n font-size: 12px;\n font-weight: var(--fc-font-weight-medium);\n border: 1px solid var(--fc-border-color);\n background: var(--fc-background);\n color: var(--fc-text-color);\n height: 28px;\n transition: all var(--fc-transition-fast);\n cursor: pointer;\n display: flex;\n align-items: center;\n }\n\n .fc-btn-today:hover {\n background: var(--fc-background-hover);\n border-color: var(--fc-border-color-hover);\n }\n\n .fc-nav-arrow {\n border: 1px solid var(--fc-border-color);\n background: var(--fc-background);\n height: 28px;\n width: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--fc-border-radius-sm);\n color: var(--fc-text-secondary);\n cursor: pointer;\n transition: all var(--fc-transition-fast);\n padding: 0;\n }\n\n .fc-nav-arrow:hover {\n background: var(--fc-background-hover);\n color: var(--fc-text-color);\n border-color: var(--fc-border-color-hover);\n }\n\n /* View Switcher - Fused Button Group */\n .fc-view-buttons {\n display: flex;\n border: 1px solid var(--fc-border-color);\n border-radius: var(--fc-border-radius-sm);\n overflow: hidden;\n }\n\n .fc-view-button {\n background: var(--fc-background);\n border: none;\n border-right: 1px solid var(--fc-border-color);\n color: var(--fc-text-secondary);\n padding: 0 12px;\n font-size: var(--fc-font-size-sm);\n font-weight: var(--fc-font-weight-medium);\n transition: background-color var(--fc-transition-fast);\n cursor: pointer;\n height: 28px;\n display: flex;\n align-items: center;\n }\n \n .fc-view-button:last-child {\n border-right: none;\n }\n\n .fc-view-button:hover:not(.active) {\n background: var(--fc-background-hover);\n color: var(--fc-text-color);\n }\n\n .fc-view-button.active {\n background: var(--fc-background-alt);\n color: var(--fc-text-color);\n font-weight: var(--fc-font-weight-semibold);\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.02);\n }\n\n .fc-body {\n flex: 1;\n position: relative;\n background: var(--fc-background);\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n .fc-view-container {\n flex: 1;\n position: relative;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n /* Ensure view container has proper dimensions */\n #calendar-view-container {\n display: block;\n width: 100%;\n height: 100%;\n flex: 1;\n }\n\n #calendar-view-container > * {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n /* Loading state */\n .fc-loading {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--fc-spacing-md);\n color: var(--fc-text-secondary);\n }\n\n .fc-spinner {\n width: 24px;\n height: 24px;\n border: 3px solid var(--fc-border-color);\n border-top-color: var(--fc-primary-color);\n border-radius: 50%;\n animation: fc-spin 1s linear infinite;\n }\n\n /* Error state */\n .fc-error {\n padding: var(--fc-spacing-xl);\n text-align: center;\n color: var(--fc-danger-color);\n background: #FEF2F2;\n border-radius: var(--fc-border-radius);\n margin: var(--fc-spacing-xl);\n }\n\n /* Icons */\n .fc-icon {\n width: 18px;\n height: 18px;\n fill: currentColor;\n }\n\n /* Responsive Adjustments */\n @media (max-width: 850px) {\n .fc-header {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--fc-spacing-md);\n height: auto;\n position: static;\n padding: var(--fc-spacing-md);\n }\n\n .fc-header-center {\n order: -1;\n text-align: center;\n width: 100%;\n padding: var(--fc-spacing-xs) 0;\n }\n\n .fc-header-left,\n .fc-header-right {\n justify-content: space-between;\n width: 100%;\n }\n\n #create-event-btn {\n flex: 1;\n }\n }\n\n /* Month View Styles (inline rendering for Locker Service compatibility) */\n .fc-month-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n }\n\n .fc-month-header {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n border-bottom: 1px solid var(--fc-border-color);\n background: var(--fc-background-alt);\n }\n\n .fc-month-header-cell {\n padding: 12px 8px;\n text-align: center;\n font-size: 11px;\n font-weight: 600;\n color: var(--fc-text-light);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n\n .fc-month-body {\n display: flex;\n flex-direction: column;\n flex: 1;\n }\n\n .fc-month-week {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n flex: 1;\n min-height: 100px;\n }\n\n .fc-month-day {\n background: var(--fc-background);\n border-right: 1px solid var(--fc-border-color);\n border-bottom: 1px solid var(--fc-border-color);\n padding: 4px;\n min-height: 80px;\n cursor: pointer;\n transition: background-color 0.15s ease;\n display: flex;\n flex-direction: column;\n }\n\n .fc-month-day:hover {\n background: var(--fc-background-hover);\n }\n\n .fc-month-day:last-child {\n border-right: none;\n }\n\n .fc-month-day.other-month {\n background: var(--fc-background-alt);\n }\n\n .fc-month-day.other-month .fc-day-number {\n color: var(--fc-text-light);\n }\n\n .fc-month-day.today {\n background: rgba(37, 99, 235, 0.05);\n }\n\n .fc-month-day.today .fc-day-number {\n background: var(--fc-primary-color);\n color: white;\n border-radius: 50%;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .fc-day-number {\n font-size: 13px;\n font-weight: 500;\n color: var(--fc-text-color);\n padding: 2px 4px;\n margin-bottom: 4px;\n }\n\n .fc-day-events {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n overflow: hidden;\n }\n\n .fc-event {\n font-size: 11px;\n padding: 2px 6px;\n border-radius: 3px;\n color: white;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n cursor: pointer;\n transition: transform 0.1s ease;\n }\n\n .fc-event:hover {\n transform: scale(1.02);\n }\n\n .fc-more-events {\n font-size: 10px;\n color: var(--fc-text-light);\n padding: 2px 4px;\n font-weight: 500;\n }\n\n /* Week View Styles (inline rendering for Locker Service compatibility) */\n .fc-week-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n }\n\n /* Day View Styles (inline rendering for Locker Service compatibility) */\n .fc-day-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n }\n `;\n }\n\n template() {\n const state = this.stateManager.getState();\n const { currentDate, view, loading, error } = state;\n\n if (error) {\n return `\n <div class=\"force-calendar\">\n <div class=\"fc-error\">\n <p><strong>Error:</strong> ${error.message || 'An error occurred'}</p>\n </div>\n </div>\n `;\n }\n\n const title = this.getTitle(currentDate, view);\n\n return `\n <div class=\"force-calendar\">\n <header class=\"fc-header\">\n <div class=\"fc-header-left\">\n <button class=\"fc-btn-today\" data-action=\"today\">\n Today\n </button>\n </div>\n\n <div class=\"fc-header-center\">\n <button class=\"fc-nav-arrow\" data-action=\"previous\" title=\"Previous\">\n ${this.getIcon('chevron-left')}\n </button>\n <h2 class=\"fc-title\">${title}</h2>\n <button class=\"fc-nav-arrow\" data-action=\"next\" title=\"Next\">\n ${this.getIcon('chevron-right')}\n </button>\n </div>\n\n <div class=\"fc-header-right\">\n <button class=\"fc-btn fc-btn-primary\" id=\"create-event-btn\" style=\"height: 28px; padding: 0 12px; font-size: 12px;\">\n + New Event\n </button>\n <div class=\"fc-view-buttons\" role=\"group\">\n <button class=\"fc-view-button ${view === 'month' ? 'active' : ''}\"\n data-view=\"month\">Month</button>\n <button class=\"fc-view-button ${view === 'week' ? 'active' : ''}\"\n data-view=\"week\">Week</button>\n <button class=\"fc-view-button ${view === 'day' ? 'active' : ''}\"\n data-view=\"day\">Day</button>\n </div>\n </div>\n </header>\n\n <div class=\"fc-body\">\n ${loading ? `\n <div class=\"fc-loading\">\n <div class=\"fc-spinner\"></div>\n <span>Loading...</span>\n </div>\n ` : `\n <div class=\"fc-view-container\">\n ${this.renderView()}\n </div>\n `}\n </div>\n \n <forcecal-event-form id=\"event-modal\"></forcecal-event-form>\n </div>\n `;\n }\n\n renderView() {\n // Use a plain div container - we'll manually instantiate view classes\n // This bypasses Locker Service's custom element restrictions\n return '<div id=\"calendar-view-container\"></div>';\n }\n\n afterRender() {\n // Manually instantiate and mount view component (bypasses Locker Service)\n const container = this.$('#calendar-view-container');\n console.log('[ForceCalendar] afterRender - container:', !!container, 'stateManager:', !!this.stateManager, 'currentView:', this.currentView);\n\n // Only create view once per view type change\n if (container && this.stateManager && this.currentView) {\n // Check if container actually has content (render() clears shadow DOM)\n if (this._currentViewInstance && this._currentViewInstance._viewType === this.currentView && container.children.length > 0) {\n console.log('[ForceCalendar] View already exists with content, skipping creation');\n return;\n }\n\n // Clean up previous view if exists\n if (this._currentViewInstance) {\n if (this._currentViewInstance.cleanup) {\n this._currentViewInstance.cleanup();\n }\n if (this._viewUnsubscribe) {\n this._viewUnsubscribe();\n this._viewUnsubscribe = null;\n }\n }\n\n console.log('[ForceCalendar] Creating view for:', this.currentView);\n\n // Create a simple view renderer that doesn't use custom elements\n try {\n const viewRenderer = this._createViewRenderer(this.currentView);\n if (viewRenderer) {\n viewRenderer._viewType = this.currentView;\n this._currentViewInstance = viewRenderer;\n viewRenderer.stateManager = this.stateManager;\n viewRenderer.container = container;\n\n console.log('[ForceCalendar] Calling viewRenderer.render()');\n viewRenderer.render();\n console.log('[ForceCalendar] viewRenderer.render() completed');\n\n // Subscribe to state changes (store unsubscribe function)\n this._viewUnsubscribe = this.stateManager.subscribe((newState, oldState) => {\n // Only re-render on data changes, not view changes\n if (newState.events !== oldState?.events ||\n newState.currentDate !== oldState?.currentDate) {\n if (viewRenderer && viewRenderer.render) {\n viewRenderer.render();\n }\n }\n });\n }\n } catch (err) {\n console.error('[ForceCalendar] Error creating/rendering view:', err);\n }\n }\n\n // Add event listeners for buttons using tracked addListener\n this.$$('[data-action]').forEach(button => {\n this.addListener(button, 'click', this.handleNavigation);\n });\n\n this.$$('[data-view]').forEach(button => {\n this.addListener(button, 'click', this.handleViewChange);\n });\n\n // Event Modal Handling\n const modal = this.$('#event-modal');\n const createBtn = this.$('#create-event-btn');\n\n if (createBtn && modal) {\n this.addListener(createBtn, 'click', () => {\n modal.open(new Date());\n });\n }\n\n // Listen for day clicks from the view\n this.addListener(this.shadowRoot, 'day-click', (e) => {\n if (modal) {\n modal.open(e.detail.date);\n }\n });\n\n // Handle event saving\n if (modal) {\n this.addListener(modal, 'save', (e) => {\n const eventData = e.detail;\n // Robust Safari support check for randomUUID\n const id = (window.crypto && typeof window.crypto.randomUUID === 'function')\n ? window.crypto.randomUUID()\n : Math.random().toString(36).substring(2, 15);\n\n this.stateManager.addEvent({\n id,\n ...eventData\n });\n });\n }\n }\n\n _createViewRenderer(viewName) {\n // Create a simple view renderer that bypasses custom elements\n // This is necessary for Salesforce Locker Service compatibility\n const self = this;\n const currentViewName = viewName;\n\n return {\n stateManager: null,\n container: null,\n _listeners: [],\n _scrolled: false,\n\n cleanup() {\n this._listeners.forEach(({ element, event, handler }) => {\n element.removeEventListener(event, handler);\n });\n this._listeners = [];\n },\n\n addListener(element, event, handler) {\n element.addEventListener(event, handler);\n this._listeners.push({ element, event, handler });\n },\n\n render() {\n if (!this.container || !this.stateManager) return;\n\n const viewData = this.stateManager.getViewData();\n if (!viewData) {\n this.container.innerHTML = '<div style=\"padding: 20px; text-align: center; color: #666;\">Loading...</div>';\n return;\n }\n\n this.cleanup();\n const config = this.stateManager.getState().config;\n let html = '';\n\n switch (currentViewName) {\n case 'week':\n html = this._renderWeekView(viewData, config);\n break;\n case 'day':\n html = this._renderDayView(viewData, config);\n break;\n case 'month':\n default:\n if (!viewData.weeks) {\n this.container.innerHTML = '<div style=\"padding: 20px; text-align: center; color: #666;\">No data available for month view.</div>';\n return;\n }\n html = this._renderMonthView(viewData, config);\n break;\n }\n\n this.container.innerHTML = html;\n this._attachEventHandlers(currentViewName);\n },\n\n _renderMonthView(viewData, config) {\n const weekStartsOn = config.weekStartsOn || 0;\n const dayNames = [];\n for (let i = 0; i < 7; i++) {\n const dayIndex = (weekStartsOn + i) % 7;\n dayNames.push(['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][dayIndex]);\n }\n\n let html = `\n <div class=\"fc-month-view\" style=\"display: flex; flex-direction: column; height: 100%; min-height: 400px; background: #fff; border: 1px solid #e5e7eb;\">\n <div class=\"fc-month-header\" style=\"display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb;\">\n ${dayNames.map(d => `<div class=\"fc-month-header-cell\" style=\"padding: 12px 8px; text-align: center; font-size: 11px; font-weight: 600; color: #6b7280; text-transform: uppercase;\">${d}</div>`).join('')}\n </div>\n <div class=\"fc-month-body\" style=\"display: flex; flex-direction: column; flex: 1;\">\n `;\n\n viewData.weeks.forEach(week => {\n html += '<div class=\"fc-month-week\" style=\"display: grid; grid-template-columns: repeat(7, 1fr); flex: 1; min-height: 80px;\">';\n week.days.forEach(day => {\n const isOtherMonth = !day.isCurrentMonth;\n const isToday = day.isToday;\n\n const dayBg = isOtherMonth ? '#f3f4f6' : '#fff';\n const dayNumColor = isOtherMonth ? '#9ca3af' : '#111827';\n const todayStyle = isToday ? 'background: #2563eb; color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;' : '';\n\n const events = day.events || [];\n const visibleEvents = events.slice(0, 3);\n const moreCount = events.length - 3;\n\n html += `\n <div class=\"fc-month-day\" data-date=\"${day.date}\" style=\"background: ${dayBg}; border-right: 1px solid #e5e7eb; border-bottom: 1px solid #e5e7eb; padding: 4px; min-height: 80px; cursor: pointer;\">\n <div class=\"fc-day-number\" style=\"font-size: 13px; font-weight: 500; color: ${dayNumColor}; padding: 2px 4px; margin-bottom: 4px; ${todayStyle}\">${day.dayOfMonth}</div>\n <div class=\"fc-day-events\" style=\"display: flex; flex-direction: column; gap: 2px;\">\n ${visibleEvents.map(evt => `\n <div class=\"fc-event\" data-event-id=\"${evt.id}\" style=\"background-color: ${evt.backgroundColor || '#2563eb'}; font-size: 11px; padding: 2px 6px; border-radius: 3px; color: white; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;\">\n ${evt.title}\n </div>\n `).join('')}\n ${moreCount > 0 ? `<div class=\"fc-more-events\" style=\"font-size: 10px; color: #6b7280; padding: 2px 4px; font-weight: 500;\">+${moreCount} more</div>` : ''}\n </div>\n </div>\n `;\n });\n html += '</div>';\n });\n\n html += '</div></div>';\n return html;\n },\n\n _renderWeekView(viewData, config) {\n const days = viewData.days || [];\n if (days.length === 0) {\n return '<div style=\"padding: 20px; text-align: center; color: #666;\">No data available for week view.</div>';\n }\n\n const weekStartsOn = config.weekStartsOn || 0;\n const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n const hours = Array.from({ length: 24 }, (_, i) => i);\n\n // Process days to add events\n const processedDays = days.map(day => {\n const dayDate = new Date(day.date);\n const events = day.events || [];\n return {\n ...day,\n date: dayDate,\n dayName: dayNames[dayDate.getDay()],\n dayOfMonth: dayDate.getDate(),\n isToday: this._isToday(dayDate),\n timedEvents: events.filter(e => !e.allDay),\n allDayEvents: events.filter(e => e.allDay)\n };\n });\n\n let html = `\n <div class=\"fc-week-view\" style=\"display: flex; flex-direction: column; height: 100%; background: #fff; overflow: hidden;\">\n <!-- Header -->\n <div style=\"display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb; flex-shrink: 0;\">\n <div style=\"border-right: 1px solid #e5e7eb;\"></div>\n ${processedDays.map(day => `\n <div style=\"padding: 12px 8px; text-align: center; border-right: 1px solid #e5e7eb;\">\n <div style=\"font-size: 10px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;\">${day.dayName}</div>\n <div style=\"font-size: 16px; font-weight: 500; margin-top: 4px; ${day.isToday ? 'background: #dc2626; color: white; border-radius: 50%; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;' : 'color: #111827;'}\">${day.dayOfMonth}</div>\n </div>\n `).join('')}\n </div>\n\n <!-- All Day Row -->\n <div style=\"display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #fafafa; min-height: 32px; flex-shrink: 0;\">\n <div style=\"font-size: 9px; color: #6b7280; display: flex; align-items: center; justify-content: center; border-right: 1px solid #e5e7eb; text-transform: uppercase; font-weight: 700;\">All day</div>\n ${processedDays.map(day => `\n <div style=\"border-right: 1px solid #e5e7eb; padding: 4px; display: flex; flex-direction: column; gap: 2px;\">\n ${day.allDayEvents.map(evt => `\n <div class=\"fc-event\" data-event-id=\"${evt.id}\" style=\"background-color: ${evt.backgroundColor || '#2563eb'}; font-size: 10px; padding: 2px 4px; border-radius: 2px; color: white; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">\n ${evt.title}\n </div>\n `).join('')}\n </div>\n `).join('')}\n </div>\n\n <!-- Time Grid Body -->\n <div id=\"week-scroll-container\" style=\"flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;\">\n <div style=\"display: grid; grid-template-columns: 60px repeat(7, 1fr); position: relative; height: 1440px;\">\n <!-- Time Gutter -->\n <div style=\"border-right: 1px solid #e5e7eb; background: #fafafa;\">\n ${hours.map(h => `\n <div style=\"height: 60px; font-size: 10px; color: #6b7280; text-align: right; padding-right: 8px; font-weight: 500;\">\n ${h === 0 ? '' : this._formatHour(h)}\n </div>\n `).join('')}\n </div>\n\n <!-- Day Columns -->\n ${processedDays.map(day => `\n <div class=\"fc-week-day-column\" data-date=\"${day.date.toISOString()}\" style=\"border-right: 1px solid #e5e7eb; position: relative; cursor: pointer;\">\n <!-- Hour grid lines -->\n ${hours.map(() => `<div style=\"height: 60px; border-bottom: 1px solid #f3f4f6;\"></div>`).join('')}\n\n <!-- Now indicator for today -->\n ${day.isToday ? this._renderNowIndicator() : ''}\n\n <!-- Timed events -->\n ${day.timedEvents.map(evt => this._renderTimedEvent(evt)).join('')}\n </div>\n `).join('')}\n </div>\n </div>\n </div>\n `;\n\n return html;\n },\n\n _renderDayView(viewData, config) {\n // Day view from core has: type, date, dayName, isToday, allDayEvents, hours\n // We need to handle both the core structure and enriched structure\n const currentDate = this.stateManager?.getState()?.currentDate || new Date();\n\n let dayDate, dayName, isToday, allDayEvents, timedEvents;\n\n if (viewData.type === 'day' && viewData.date) {\n // Core day view structure\n dayDate = new Date(viewData.date);\n dayName = viewData.dayName || ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dayDate.getDay()];\n isToday = viewData.isToday !== undefined ? viewData.isToday : this._isToday(dayDate);\n allDayEvents = viewData.allDayEvents || [];\n\n // Extract timed events from hours array or get from stateManager\n if (viewData.hours && Array.isArray(viewData.hours)) {\n // Collect unique events from hours (events can span multiple hours)\n const eventMap = new Map();\n viewData.hours.forEach(hour => {\n (hour.events || []).forEach(evt => {\n if (!eventMap.has(evt.id)) {\n eventMap.set(evt.id, evt);\n }\n });\n });\n timedEvents = Array.from(eventMap.values());\n } else {\n timedEvents = [];\n }\n } else if (viewData.days && viewData.days.length > 0) {\n // Enriched structure with days array\n const dayData = viewData.days.find(d => this._isSameDay(new Date(d.date), currentDate)) || viewData.days[0];\n dayDate = new Date(dayData.date);\n dayName = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dayDate.getDay()];\n isToday = this._isToday(dayDate);\n const events = dayData.events || [];\n allDayEvents = events.filter(e => e.allDay);\n timedEvents = events.filter(e => !e.allDay);\n } else {\n return '<div style=\"padding: 20px; text-align: center; color: #666;\">No data available for day view.</div>';\n }\n\n const hours = Array.from({ length: 24 }, (_, i) => i);\n\n let html = `\n <div class=\"fc-day-view\" style=\"display: flex; flex-direction: column; height: 100%; background: #fff; overflow: hidden;\">\n <!-- Header -->\n <div style=\"display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid #e5e7eb; background: #f9fafb; flex-shrink: 0;\">\n <div style=\"border-right: 1px solid #e5e7eb;\"></div>\n <div style=\"padding: 16px 24px;\">\n <div style=\"font-size: 12px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;\">${dayName}</div>\n <div style=\"font-size: 24px; font-weight: 600; margin-top: 4px; ${isToday ? 'color: #dc2626;' : 'color: #111827;'}\">${dayDate.getDate()}</div>\n </div>\n </div>\n\n <!-- All Day Row -->\n <div style=\"display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid #e5e7eb; background: #fafafa; min-height: 36px; flex-shrink: 0;\">\n <div style=\"font-size: 9px; color: #6b7280; display: flex; align-items: center; justify-content: center; border-right: 1px solid #e5e7eb; text-transform: uppercase; font-weight: 700;\">All day</div>\n <div style=\"padding: 6px 12px; display: flex; flex-wrap: wrap; gap: 4px;\">\n ${allDayEvents.map(evt => `\n <div class=\"fc-event\" data-event-id=\"${evt.id}\" style=\"background-color: ${evt.backgroundColor || '#2563eb'}; font-size: 12px; padding: 4px 8px; border-radius: 4px; color: white; cursor: pointer; font-weight: 500;\">\n ${evt.title}\n </div>\n `).join('')}\n </div>\n </div>\n\n <!-- Time Grid Body -->\n <div id=\"day-scroll-container\" style=\"flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;\">\n <div style=\"display: grid; grid-template-columns: 60px 1fr; position: relative; height: 1440px;\">\n <!-- Time Gutter -->\n <div style=\"border-right: 1px solid #e5e7eb; background: #fafafa;\">\n ${hours.map(h => `\n <div style=\"height: 60px; font-size: 11px; color: #6b7280; text-align: right; padding-right: 12px; font-weight: 500;\">\n ${h === 0 ? '' : this._formatHour(h)}\n </div>\n `).join('')}\n </div>\n\n <!-- Day Column -->\n <div class=\"fc-day-column\" data-date=\"${dayDate.toISOString()}\" style=\"position: relative; cursor: pointer;\">\n <!-- Hour grid lines -->\n ${hours.map(() => `<div style=\"height: 60px; border-bottom: 1px solid #f3f4f6;\"></div>`).join('')}\n\n <!-- Now indicator for today -->\n ${isToday ? this._renderNowIndicator() : ''}\n\n <!-- Timed events -->\n ${timedEvents.map(evt => this._renderTimedEventDay(evt)).join('')}\n </div>\n </div>\n </div>\n </div>\n `;\n\n return html;\n },\n\n _renderTimedEvent(event) {\n const start = new Date(event.start);\n const end = new Date(event.end);\n const startMinutes = start.getHours() * 60 + start.getMinutes();\n const durationMinutes = Math.max((end - start) / (1000 * 60), 20);\n const color = event.backgroundColor || '#2563eb';\n\n return `\n <div class=\"fc-event\" data-event-id=\"${event.id}\"\n style=\"position: absolute; top: ${startMinutes}px; height: ${durationMinutes}px; left: 2px; right: 2px;\n background-color: ${color}; border-radius: 4px; padding: 4px 8px; font-size: 11px;\n font-weight: 500; color: white; overflow: hidden; box-shadow: 0 1px 2px rgba(0,0,0,0.1);\n cursor: pointer; z-index: 5;\">\n <div style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">${event.title}</div>\n <div style=\"font-size: 10px; opacity: 0.9;\">${this._formatTime(start)}</div>\n </div>\n `;\n },\n\n _renderTimedEventDay(event) {\n const start = new Date(event.start);\n const end = new Date(event.end);\n const startMinutes = start.getHours() * 60 + start.getMinutes();\n const durationMinutes = Math.max((end - start) / (1000 * 60), 30);\n const color = event.backgroundColor || '#2563eb';\n\n return `\n <div class=\"fc-event\" data-event-id=\"${event.id}\"\n style=\"position: absolute; top: ${startMinutes}px; height: ${durationMinutes}px; left: 12px; right: 24px;\n background-color: ${color}; border-radius: 6px; padding: 8px 12px; font-size: 13px;\n font-weight: 500; color: white; overflow: hidden; box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n cursor: pointer; z-index: 5;\">\n <div style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">${event.title}</div>\n <div style=\"font-size: 11px; opacity: 0.9;\">${this._formatTime(start)} - ${this._formatTime(end)}</div>\n </div>\n `;\n },\n\n _renderNowIndicator() {\n const now = new Date();\n const minutes = now.getHours() * 60 + now.getMinutes();\n return `<div style=\"position: absolute; left: 0; right: 0; top: ${minutes}px; height: 2px; background: #dc2626; z-index: 15; pointer-events: none;\"></div>`;\n },\n\n _formatHour(hour) {\n const period = hour >= 12 ? 'PM' : 'AM';\n const displayHour = hour % 12 || 12;\n return `${displayHour} ${period}`;\n },\n\n _formatTime(date) {\n const hours = date.getHours();\n const minutes = date.getMinutes();\n const period = hours >= 12 ? 'PM' : 'AM';\n const displayHour = hours % 12 || 12;\n return minutes === 0 ? `${displayHour} ${period}` : `${displayHour}:${minutes.toString().padStart(2, '0')} ${period}`;\n },\n\n _isToday(date) {\n const today = new Date();\n return date.getDate() === today.getDate() &&\n date.getMonth() === today.getMonth() &&\n date.getFullYear() === today.getFullYear();\n },\n\n _isSameDay(date1, date2) {\n return date1.getDate() === date2.getDate() &&\n date1.getMonth() === date2.getMonth() &&\n date1.getFullYear() === date2.getFullYear();\n },\n\n _attachEventHandlers(viewType) {\n const stateManager = this.stateManager;\n const self = this;\n\n // Day click handlers (for month view)\n this.container.querySelectorAll('.fc-month-day').forEach(dayEl => {\n this.addListener(dayEl, 'click', (e) => {\n const date = new Date(dayEl.dataset.date);\n stateManager.selectDate(date);\n });\n });\n\n // Week view day column click handlers\n this.container.querySelectorAll('.fc-week-day-column').forEach(dayEl => {\n this.addListener(dayEl, 'click', (e) => {\n if (e.target.closest('.fc-event')) return;\n const date = new Date(dayEl.dataset.date);\n const rect = dayEl.getBoundingClientRect();\n const scrollContainer = this.container.querySelector('#week-scroll-container');\n const y = e.clientY - rect.top + (scrollContainer ? scrollContainer.scrollTop : 0);\n date.setHours(Math.floor(y / 60), Math.floor(y % 60), 0, 0);\n stateManager.selectDate(date);\n });\n });\n\n // Day view column click handlers\n this.container.querySelectorAll('.fc-day-column').forEach(dayEl => {\n this.addListener(dayEl, 'click', (e) => {\n if (e.target.closest('.fc-event')) return;\n const date = new Date(dayEl.dataset.date);\n const rect = dayEl.getBoundingClientRect();\n const scrollContainer = this.container.querySelector('#day-scroll-container');\n const y = e.clientY - rect.top + (scrollContainer ? scrollContainer.scrollTop : 0);\n date.setHours(Math.floor(y / 60), Math.floor(y % 60), 0, 0);\n stateManager.selectDate(date);\n });\n });\n\n // Event click handlers\n this.container.querySelectorAll('.fc-event').forEach(eventEl => {\n this.addListener(eventEl, 'click', (e) => {\n e.stopPropagation();\n const eventId = eventEl.dataset.eventId;\n const event = stateManager.getEvents().find(ev => ev.id === eventId);\n if (event) {\n stateManager.selectEvent(event);\n }\n });\n });\n\n // Scroll to 8 AM for week and day views\n if (viewType === 'week' || viewType === 'day') {\n const scrollContainerId = viewType === 'week' ? '#week-scroll-container' : '#day-scroll-container';\n const scrollContainer = this.container.querySelector(scrollContainerId);\n if (scrollContainer && !this._scrolled) {\n scrollContainer.scrollTop = 8 * 60 - 50;\n this._scrolled = true;\n }\n }\n }\n };\n }\n\n handleNavigation(event) {\n const action = event.currentTarget.dataset.action;\n switch (action) {\n case 'today':\n this.stateManager.today();\n break;\n case 'previous':\n this.stateManager.previous();\n break;\n case 'next':\n this.stateManager.next();\n break;\n }\n }\n\n handleViewChange(event) {\n const view = event.currentTarget.dataset.view;\n this.stateManager.setView(view);\n }\n\n getTitle(date, view) {\n const locale = this.stateManager.state.config.locale;\n\n switch (view) {\n case 'month':\n return DateUtils.formatDate(date, 'month', locale);\n case 'week':\n const weekStart = DateUtils.startOfWeek(date);\n const weekEnd = DateUtils.endOfWeek(date);\n return DateUtils.formatDateRange(weekStart, weekEnd, locale);\n case 'day':\n return DateUtils.formatDate(date, 'long', locale);\n default:\n return DateUtils.formatDate(date, 'month', locale);\n }\n }\n\n getIcon(name) {\n const icons = {\n 'chevron-left': `\n <svg class=\"fc-icon\" viewBox=\"0 0 24 24\">\n <path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/>\n </svg>\n `,\n 'chevron-right': `\n <svg class=\"fc-icon\" viewBox=\"0 0 24 24\">\n <path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/>\n </svg>\n `,\n 'calendar': `\n <svg class=\"fc-icon\" viewBox=\"0 0 24 24\">\n <path d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z\"/>\n </svg>\n `\n };\n\n return icons[name] || '';\n }\n\n // Public API methods\n addEvent(event) {\n return this.stateManager.addEvent(event);\n }\n\n updateEvent(eventId, updates) {\n return this.stateManager.updateEvent(eventId, updates);\n }\n\n deleteEvent(eventId) {\n return this.stateManager.deleteEvent(eventId);\n }\n\n getEvents() {\n return this.stateManager.getEvents();\n }\n\n setView(view) {\n this.stateManager.setView(view);\n }\n\n setDate(date) {\n this.stateManager.setDate(date);\n }\n\n next() {\n this.stateManager.next();\n }\n\n previous() {\n this.stateManager.previous();\n }\n\n today() {\n this.stateManager.today();\n }\n\n destroy() {\n if (this.stateManager) {\n this.stateManager.destroy();\n }\n eventBus.clear();\n super.cleanup();\n }\n}\n\n// Register component\nif (!customElements.get('forcecal-main')) {\n customElements.define('forcecal-main', ForceCalendar);\n}","/**\n * Force Calendar Interface\n * Main entry point for the component library\n *\n * A solid foundation for calendar interfaces built on @forcecalendar/core\n */\n\n// Core modules\nexport { BaseComponent } from './core/BaseComponent.js';\nexport { default as StateManager } from './core/StateManager.js';\nexport { default as eventBus, EventBus } from './core/EventBus.js';\n\n// Utilities\nexport { DateUtils } from './utils/DateUtils.js';\nexport { DOMUtils } from './utils/DOMUtils.js';\nexport { StyleUtils } from './utils/StyleUtils.js';\n\n// Components\nimport './components/ForceCalendar.js';\nexport { ForceCalendar } from './components/ForceCalendar.js';\n\n// Views\nexport { MonthView } from './components/views/MonthView.js';\nexport { WeekView } from './components/views/WeekView.js';\nexport { DayView } from './components/views/DayView.js';\n\n// Auto-register main component if in browser environment\nif (typeof window !== 'undefined' && typeof customElements !== 'undefined') {\n // The ForceCalendar component self-registers\n console.log('Force Calendar Interface loading...');\n}"],"names":["BaseComponent","element","event","handler","newState","oldState","key","value","oldValue","newValue","boundHandler","eventName","detail","styles","template","selector","name","TimezoneDatabase","timezone","offsetMinutes","_","data","id","TimezoneManager","date","fromTimezone","toTimezone","fromOffset","offsetDiff","offset","utcDate","cacheKey","parts","p","tzData","dstRule","year","dstStart","dstEnd","month","week","dayOfWeek","firstDay","dayOffset","lastDay","now","tz","offsetHours","hours","minutes","offsetStr","a","b","options","formatOptions","tzString","upperTz","offsetMatch","sign","totalOffset","timezone1","timezone2","offset1","hitRate","entriesToRemove","keys","i","Event","normalized","attendee","index","reminder","title","start","end","allDay","description","location","color","backgroundColor","borderColor","textColor","recurring","recurrenceRule","timeZone","endTimeZone","status","visibility","organizer","attendees","reminders","category","categories","attachments","conferenceData","metadata","rest","startDay","endDay","dateString","startString","endString","dayStart","dayEnd","otherEvent","datetime","updates","r","obj","other","emailOrId","email","responseStatus","counts","reminderId","triggerTime","normalizedCategory","c","DateUtils$1","DateUtils","result","weekStartsOn","day","diff","days","weeks","months","dayOfMonth","years","today","date1","date2","week1Start","week2Start","yearDiff","monthDiff","firstDayOfYear","pastDaysOfYear","locale","format","use24Hour","timeString","dates","current","endTime","dateObj","part","tzDate","jan","jul","janOffset","julOffset","currentOffset","originalOffset","newOffset","dstAdjustment","hour","minute","second","dateStr","timeStr","localDate","utcTime","RRuleParser","rrule","rule","freq","weekDays","match","nth","weekday","v","validateArray","arr","min","max","dayStr","d","freqMap","weekdayMap","nthMap","dayDescs","monthNames","m","RecurrenceEngine","rangeStart","rangeEnd","maxOccurrences","occurrences","duration","eventTimezone","tzManager","currentDate","count","lastOffset","occurrenceStart","occurrenceEnd","ruleString","next","iterations","currentMonth","byDay","dayMap","weekdayCode","position","targetDay","nextMonth","eventId","dateTime","exDate","exceptionDate","exceptions","interval","dayCode","dayNames","code","LRUCache","capacity","firstKey","AdaptiveMemoryManager","config","cache","memoryUsage","memInfo","memFn","usage","totalItems","maxItems","cacheInfo","pressureLevel","sortedCaches","reduction","newCapacity","increase","oldCapacity","targetSize","itemsToRemove","cacheStats","thresholds","PerformanceOptimizer","operation","fn","error","isError","metric","summary","op","time","markers","startMonth","endMonth","promise","resolve","indexed","cacheType","cacheManagerName","reject","operations","callbacks","results","errors","callback","maxAge","queryKey","queryFn","cached","ConflictDetector","eventStore","opts","conflicts","affectedEventIds","affectedAttendees","searchStart","searchEnd","potentialConflicts","e","conflictingEvent","eventConflicts","event1","event2","attendeeEmails","busyPeriods","freePeriods","currentTime","busy","timeConflict","attendeeConflicts","resourceConflicts","locationConflict","bufferMinutes","buffer","start1","end1","start2","end2","overlapStart","overlapEnd","overlapMinutes","severity","conflictingAttendees","attendee1","attendee2","a1","a2","_a","_b","resources1","resources2","resource1","resource2","loc1","loc2","conflictsByType","conflictsBySeverity","conflict","periods","merged","last","startHour","endHour","businessStart","businessEnd","EventStore","existingEvent","updatedEvent","filters","monthKey","eventIds","candidateIds","checkDate","tempDate","tempDateStr","monthEventIds","allEvents","startOfDay","endOfDay","eventStartLocal","eventEndLocal","aStart","bStart","timeCompare","excludeId","overlapping","startDate","endDate","checkedIds","timedOnly","events","groups","processed","group","currentEvent","positions","startDiff","columns","column","totalColumns","pos","expandRecurring","startUTC","endUTC","baseEvents","expandedEvents","occurrence","oldEvents","eventData","firstWeekEnd","lastWeekStart","change","listener","enableRollback","k","eventUpdates","removed","cutoffDate","stillNeeded","eventId1","eventId2","allConflicts","checkedPairs","j","pairKey","durationMinutes","allowConflicts","eventsWithConflicts","StateManager$1","initialState","view","validViews","newDate","isLoading","message","keyArray","previousState","currentState","nextState","seen","aKeys","bKeys","state","Calendar","StateManager","viewType","oldEvent","parsedTimezone","previousTimezone","fixedWeekCount","maxWeeks","weekIndex","dayIndex","dayDate","isCurrentMonth","isToday","isWeekend","allDayEvents","timedEvents","hourDate","hourEnd","groupedEvents","dateKey","plugin","EventBus","once","priority","subscription","handlers","sub","promises","toRemove","pattern","eventBus","silent","changedKeys","addedEvent","newEvents","viewData","selectedDateString","loading","CoreDateUtils","formats","showMinutes","startFormat","startTime","baseDate","rtf","diffInSeconds","diffInMinutes","diffInHours","diffInDays","diffInWeeks","diffInMonths","diffInYears","monthIndex","period","adjustedHours","DOMUtils","tag","attributes","children","child","delegatedHandler","target","rect","threshold","behavior","block","inline","property","className","eventType","ms","htmlString","str","div","func","wait","timeout","args","later","limit","inThrottle","parents","parent","margin","deep","container","focusableElements","firstFocusable","lastFocusable","handleKeyDown","StyleUtils","variables","percent","num","amt","R","G","B","bgColor","g","fallback","trimmed","hex","alpha","breakpoint","size","__publicField","MonthView","attempts","registryId","manager","oldDate","oldDateEl","newDateEl","selectedDate","isSelected","processedEvents","fullColor","col","dayName","dayData","isOtherMonth","dayNumber","classes","visibleEvents","remainingCount","eventsHtml","moreHtml","style","safeColor","safeTextColor","dayEl","eventEl","moreEl","calendarEvent","WeekView","oldDayEl","newDayEl","h","startMinutes","top","height","el","ev","y","DayView","dayCol","allDays","w","_c","EventForm","btn","initialDate","isValid","pad","ForceCalendar","viewRenderer","err","button","modal","createBtn","viewName","currentViewName","html","dayBg","dayNumColor","todayStyle","moreCount","evt","processedDays","eventMap","displayHour","stateManager","scrollContainer","scrollContainerId","weekStart","weekEnd"],"mappings":"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","x_google_ignoreList":[1,2,3,4,5,6,7,8,9,10,11,12,13]}
1
+ {"version":3,"file":"force-calendar-interface.esm.js","sources":["../src/core/BaseComponent.js","../node_modules/@forcecalendar/core/core/timezone/TimezoneDatabase.js","../node_modules/@forcecalendar/core/core/timezone/TimezoneManager.js","../node_modules/@forcecalendar/core/core/events/Event.js","../node_modules/@forcecalendar/core/core/calendar/DateUtils.js","../node_modules/@forcecalendar/core/core/events/RRuleParser.js","../node_modules/@forcecalendar/core/core/events/RecurrenceEngine.js","../node_modules/@forcecalendar/core/core/performance/LRUCache.js","../node_modules/@forcecalendar/core/core/performance/AdaptiveMemoryManager.js","../node_modules/@forcecalendar/core/core/performance/PerformanceOptimizer.js","../node_modules/@forcecalendar/core/core/conflicts/ConflictDetector.js","../node_modules/@forcecalendar/core/core/events/EventStore.js","../node_modules/@forcecalendar/core/core/state/StateManager.js","../node_modules/@forcecalendar/core/core/calendar/Calendar.js","../src/core/EventBus.js","../src/core/StateManager.js","../src/utils/DateUtils.js","../src/utils/DOMUtils.js","../src/utils/StyleUtils.js","../src/components/views/MonthView.js","../src/components/views/WeekView.js","../src/components/views/DayView.js","../src/components/EventForm.js","../src/components/ForceCalendar.js","../src/index.js"],"sourcesContent":["/**\n * BaseComponent - Foundation for all Force Calendar Web Components\n *\n * Provides common functionality:\n * - Shadow DOM setup\n * - Event handling\n * - State management integration\n * - Lifecycle management\n * - Style management\n */\n\nexport class BaseComponent extends HTMLElement {\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n this._listeners = [];\n this._state = null;\n this._props = new Map();\n this._initialized = false;\n }\n\n // Lifecycle methods\n connectedCallback() {\n if (!this._initialized) {\n this.initialize();\n this._initialized = true;\n }\n this.mount();\n }\n\n disconnectedCallback() {\n this.unmount();\n this.cleanup();\n }\n\n // To be overridden by child classes\n initialize() {\n // Setup component-specific initialization\n }\n\n mount() {\n // Component mounted to DOM\n this.render();\n }\n\n unmount() {\n // Component removed from DOM\n }\n\n cleanup() {\n // Clean up event listeners\n this._listeners.forEach(({ element, event, handler }) => {\n element.removeEventListener(event, handler);\n });\n this._listeners = [];\n }\n\n // State management\n setState(newState) {\n const oldState = this._state;\n this._state = { ...this._state, ...newState };\n this.stateChanged(oldState, this._state);\n this.render();\n }\n\n getState() {\n return this._state;\n }\n\n stateChanged(oldState, newState) {\n // Override in child classes to handle state changes\n }\n\n // Props management\n setProp(key, value) {\n const oldValue = this._props.get(key);\n this._props.set(key, value);\n this.propChanged(key, oldValue, value);\n }\n\n getProp(key) {\n return this._props.get(key);\n }\n\n propChanged(key, oldValue, newValue) {\n // Override in child classes to handle prop changes\n }\n\n // Event handling\n addListener(element, event, handler) {\n if (!element || !event || !handler) {\n console.warn('addListener called with invalid parameters', { element, event, handler });\n return;\n }\n const boundHandler = handler.bind(this);\n element.addEventListener(event, boundHandler);\n this._listeners.push({ element, event, handler: boundHandler });\n }\n\n emit(eventName, detail = {}) {\n this.dispatchEvent(new CustomEvent(eventName, {\n detail,\n bubbles: true,\n composed: true\n }));\n }\n\n // Style management\n getStyles() {\n // Override in child classes to provide component styles\n return '';\n }\n\n getBaseStyles() {\n return `\n :host {\n display: block;\n box-sizing: border-box;\n }\n\n *, *::before, *::after {\n box-sizing: inherit;\n }\n `;\n }\n\n // Template rendering\n render() {\n // Clean up existing listeners before replacing DOM\n this.cleanup();\n\n const styles = `\n <style>\n ${this.getBaseStyles()}\n ${this.getStyles()}\n </style>\n `;\n\n const template = this.template();\n this.shadowRoot.innerHTML = styles + template;\n this.afterRender();\n }\n\n template() {\n // Override in child classes to provide component template\n return '';\n }\n\n afterRender() {\n // Override in child classes for post-render operations\n }\n\n // Utility methods\n $(selector) {\n return this.shadowRoot.querySelector(selector);\n }\n\n $$(selector) {\n return this.shadowRoot.querySelectorAll(selector);\n }\n\n // Attribute observation\n static get observedAttributes() {\n return [];\n }\n\n attributeChangedCallback(name, oldValue, newValue) {\n this.setProp(name, newValue);\n if (this._initialized) {\n this.render();\n }\n }\n}","/**\n * TimezoneDatabase - Comprehensive IANA timezone database\n * Contains timezone rules for all major zones worldwide\n */\n\nexport class TimezoneDatabase {\n constructor() {\n // Comprehensive IANA timezone offset data (Standard Time)\n // Offsets in minutes from UTC\n this.timezones = {\n // UTC\n UTC: { offset: 0, dst: null },\n GMT: { offset: 0, dst: null },\n\n // Africa\n 'Africa/Abidjan': { offset: 0, dst: null },\n 'Africa/Accra': { offset: 0, dst: null },\n 'Africa/Addis_Ababa': { offset: 180, dst: null },\n 'Africa/Algiers': { offset: 60, dst: null },\n 'Africa/Cairo': { offset: 120, dst: null },\n 'Africa/Casablanca': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Africa/Johannesburg': { offset: 120, dst: null },\n 'Africa/Lagos': { offset: 60, dst: null },\n 'Africa/Nairobi': { offset: 180, dst: null },\n\n // Americas\n 'America/Anchorage': {\n offset: -540,\n dst: {\n start: { month: 3, week: 2, day: 0 },\n end: { month: 11, week: 1, day: 0 },\n offset: 60\n }\n },\n 'America/Argentina/Buenos_Aires': { offset: -180, dst: null },\n 'America/Bogota': { offset: -300, dst: null },\n 'America/Caracas': { offset: -240, dst: null },\n 'America/Chicago': {\n offset: -360,\n dst: {\n start: { month: 3, week: 2, day: 0 },\n end: { month: 11, week: 1, day: 0 },\n offset: 60\n }\n },\n 'America/Denver': {\n offset: -420,\n dst: {\n start: { month: 3, week: 2, day: 0 },\n end: { month: 11, week: 1, day: 0 },\n offset: 60\n }\n },\n 'America/Detroit': {\n offset: -300,\n dst: {\n start: { month: 3, week: 2, day: 0 },\n end: { month: 11, week: 1, day: 0 },\n offset: 60\n }\n },\n 'America/Halifax': {\n offset: -240,\n dst: {\n start: { month: 3, week: 2, day: 0 },\n end: { month: 11, week: 1, day: 0 },\n offset: 60\n }\n },\n 'America/Los_Angeles': {\n offset: -480,\n dst: {\n start: { month: 3, week: 2, day: 0 },\n end: { month: 11, week: 1, day: 0 },\n offset: 60\n }\n },\n 'America/Mexico_City': {\n offset: -360,\n dst: {\n start: { month: 4, week: 1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'America/New_York': {\n offset: -300,\n dst: {\n start: { month: 3, week: 2, day: 0 },\n end: { month: 11, week: 1, day: 0 },\n offset: 60\n }\n },\n 'America/Phoenix': { offset: -420, dst: null },\n 'America/Regina': { offset: -360, dst: null },\n 'America/Santiago': {\n offset: -180,\n dst: {\n start: { month: 9, week: 1, day: 0 },\n end: { month: 4, week: 1, day: 0 },\n offset: 60\n }\n },\n 'America/Sao_Paulo': {\n offset: -180,\n dst: {\n start: { month: 10, week: 3, day: 0 },\n end: { month: 2, week: 3, day: 0 },\n offset: 60\n }\n },\n 'America/St_Johns': {\n offset: -210,\n dst: {\n start: { month: 3, week: 2, day: 0 },\n end: { month: 11, week: 1, day: 0 },\n offset: 60\n }\n },\n 'America/Toronto': {\n offset: -300,\n dst: {\n start: { month: 3, week: 2, day: 0 },\n end: { month: 11, week: 1, day: 0 },\n offset: 60\n }\n },\n 'America/Vancouver': {\n offset: -480,\n dst: {\n start: { month: 3, week: 2, day: 0 },\n end: { month: 11, week: 1, day: 0 },\n offset: 60\n }\n },\n\n // Asia\n 'Asia/Baghdad': { offset: 180, dst: null },\n 'Asia/Bangkok': { offset: 420, dst: null },\n 'Asia/Dubai': { offset: 240, dst: null },\n 'Asia/Hong_Kong': { offset: 480, dst: null },\n 'Asia/Jakarta': { offset: 420, dst: null },\n 'Asia/Jerusalem': {\n offset: 120,\n dst: {\n start: { month: 3, week: -1, day: 5 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Asia/Karachi': { offset: 300, dst: null },\n 'Asia/Kolkata': { offset: 330, dst: null },\n 'Asia/Kuala_Lumpur': { offset: 480, dst: null },\n 'Asia/Manila': { offset: 480, dst: null },\n 'Asia/Seoul': { offset: 540, dst: null },\n 'Asia/Shanghai': { offset: 480, dst: null },\n 'Asia/Singapore': { offset: 480, dst: null },\n 'Asia/Taipei': { offset: 480, dst: null },\n 'Asia/Tehran': {\n offset: 210,\n dst: {\n start: { month: 3, week: 4, day: 0 },\n end: { month: 9, week: 4, day: 0 },\n offset: 60\n }\n },\n 'Asia/Tokyo': { offset: 540, dst: null },\n\n // Atlantic\n 'Atlantic/Azores': {\n offset: -60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Atlantic/Bermuda': {\n offset: -240,\n dst: {\n start: { month: 3, week: 2, day: 0 },\n end: { month: 11, week: 1, day: 0 },\n offset: 60\n }\n },\n 'Atlantic/Reykjavik': { offset: 0, dst: null },\n\n // Australia & Pacific\n 'Australia/Adelaide': {\n offset: 570,\n dst: {\n start: { month: 10, week: 1, day: 0 },\n end: { month: 4, week: 1, day: 0 },\n offset: 60\n }\n },\n 'Australia/Brisbane': { offset: 600, dst: null },\n 'Australia/Darwin': { offset: 570, dst: null },\n 'Australia/Hobart': {\n offset: 600,\n dst: {\n start: { month: 10, week: 1, day: 0 },\n end: { month: 4, week: 1, day: 0 },\n offset: 60\n }\n },\n 'Australia/Melbourne': {\n offset: 600,\n dst: {\n start: { month: 10, week: 1, day: 0 },\n end: { month: 4, week: 1, day: 0 },\n offset: 60\n }\n },\n 'Australia/Perth': { offset: 480, dst: null },\n 'Australia/Sydney': {\n offset: 600,\n dst: {\n start: { month: 10, week: 1, day: 0 },\n end: { month: 4, week: 1, day: 0 },\n offset: 60\n }\n },\n\n // Europe\n 'Europe/Amsterdam': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Athens': {\n offset: 120,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Berlin': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Brussels': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Budapest': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Copenhagen': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Dublin': {\n offset: 0,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Helsinki': {\n offset: 120,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Istanbul': { offset: 180, dst: null },\n 'Europe/Kiev': {\n offset: 120,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Lisbon': {\n offset: 0,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/London': {\n offset: 0,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Madrid': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Moscow': { offset: 180, dst: null },\n 'Europe/Oslo': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Paris': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Prague': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Rome': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Stockholm': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Vienna': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Warsaw': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n 'Europe/Zurich': {\n offset: 60,\n dst: {\n start: { month: 3, week: -1, day: 0 },\n end: { month: 10, week: -1, day: 0 },\n offset: 60\n }\n },\n\n // Indian\n 'Indian/Maldives': { offset: 300, dst: null },\n 'Indian/Mauritius': { offset: 240, dst: null },\n\n // Pacific\n 'Pacific/Auckland': {\n offset: 720,\n dst: {\n start: { month: 9, week: -1, day: 0 },\n end: { month: 4, week: 1, day: 0 },\n offset: 60\n }\n },\n 'Pacific/Fiji': {\n offset: 720,\n dst: {\n start: { month: 11, week: 1, day: 0 },\n end: { month: 1, week: 3, day: 0 },\n offset: 60\n }\n },\n 'Pacific/Guam': { offset: 600, dst: null },\n 'Pacific/Honolulu': { offset: -600, dst: null },\n 'Pacific/Midway': { offset: -660, dst: null },\n 'Pacific/Noumea': { offset: 660, dst: null },\n 'Pacific/Pago_Pago': { offset: -660, dst: null },\n 'Pacific/Port_Moresby': { offset: 600, dst: null },\n 'Pacific/Tahiti': { offset: -600, dst: null }\n };\n\n // Timezone aliases and abbreviations\n this.aliases = {\n // Common abbreviations to IANA\n EST: 'America/New_York',\n EDT: 'America/New_York',\n CST: 'America/Chicago',\n CDT: 'America/Chicago',\n MST: 'America/Denver',\n MDT: 'America/Denver',\n PST: 'America/Los_Angeles',\n PDT: 'America/Los_Angeles',\n AKST: 'America/Anchorage',\n AKDT: 'America/Anchorage',\n HST: 'Pacific/Honolulu',\n AST: 'America/Halifax',\n ADT: 'America/Halifax',\n NST: 'America/St_Johns',\n NDT: 'America/St_Johns',\n BST: 'Europe/London',\n IST: 'Asia/Kolkata',\n WET: 'Europe/Lisbon',\n WEST: 'Europe/Lisbon',\n CET: 'Europe/Paris',\n CEST: 'Europe/Paris',\n EET: 'Europe/Athens',\n EEST: 'Europe/Athens',\n MSK: 'Europe/Moscow',\n JST: 'Asia/Tokyo',\n KST: 'Asia/Seoul',\n CST_CN: 'Asia/Shanghai',\n HKT: 'Asia/Hong_Kong',\n SGT: 'Asia/Singapore',\n AEST: 'Australia/Sydney',\n AEDT: 'Australia/Sydney',\n ACST: 'Australia/Adelaide',\n ACDT: 'Australia/Adelaide',\n AWST: 'Australia/Perth',\n NZST: 'Pacific/Auckland',\n NZDT: 'Pacific/Auckland',\n\n // City/Country aliases\n 'US/Eastern': 'America/New_York',\n 'US/Central': 'America/Chicago',\n 'US/Mountain': 'America/Denver',\n 'US/Pacific': 'America/Los_Angeles',\n 'US/Alaska': 'America/Anchorage',\n 'US/Hawaii': 'Pacific/Honolulu',\n 'Canada/Eastern': 'America/Toronto',\n 'Canada/Central': 'America/Regina',\n 'Canada/Mountain': 'America/Denver',\n 'Canada/Pacific': 'America/Vancouver',\n 'Canada/Atlantic': 'America/Halifax',\n 'Canada/Newfoundland': 'America/St_Johns',\n 'Mexico/General': 'America/Mexico_City',\n 'Brazil/East': 'America/Sao_Paulo',\n 'Chile/Continental': 'America/Santiago',\n GB: 'Europe/London',\n 'GB-Eire': 'Europe/London',\n Eire: 'Europe/Dublin',\n Israel: 'Asia/Jerusalem',\n Japan: 'Asia/Tokyo',\n Singapore: 'Asia/Singapore',\n Hongkong: 'Asia/Hong_Kong',\n ROK: 'Asia/Seoul',\n PRC: 'Asia/Shanghai',\n 'Australia/NSW': 'Australia/Sydney',\n 'Australia/Victoria': 'Australia/Melbourne',\n 'Australia/Queensland': 'Australia/Brisbane',\n 'Australia/South': 'Australia/Adelaide',\n 'Australia/Tasmania': 'Australia/Hobart',\n 'Australia/West': 'Australia/Perth',\n 'Australia/North': 'Australia/Darwin',\n NZ: 'Pacific/Auckland'\n };\n }\n\n /**\n * Get timezone data by identifier\n * @param {string} timezone - Timezone identifier or alias\n * @returns {Object|null} Timezone data or null if not found\n */\n getTimezone(timezone) {\n // Check for alias first\n if (this.aliases[timezone]) {\n timezone = this.aliases[timezone];\n }\n\n return this.timezones[timezone] || null;\n }\n\n /**\n * Get all available timezone identifiers\n * @returns {string[]} Array of timezone identifiers\n */\n getAllTimezones() {\n return Object.keys(this.timezones);\n }\n\n /**\n * Check if a timezone identifier is valid\n * @param {string} timezone - Timezone identifier\n * @returns {boolean} True if valid\n */\n isValidTimezone(timezone) {\n return this.aliases[timezone] !== undefined || this.timezones[timezone] !== undefined;\n }\n\n /**\n * Resolve timezone alias to canonical identifier\n * @param {string} timezone - Timezone identifier or alias\n * @returns {string} Canonical timezone identifier\n */\n resolveAlias(timezone) {\n return this.aliases[timezone] || timezone;\n }\n\n /**\n * Get timezones by offset\n * @param {number} offsetMinutes - Offset in minutes from UTC\n * @returns {string[]} Array of timezone identifiers\n */\n getTimezonesByOffset(offsetMinutes) {\n return Object.entries(this.timezones)\n .filter(([_, data]) => data.offset === offsetMinutes)\n .map(([id, _]) => id);\n }\n\n /**\n * Get common timezones for quick selection\n * @returns {Object} Grouped timezones by region\n */\n getCommonTimezones() {\n return {\n Americas: [\n 'America/New_York',\n 'America/Chicago',\n 'America/Denver',\n 'America/Los_Angeles',\n 'America/Toronto',\n 'America/Mexico_City',\n 'America/Sao_Paulo'\n ],\n Europe: [\n 'Europe/London',\n 'Europe/Paris',\n 'Europe/Berlin',\n 'Europe/Moscow',\n 'Europe/Rome',\n 'Europe/Madrid',\n 'Europe/Amsterdam'\n ],\n Asia: [\n 'Asia/Tokyo',\n 'Asia/Shanghai',\n 'Asia/Hong_Kong',\n 'Asia/Singapore',\n 'Asia/Kolkata',\n 'Asia/Dubai',\n 'Asia/Seoul'\n ],\n 'Australia/Pacific': [\n 'Australia/Sydney',\n 'Australia/Melbourne',\n 'Australia/Brisbane',\n 'Australia/Perth',\n 'Pacific/Auckland',\n 'Pacific/Honolulu'\n ],\n Africa: ['Africa/Cairo', 'Africa/Lagos', 'Africa/Johannesburg', 'Africa/Nairobi']\n };\n }\n}\n","/**\n * TimezoneManager - Comprehensive timezone handling for global calendar operations\n * Handles timezone conversions, DST transitions, and IANA timezone database\n *\n * Critical for Salesforce orgs spanning multiple timezones\n */\n\nimport { TimezoneDatabase } from './TimezoneDatabase.js';\n\n// Singleton instance for shared use across the application\nlet sharedInstance = null;\n\nexport class TimezoneManager {\n /**\n * Get the shared singleton instance of TimezoneManager\n * This should be used instead of creating new instances to avoid memory bloat\n * @returns {TimezoneManager} The shared instance\n */\n static getInstance() {\n if (!sharedInstance) {\n sharedInstance = new TimezoneManager();\n }\n return sharedInstance;\n }\n\n /**\n * Reset the singleton instance (useful for testing)\n * @private\n */\n static _resetInstance() {\n if (sharedInstance) {\n sharedInstance.clearCache();\n }\n sharedInstance = null;\n }\n\n constructor() {\n // Initialize comprehensive timezone database\n this.database = new TimezoneDatabase();\n\n // Cache timezone offsets for performance\n this.offsetCache = new Map();\n this.dstCache = new Map();\n\n // Cache size management\n this.maxCacheSize = 1000;\n this.cacheHits = 0;\n this.cacheMisses = 0;\n }\n\n /**\n * Convert date from one timezone to another\n * @param {Date} date - Date to convert\n * @param {string} fromTimezone - Source timezone (IANA identifier)\n * @param {string} toTimezone - Target timezone (IANA identifier)\n * @returns {Date} Converted date\n */\n convertTimezone(date, fromTimezone, toTimezone) {\n if (!date) return null;\n if (fromTimezone === toTimezone) return new Date(date);\n\n // Get offset difference\n const fromOffset = this.getTimezoneOffset(date, fromTimezone);\n const toOffset = this.getTimezoneOffset(date, toTimezone);\n const offsetDiff = (toOffset - fromOffset) * 60 * 1000; // Convert to milliseconds\n\n return new Date(date.getTime() + offsetDiff);\n }\n\n /**\n * Convert date to UTC\n * @param {Date} date - Date in local timezone\n * @param {string} timezone - Source timezone\n * @returns {Date} Date in UTC\n */\n toUTC(date, timezone) {\n if (!date) return null;\n if (timezone === 'UTC') return new Date(date);\n\n // offset is positive for timezones behind UTC (e.g., NYC = +300)\n // To convert local to UTC, we ADD the offset\n const offset = this.getTimezoneOffset(date, timezone);\n return new Date(date.getTime() + offset * 60 * 1000);\n }\n\n /**\n * Convert UTC date to timezone\n * @param {Date} utcDate - Date in UTC\n * @param {string} timezone - Target timezone\n * @returns {Date} Date in specified timezone\n */\n fromUTC(utcDate, timezone) {\n if (!utcDate) return null;\n if (timezone === 'UTC') return new Date(utcDate);\n\n // offset is positive for timezones behind UTC (e.g., NYC = +300)\n // To convert UTC to local, we SUBTRACT the offset\n const offset = this.getTimezoneOffset(utcDate, timezone);\n return new Date(utcDate.getTime() - offset * 60 * 1000);\n }\n\n /**\n * Get timezone offset in minutes\n * @param {Date} date - Date to check (for DST calculation)\n * @param {string} timezone - Timezone identifier\n * @returns {number} Offset in minutes from UTC\n */\n getTimezoneOffset(date, timezone) {\n // Resolve any aliases\n timezone = this.database.resolveAlias(timezone);\n\n // Check cache first\n const cacheKey = `${timezone}_${date.getFullYear()}_${date.getMonth()}_${date.getDate()}`;\n if (this.offsetCache.has(cacheKey)) {\n this.cacheHits++;\n this._manageCacheSize();\n return this.offsetCache.get(cacheKey);\n }\n\n this.cacheMisses++;\n\n // Try using Intl API if available (best option for browser/Node.js environments)\n if (typeof Intl !== 'undefined' && Intl.DateTimeFormat) {\n try {\n const formatter = new Intl.DateTimeFormat('en-US', {\n timeZone: timezone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false\n });\n\n // Create same date in target timezone\n const parts = formatter.formatToParts(date);\n const tzDate = new Date(\n parts.find(p => p.type === 'year').value,\n parts.find(p => p.type === 'month').value - 1,\n parts.find(p => p.type === 'day').value,\n parts.find(p => p.type === 'hour').value,\n parts.find(p => p.type === 'minute').value,\n parts.find(p => p.type === 'second').value\n );\n\n const offset = (tzDate.getTime() - date.getTime()) / (1000 * 60);\n this.offsetCache.set(cacheKey, -offset);\n this._manageCacheSize();\n return -offset;\n } catch (e) {\n // Fallback to database calculation\n }\n }\n\n // Fallback: Use timezone database\n const tzData = this.database.getTimezone(timezone);\n if (!tzData) {\n throw new Error(`Unknown timezone: ${timezone}`);\n }\n\n let offset = tzData.offset;\n\n // Apply DST if applicable\n if (tzData.dst && this.isDST(date, timezone, tzData.dst)) {\n offset += tzData.dst.offset;\n }\n\n this.offsetCache.set(cacheKey, offset);\n this._manageCacheSize();\n return offset;\n }\n\n /**\n * Check if date is in DST for given timezone\n * @param {Date} date - Date to check\n * @param {string} timezone - Timezone identifier\n * @param {Object} [dstRule] - DST rule object (optional, will fetch if not provided)\n * @returns {boolean} True if in DST\n */\n isDST(date, timezone, dstRule = null) {\n // Get DST rule if not provided\n if (!dstRule) {\n const tzData = this.database.getTimezone(timezone);\n if (!tzData || !tzData.dst) return false;\n dstRule = tzData.dst;\n }\n\n const year = date.getFullYear();\n const dstStart = this.getNthWeekdayOfMonth(\n year,\n dstRule.start.month,\n dstRule.start.week,\n dstRule.start.day\n );\n const dstEnd = this.getNthWeekdayOfMonth(\n year,\n dstRule.end.month,\n dstRule.end.week,\n dstRule.end.day\n );\n\n // Handle Southern Hemisphere (DST crosses year boundary)\n if (dstStart > dstEnd) {\n return date >= dstStart || date < dstEnd;\n }\n\n return date >= dstStart && date < dstEnd;\n }\n\n /**\n * Get nth weekday of month\n * @private\n */\n getNthWeekdayOfMonth(year, month, week, dayOfWeek) {\n const date = new Date(year, month, 1);\n const firstDay = date.getDay();\n\n let dayOffset = dayOfWeek - firstDay;\n if (dayOffset < 0) dayOffset += 7;\n\n if (week > 0) {\n // Nth occurrence from start\n date.setDate(1 + dayOffset + (week - 1) * 7);\n } else {\n // Nth occurrence from end\n const lastDay = new Date(year, month + 1, 0).getDate();\n date.setDate(lastDay);\n const lastDayOfWeek = date.getDay();\n let offset = lastDayOfWeek - dayOfWeek;\n if (offset < 0) offset += 7;\n date.setDate(lastDay - offset + (week + 1) * 7);\n }\n\n return date;\n }\n\n /**\n * Get list of common timezones\n * @returns {Array<{value: string, label: string, offset: string}>}\n */\n getCommonTimezones() {\n const now = new Date();\n const timezones = [\n { value: 'America/New_York', label: 'Eastern Time (New York)', region: 'Americas' },\n { value: 'America/Chicago', label: 'Central Time (Chicago)', region: 'Americas' },\n { value: 'America/Denver', label: 'Mountain Time (Denver)', region: 'Americas' },\n { value: 'America/Phoenix', label: 'Mountain Time - Arizona (Phoenix)', region: 'Americas' },\n { value: 'America/Los_Angeles', label: 'Pacific Time (Los Angeles)', region: 'Americas' },\n { value: 'America/Anchorage', label: 'Alaska Time (Anchorage)', region: 'Americas' },\n { value: 'Pacific/Honolulu', label: 'Hawaii Time (Honolulu)', region: 'Pacific' },\n { value: 'America/Toronto', label: 'Eastern Time (Toronto)', region: 'Americas' },\n { value: 'America/Vancouver', label: 'Pacific Time (Vancouver)', region: 'Americas' },\n { value: 'America/Mexico_City', label: 'Central Time (Mexico City)', region: 'Americas' },\n { value: 'America/Sao_Paulo', label: 'Brasilia Time (São Paulo)', region: 'Americas' },\n { value: 'Europe/London', label: 'GMT/BST (London)', region: 'Europe' },\n { value: 'Europe/Paris', label: 'Central European Time (Paris)', region: 'Europe' },\n { value: 'Europe/Berlin', label: 'Central European Time (Berlin)', region: 'Europe' },\n { value: 'Europe/Moscow', label: 'Moscow Time', region: 'Europe' },\n { value: 'Asia/Dubai', label: 'Gulf Time (Dubai)', region: 'Asia' },\n { value: 'Asia/Kolkata', label: 'India Time (Mumbai)', region: 'Asia' },\n { value: 'Asia/Shanghai', label: 'China Time (Shanghai)', region: 'Asia' },\n { value: 'Asia/Tokyo', label: 'Japan Time (Tokyo)', region: 'Asia' },\n { value: 'Asia/Seoul', label: 'Korea Time (Seoul)', region: 'Asia' },\n { value: 'Asia/Singapore', label: 'Singapore Time', region: 'Asia' },\n { value: 'Australia/Sydney', label: 'Australian Eastern Time (Sydney)', region: 'Oceania' },\n {\n value: 'Australia/Melbourne',\n label: 'Australian Eastern Time (Melbourne)',\n region: 'Oceania'\n },\n { value: 'Pacific/Auckland', label: 'New Zealand Time (Auckland)', region: 'Oceania' },\n { value: 'UTC', label: 'UTC', region: 'UTC' }\n ];\n\n // Add current offset to each timezone\n return timezones\n .map(tz => {\n const offset = this.getTimezoneOffset(now, tz.value);\n const offsetHours = -offset / 60; // Convert to hours from UTC\n const hours = Math.floor(Math.abs(offsetHours));\n const minutes = Math.round(Math.abs(offsetHours % 1) * 60);\n const sign = offsetHours >= 0 ? '+' : '-';\n const offsetStr = `UTC${sign}${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;\n\n return {\n ...tz,\n offset: offsetStr,\n offsetMinutes: -offset // Store in minutes for sorting\n };\n })\n .sort((a, b) => a.offsetMinutes - b.offsetMinutes);\n }\n\n /**\n * Format date in specific timezone\n * @param {Date} date - Date to format\n * @param {string} timezone - Timezone for formatting\n * @param {Object} options - Formatting options\n * @returns {string} Formatted date string\n */\n formatInTimezone(date, timezone, options = {}) {\n if (!date) return '';\n\n const defaultOptions = {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n hour12: true,\n timeZone: timezone\n };\n\n const formatOptions = { ...defaultOptions, ...options };\n\n try {\n return new Intl.DateTimeFormat('en-US', formatOptions).format(date);\n } catch (e) {\n // Fallback to basic formatting\n const tzDate = this.fromUTC(this.toUTC(date, 'UTC'), timezone);\n return tzDate.toLocaleString('en-US', options);\n }\n }\n\n /**\n * Get timezone from browser/system\n * @returns {string} IANA timezone identifier\n */\n getSystemTimezone() {\n if (typeof Intl !== 'undefined' && Intl.DateTimeFormat) {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n } catch (e) {\n // Fallback\n }\n }\n\n // Fallback based on offset\n const offset = new Date().getTimezoneOffset();\n const offsetHours = -offset / 60;\n\n // Try to match offset to known timezone\n for (const [tz, tzData] of Object.entries(this.database.timezones)) {\n if (tzData.offset / 60 === offsetHours) {\n return tz;\n }\n }\n\n return 'UTC';\n }\n\n /**\n * Parse timezone from string (handles abbreviations)\n * @param {string} tzString - Timezone string\n * @returns {string} IANA timezone identifier\n */\n parseTimezone(tzString) {\n if (!tzString) return 'UTC';\n\n // Check if it's already an IANA identifier\n if (Object.prototype.hasOwnProperty.call(this.database.timezones, tzString)) {\n return tzString;\n }\n\n // Check abbreviations\n const upperTz = tzString.toUpperCase();\n if (\n this.database.abbreviations &&\n Object.prototype.hasOwnProperty.call(this.database.abbreviations, upperTz)\n ) {\n return this.database.abbreviations[upperTz];\n }\n\n // Try to parse offset format (e.g., \"+05:30\", \"-08:00\")\n const offsetMatch = tzString.match(/^([+-])(\\d{2}):?(\\d{2})$/);\n if (offsetMatch) {\n const sign = offsetMatch[1] === '+' ? 1 : -1;\n const hours = parseInt(offsetMatch[2], 10);\n const minutes = parseInt(offsetMatch[3], 10);\n const totalOffset = sign * (hours + minutes / 60);\n\n // Find matching timezone\n for (const [tz, tzData] of Object.entries(this.database.timezones)) {\n if (tzData.offset / 60 === totalOffset) {\n return tz;\n }\n }\n }\n\n return 'UTC';\n }\n\n /**\n * Calculate timezone difference in hours\n * @param {string} timezone1 - First timezone\n * @param {string} timezone2 - Second timezone\n * @param {Date} [date] - Date for DST calculation\n * @returns {number} Hour difference\n */\n getTimezoneDifference(timezone1, timezone2, date = new Date()) {\n const offset1 = this.getTimezoneOffset(date, timezone1);\n const offset2 = this.getTimezoneOffset(date, timezone2);\n return (offset2 - offset1) / 60;\n }\n\n /**\n * Clear caches (useful when date changes significantly)\n */\n clearCache() {\n this.offsetCache.clear();\n this.dstCache.clear();\n this.cacheHits = 0;\n this.cacheMisses = 0;\n }\n\n /**\n * Validate timezone identifier\n * @param {string} timezone - Timezone to validate\n * @returns {boolean} True if valid\n */\n isValidTimezone(timezone) {\n return this.database.isValidTimezone(timezone);\n }\n\n /**\n * Get cache statistics\n * @returns {Object} Cache stats\n */\n getCacheStats() {\n const hitRate =\n this.cacheHits + this.cacheMisses > 0\n ? ((this.cacheHits / (this.cacheHits + this.cacheMisses)) * 100).toFixed(2)\n : 0;\n\n return {\n offsetCacheSize: this.offsetCache.size,\n dstCacheSize: this.dstCache.size,\n maxCacheSize: this.maxCacheSize,\n cacheHits: this.cacheHits,\n cacheMisses: this.cacheMisses,\n hitRate: `${hitRate}%`\n };\n }\n\n /**\n * Manage cache size - evict old entries if needed\n * @private\n */\n _manageCacheSize() {\n // Clear caches if they get too large\n if (this.offsetCache.size > this.maxCacheSize) {\n // Remove first half of entries (oldest)\n const entriesToRemove = Math.floor(this.offsetCache.size / 2);\n const keys = Array.from(this.offsetCache.keys());\n for (let i = 0; i < entriesToRemove; i++) {\n this.offsetCache.delete(keys[i]);\n }\n }\n\n if (this.dstCache.size > this.maxCacheSize / 2) {\n const entriesToRemove = Math.floor(this.dstCache.size / 2);\n const keys = Array.from(this.dstCache.keys());\n for (let i = 0; i < entriesToRemove; i++) {\n this.dstCache.delete(keys[i]);\n }\n }\n }\n}\n","/**\n * Event class - represents a calendar event with timezone support\n * Pure JavaScript, no DOM dependencies\n * Locker Service compatible\n */\n\nimport { TimezoneManager } from '../timezone/TimezoneManager.js';\n\nexport class Event {\n /**\n * Normalize event data\n * @param {import('../../types.js').EventData} data - Raw event data\n * @returns {import('../../types.js').EventData} Normalized event data\n */\n static normalize(data) {\n const normalized = { ...data };\n\n // Always clone Date objects to avoid mutating caller's data\n if (normalized.start) {\n normalized.start = new Date(normalized.start);\n }\n if (normalized.end) {\n normalized.end = new Date(normalized.end);\n }\n\n // If no end date, set it to start date\n if (!normalized.end) {\n normalized.end = normalized.start ? new Date(normalized.start) : null;\n }\n\n // For all-day events, normalize times to midnight\n // (safe to mutate now since we cloned above)\n if (normalized.allDay && normalized.start) {\n normalized.start.setHours(0, 0, 0, 0);\n if (normalized.end) {\n normalized.end.setHours(23, 59, 59, 999);\n }\n }\n\n // Normalize string fields\n normalized.id = String(normalized.id || '').trim();\n normalized.title = String(normalized.title || '').trim();\n normalized.description = String(normalized.description || '').trim();\n normalized.location = String(normalized.location || '').trim();\n\n // Normalize arrays\n normalized.attendees = Array.isArray(normalized.attendees) ? normalized.attendees : [];\n normalized.reminders = Array.isArray(normalized.reminders) ? normalized.reminders : [];\n\n // Handle both 'category' (singular) and 'categories' (plural)\n if (data.category && !data.categories) {\n // If single category is provided, convert to array\n normalized.categories = [data.category];\n } else if (normalized.categories) {\n normalized.categories = Array.isArray(normalized.categories) ? normalized.categories : [];\n } else {\n normalized.categories = [];\n }\n\n normalized.attachments = Array.isArray(normalized.attachments) ? normalized.attachments : [];\n\n // Normalize status and visibility\n const validStatuses = ['confirmed', 'tentative', 'cancelled'];\n if (!validStatuses.includes(normalized.status)) {\n normalized.status = 'confirmed';\n }\n\n const validVisibilities = ['public', 'private', 'confidential'];\n if (!validVisibilities.includes(normalized.visibility)) {\n normalized.visibility = 'public';\n }\n\n // Normalize colors\n if (normalized.color && !normalized.backgroundColor) {\n normalized.backgroundColor = normalized.color;\n }\n if (normalized.color && !normalized.borderColor) {\n normalized.borderColor = normalized.color;\n }\n\n return normalized;\n }\n\n /**\n * Validate event data\n * @param {import('../../types.js').EventData} data - Normalized event data\n * @throws {Error} If validation fails\n */\n static validate(data) {\n // Required fields\n if (!data.id) {\n throw new Error('Event must have an id');\n }\n if (!data.title) {\n throw new Error('Event must have a title');\n }\n if (!data.start) {\n throw new Error('Event must have a start date');\n }\n\n // Validate dates\n if (!(data.start instanceof Date) || isNaN(data.start.getTime())) {\n throw new Error('Invalid start date');\n }\n if (data.end && (!(data.end instanceof Date) || isNaN(data.end.getTime()))) {\n throw new Error('Invalid end date');\n }\n\n // Validate date order\n if (data.end && data.start && data.end < data.start) {\n throw new Error('Event end time cannot be before start time');\n }\n\n // Validate recurrence\n if (data.recurring && !data.recurrenceRule) {\n throw new Error('Recurring events must have a recurrence rule');\n }\n\n // Validate attendees\n if (data.attendees && data.attendees.length > 0) {\n data.attendees.forEach((attendee, index) => {\n if (!attendee.email || !attendee.name) {\n throw new Error(`Attendee at index ${index} must have email and name`);\n }\n // Validate email format\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(attendee.email)) {\n throw new Error(`Invalid email for attendee: ${attendee.email}`);\n }\n });\n }\n\n // Validate reminders\n if (data.reminders && data.reminders.length > 0) {\n data.reminders.forEach((reminder, index) => {\n if (!reminder.method || reminder.minutesBefore == null) {\n throw new Error(`Reminder at index ${index} must have method and minutesBefore`);\n }\n if (reminder.minutesBefore < 0) {\n throw new Error('Reminder minutesBefore must be non-negative');\n }\n });\n }\n\n // Validate timezone if provided\n if (data.timeZone) {\n try {\n // Test if timezone is valid by trying to use it\n new Intl.DateTimeFormat('en-US', { timeZone: data.timeZone });\n } catch (e) {\n throw new Error(`Invalid timezone: ${data.timeZone}`);\n }\n }\n }\n\n /**\n * Create a new Event instance\n * @param {import('../../types.js').EventData} eventData - Event data object\n * @throws {Error} If required fields are missing or invalid\n */\n constructor({\n id,\n title,\n start,\n end,\n allDay = false,\n description = '',\n location = '',\n color = null,\n backgroundColor = null,\n borderColor = null,\n textColor = null,\n recurring = false,\n recurrenceRule = null,\n timeZone = null,\n endTimeZone = null,\n status = 'confirmed',\n visibility = 'public',\n organizer = null,\n attendees = [],\n reminders = [],\n category, // Support singular category (no default)\n categories, // Support plural categories (no default)\n attachments = [],\n conferenceData = null,\n metadata = {},\n ...rest // Capture any extra properties\n }) {\n // Normalize and validate input\n const normalized = Event.normalize({\n id,\n title,\n start,\n end,\n allDay,\n description,\n location,\n color,\n backgroundColor,\n borderColor,\n textColor,\n recurring,\n recurrenceRule,\n timeZone,\n endTimeZone,\n status,\n visibility,\n organizer,\n attendees,\n reminders,\n category, // Pass category to normalize\n categories, // Pass categories to normalize\n attachments,\n conferenceData,\n metadata,\n ...rest // Pass any extra properties\n });\n\n // Validate normalized data\n Event.validate(normalized);\n\n this.id = normalized.id;\n this.title = normalized.title;\n\n // Use shared timezone manager singleton to avoid memory bloat\n // (previously each Event created its own TimezoneManager instance)\n this._timezoneManager = TimezoneManager.getInstance();\n\n // Timezone handling\n // Store the timezone the event was created in (wall-clock time)\n this.timeZone = normalized.timeZone || this._timezoneManager.getSystemTimezone();\n this.endTimeZone = normalized.endTimeZone || this.timeZone; // Different end timezone for flights etc.\n\n // Store dates as provided (wall-clock time in event timezone)\n this.start = normalized.start;\n this.end = normalized.end;\n\n // Store UTC versions for efficient querying and comparison\n this.startUTC = this._timezoneManager.toUTC(this.start, this.timeZone);\n this.endUTC = this._timezoneManager.toUTC(this.end, this.endTimeZone);\n\n this.allDay = normalized.allDay;\n this.description = normalized.description;\n this.location = normalized.location;\n\n // Styling\n this.color = normalized.color;\n this.backgroundColor = normalized.backgroundColor;\n this.borderColor = normalized.borderColor;\n this.textColor = normalized.textColor;\n\n // Recurrence\n this.recurring = normalized.recurring;\n this.recurrenceRule = normalized.recurrenceRule;\n\n // Store original timezone from system if not provided\n this._originalTimeZone = normalized.timeZone || null;\n\n // Event status and visibility\n this.status = normalized.status;\n this.visibility = normalized.visibility;\n\n // People\n this.organizer = normalized.organizer;\n this.attendees = [...normalized.attendees];\n\n // Reminders\n this.reminders = [...normalized.reminders];\n\n // Categories/Tags\n this.categories = normalized.categories ? [...normalized.categories] : [];\n\n // Attachments\n this.attachments = [...normalized.attachments];\n\n // Conference/Virtual meeting\n this.conferenceData = normalized.conferenceData;\n\n // Custom metadata for extensibility\n this.metadata = { ...normalized.metadata };\n\n // Computed properties cache\n this._cache = {};\n\n // Validate complex properties\n this._validateAttendees();\n this._validateReminders();\n }\n\n /**\n * Get event duration in milliseconds\n * @returns {number} Duration in milliseconds\n */\n get duration() {\n if (!this._cache.duration) {\n // Use UTC times for accurate duration calculation\n this._cache.duration = this.endUTC.getTime() - this.startUTC.getTime();\n }\n return this._cache.duration;\n }\n\n /**\n * Get start date in a specific timezone\n * @param {string} timezone - Target timezone\n * @returns {Date} Start date in specified timezone\n */\n getStartInTimezone(timezone) {\n if (timezone === this.timeZone) {\n return new Date(this.start);\n }\n return this._timezoneManager.fromUTC(this.startUTC, timezone);\n }\n\n /**\n * Get end date in a specific timezone\n * @param {string} timezone - Target timezone\n * @returns {Date} End date in specified timezone\n */\n getEndInTimezone(timezone) {\n if (timezone === this.endTimeZone) {\n return new Date(this.end);\n }\n return this._timezoneManager.fromUTC(this.endUTC, timezone);\n }\n\n /**\n * Update event times preserving the timezone\n * @param {Date} start - New start date\n * @param {Date} end - New end date\n * @param {string} [timezone] - Timezone for the new dates\n */\n updateTimes(start, end, timezone) {\n const tz = timezone || this.timeZone;\n\n this.start = start instanceof Date ? start : new Date(start);\n this.end = end instanceof Date ? end : new Date(end);\n\n if (timezone) {\n this.timeZone = timezone;\n this.endTimeZone = timezone;\n }\n\n // Update UTC versions\n this.startUTC = this._timezoneManager.toUTC(this.start, this.timeZone);\n this.endUTC = this._timezoneManager.toUTC(this.end, this.endTimeZone);\n\n // Clear cache\n this._cache = {};\n\n // Validate\n if (this.endUTC < this.startUTC) {\n throw new Error('Event end time cannot be before start time');\n }\n }\n\n /**\n * Get event duration in minutes\n * @returns {number} Duration in minutes\n */\n get durationMinutes() {\n return Math.floor(this.duration / (1000 * 60));\n }\n\n /**\n * Get event duration in hours\n * @returns {number} Duration in hours\n */\n get durationHours() {\n return this.duration / (1000 * 60 * 60);\n }\n\n /**\n * Check if this is a multi-day event\n * @returns {boolean} True if event spans multiple days\n */\n get isMultiDay() {\n if (!Object.prototype.hasOwnProperty.call(this._cache, 'isMultiDay')) {\n const startDay = this.start.toDateString();\n const endDay = this.end.toDateString();\n this._cache.isMultiDay = startDay !== endDay;\n }\n return this._cache.isMultiDay;\n }\n\n /**\n * Check if event is recurring\n * @returns {boolean} True if event is recurring\n */\n isRecurring() {\n return this.recurring && this.recurrenceRule !== null;\n }\n\n /**\n * Check if event occurs on a specific date\n * @param {Date|string} date - The date to check\n * @returns {boolean} True if event occurs on the given date\n */\n occursOn(date) {\n if (!(date instanceof Date)) {\n date = new Date(date);\n }\n\n const dateString = date.toDateString();\n const startString = this.start.toDateString();\n const endString = this.end.toDateString();\n\n // For all-day events, check if date falls within range\n if (this.allDay) {\n return date >= new Date(startString) && date <= new Date(endString);\n }\n\n // For timed events, check if any part of the event occurs on this date\n if (this.isMultiDay) {\n // Multi-day event: check if date is within range\n const dayStart = new Date(dateString);\n const dayEnd = new Date(dateString);\n dayEnd.setHours(23, 59, 59, 999);\n\n return this.start <= dayEnd && this.end >= dayStart;\n }\n // Single day event: check if it's on the same day\n return startString === dateString;\n }\n\n /**\n * Check if this event overlaps with another event\n * @param {Event|{start: Date, end: Date}} otherEvent - The other event or time range to check\n * @returns {boolean} True if events overlap\n * @throws {Error} If otherEvent is not an Event instance or doesn't have start/end\n */\n overlaps(otherEvent) {\n if (otherEvent instanceof Event) {\n // Events don't overlap if one ends before the other starts\n return !(this.end <= otherEvent.start || this.start >= otherEvent.end);\n } else if (otherEvent && otherEvent.start && otherEvent.end) {\n // Allow checking against time ranges\n return !(this.end <= otherEvent.start || this.start >= otherEvent.end);\n }\n throw new Error('Parameter must be an Event instance or have start/end properties');\n }\n\n /**\n * Check if event contains a specific datetime\n * @param {Date|string} datetime - The datetime to check\n * @returns {boolean} True if the datetime falls within the event\n */\n contains(datetime) {\n if (!(datetime instanceof Date)) {\n datetime = new Date(datetime);\n }\n return datetime >= this.start && datetime <= this.end;\n }\n\n /**\n * Clone the event with optional updates\n * @param {Partial<import('../../types.js').EventData>} [updates={}] - Properties to update in the clone\n * @returns {Event} New Event instance with updated properties\n */\n clone(updates = {}) {\n return new Event({\n id: this.id,\n title: this.title,\n start: new Date(this.start),\n end: new Date(this.end),\n allDay: this.allDay,\n description: this.description,\n location: this.location,\n color: this.color,\n backgroundColor: this.backgroundColor,\n borderColor: this.borderColor,\n textColor: this.textColor,\n recurring: this.recurring,\n recurrenceRule: this.recurrenceRule,\n timeZone: this.timeZone,\n status: this.status,\n visibility: this.visibility,\n organizer: this.organizer ? { ...this.organizer } : null,\n attendees: this.attendees.map(a => ({ ...a })),\n reminders: this.reminders.map(r => ({ ...r })),\n categories: [...this.categories],\n attachments: this.attachments.map(a => ({ ...a })),\n conferenceData: this.conferenceData ? { ...this.conferenceData } : null,\n metadata: { ...this.metadata },\n ...updates\n });\n }\n\n /**\n * Convert event to plain object\n * @returns {import('../../types.js').EventData} Plain object representation of the event\n */\n toObject() {\n return {\n id: this.id,\n title: this.title,\n start: this.start.toISOString(),\n end: this.end.toISOString(),\n allDay: this.allDay,\n description: this.description,\n location: this.location,\n color: this.color,\n backgroundColor: this.backgroundColor,\n borderColor: this.borderColor,\n textColor: this.textColor,\n recurring: this.recurring,\n recurrenceRule: this.recurrenceRule,\n timeZone: this.timeZone,\n status: this.status,\n visibility: this.visibility,\n organizer: this.organizer,\n attendees: this.attendees,\n reminders: this.reminders,\n categories: this.categories,\n attachments: this.attachments,\n conferenceData: this.conferenceData,\n metadata: { ...this.metadata }\n };\n }\n\n /**\n * Create Event from plain object\n * @param {import('../../types.js').EventData} obj - Plain object with event properties\n * @returns {Event} New Event instance\n */\n static fromObject(obj) {\n return new Event(obj);\n }\n\n /**\n * Compare events for equality\n * @param {Event} other - The other event\n * @returns {boolean} True if events are equal\n */\n equals(other) {\n if (!(other instanceof Event)) return false;\n\n return (\n this.id === other.id &&\n this.title === other.title &&\n this.start.getTime() === other.start.getTime() &&\n this.end.getTime() === other.end.getTime() &&\n this.allDay === other.allDay &&\n this.description === other.description &&\n this.location === other.location &&\n this.recurring === other.recurring &&\n this.recurrenceRule === other.recurrenceRule &&\n this.status === other.status\n );\n }\n\n // ============ Attendee Management Methods ============\n\n /**\n * Add an attendee to the event\n * @param {import('../../types.js').Attendee} attendee - Attendee to add\n * @returns {boolean} True if attendee was added, false if already exists\n */\n addAttendee(attendee) {\n if (!attendee || !attendee.email) {\n throw new Error('Attendee must have an email');\n }\n\n // Check if attendee already exists\n if (this.hasAttendee(attendee.email)) {\n return false;\n }\n\n // Generate ID if not provided\n if (!attendee.id) {\n attendee.id = `attendee_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n // Set defaults\n attendee.responseStatus = attendee.responseStatus || 'needs-action';\n attendee.role = attendee.role || 'required';\n\n this.attendees.push(attendee);\n return true;\n }\n\n /**\n * Remove an attendee from the event\n * @param {string} emailOrId - Email or ID of the attendee to remove\n * @returns {boolean} True if attendee was removed\n */\n removeAttendee(emailOrId) {\n const index = this.attendees.findIndex(a => a.email === emailOrId || a.id === emailOrId);\n\n if (index !== -1) {\n this.attendees.splice(index, 1);\n return true;\n }\n return false;\n }\n\n /**\n * Update an attendee's response status\n * @param {string} email - Attendee's email\n * @param {import('../../types.js').AttendeeResponseStatus} responseStatus - New response status\n * @returns {boolean} True if attendee was updated\n */\n updateAttendeeResponse(email, responseStatus) {\n const attendee = this.getAttendee(email);\n if (attendee) {\n attendee.responseStatus = responseStatus;\n attendee.responseTime = new Date();\n return true;\n }\n return false;\n }\n\n /**\n * Get an attendee by email\n * @param {string} email - Attendee's email\n * @returns {import('../../types.js').Attendee|null} The attendee or null\n */\n getAttendee(email) {\n return this.attendees.find(a => a.email === email) || null;\n }\n\n /**\n * Check if an attendee exists\n * @param {string} email - Attendee's email\n * @returns {boolean} True if attendee exists\n */\n hasAttendee(email) {\n return this.attendees.some(a => a.email === email);\n }\n\n /**\n * Get attendees by response status\n * @param {import('../../types.js').AttendeeResponseStatus} status - Response status to filter by\n * @returns {import('../../types.js').Attendee[]} Filtered attendees\n */\n getAttendeesByStatus(status) {\n return this.attendees.filter(a => a.responseStatus === status);\n }\n\n /**\n * Get count of attendees by response status\n * @returns {Object.<string, number>} Count by status\n */\n getAttendeeCounts() {\n return this.attendees.reduce((counts, attendee) => {\n const status = attendee.responseStatus || 'needs-action';\n counts[status] = (counts[status] || 0) + 1;\n return counts;\n }, {});\n }\n\n // ============ Reminder Management Methods ============\n\n /**\n * Add a reminder to the event\n * @param {import('../../types.js').Reminder} reminder - Reminder to add\n * @returns {boolean} True if reminder was added\n */\n addReminder(reminder) {\n if (!reminder || typeof reminder.minutesBefore !== 'number') {\n throw new Error('Reminder must have minutesBefore property');\n }\n\n // Generate ID if not provided\n if (!reminder.id) {\n reminder.id = `reminder_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n // Set defaults\n reminder.method = reminder.method || 'popup';\n reminder.enabled = reminder.enabled !== false;\n\n // Check for duplicate\n const duplicate = this.reminders.some(\n r => r.method === reminder.method && r.minutesBefore === reminder.minutesBefore\n );\n\n if (duplicate) {\n return false;\n }\n\n this.reminders.push(reminder);\n return true;\n }\n\n /**\n * Remove a reminder from the event\n * @param {string} reminderId - ID of the reminder to remove\n * @returns {boolean} True if reminder was removed\n */\n removeReminder(reminderId) {\n const index = this.reminders.findIndex(r => r.id === reminderId);\n if (index !== -1) {\n this.reminders.splice(index, 1);\n return true;\n }\n return false;\n }\n\n /**\n * Get active reminders\n * @returns {import('../../types.js').Reminder[]} Active reminders\n */\n getActiveReminders() {\n return this.reminders.filter(r => r.enabled !== false);\n }\n\n /**\n * Get reminder trigger times\n * @returns {Date[]} Array of dates when reminders should trigger\n */\n getReminderTriggerTimes() {\n return this.getActiveReminders().map(reminder => {\n const triggerTime = new Date(this.start);\n triggerTime.setMinutes(triggerTime.getMinutes() - reminder.minutesBefore);\n return triggerTime;\n });\n }\n\n // ============ Category Management Methods ============\n\n /**\n * Add a category to the event\n * @param {string} category - Category to add\n * @returns {boolean} True if category was added\n */\n addCategory(category) {\n if (!category || typeof category !== 'string') {\n throw new Error('Category must be a non-empty string');\n }\n\n const normalizedCategory = category.trim().toLowerCase();\n if (!this.hasCategory(normalizedCategory)) {\n this.categories.push(normalizedCategory);\n return true;\n }\n return false;\n }\n\n /**\n * Remove a category from the event\n * @param {string} category - Category to remove\n * @returns {boolean} True if category was removed\n */\n removeCategory(category) {\n const normalizedCategory = category.trim().toLowerCase();\n const index = this.categories.findIndex(c => c.toLowerCase() === normalizedCategory);\n\n if (index !== -1) {\n this.categories.splice(index, 1);\n return true;\n }\n return false;\n }\n\n /**\n * Get primary category (first in array) for backward compatibility\n * @returns {string|null} Primary category or null\n */\n get category() {\n return this.categories && this.categories.length > 0 ? this.categories[0] : null;\n }\n\n /**\n * Check if event has a specific category\n * @param {string} category - Category to check\n * @returns {boolean} True if event has the category\n */\n hasCategory(category) {\n const normalizedCategory = category.trim().toLowerCase();\n return this.categories.some(c => c.toLowerCase() === normalizedCategory);\n }\n\n /**\n * Check if event has any of the specified categories\n * @param {string[]} categories - Categories to check\n * @returns {boolean} True if event has any of the categories\n */\n hasAnyCategory(categories) {\n return categories.some(category => this.hasCategory(category));\n }\n\n /**\n * Check if event has all of the specified categories\n * @param {string[]} categories - Categories to check\n * @returns {boolean} True if event has all of the categories\n */\n hasAllCategories(categories) {\n return categories.every(category => this.hasCategory(category));\n }\n\n // ============ Validation Methods ============\n\n /**\n * Validate attendees\n * @private\n * @throws {Error} If attendees are invalid\n */\n _validateAttendees() {\n for (const attendee of this.attendees) {\n if (!attendee.email) {\n throw new Error('All attendees must have an email address');\n }\n if (!attendee.name) {\n attendee.name = attendee.email; // Use email as fallback name\n }\n if (!this._isValidEmail(attendee.email)) {\n throw new Error(`Invalid attendee email: ${attendee.email}`);\n }\n }\n }\n\n /**\n * Validate reminders\n * @private\n * @throws {Error} If reminders are invalid\n */\n _validateReminders() {\n for (const reminder of this.reminders) {\n if (typeof reminder.minutesBefore !== 'number' || reminder.minutesBefore < 0) {\n throw new Error('Reminder minutesBefore must be a positive number');\n }\n\n const validMethods = ['email', 'popup', 'sms'];\n if (!validMethods.includes(reminder.method)) {\n throw new Error(`Invalid reminder method: ${reminder.method}`);\n }\n }\n }\n\n /**\n * Validate email address\n * @private\n * @param {string} email - Email to validate\n * @returns {boolean} True if email is valid\n */\n _isValidEmail(email) {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n }\n\n // ============ Enhanced Getters ============\n\n /**\n * Check if the event is cancelled\n * @returns {boolean} True if event is cancelled\n */\n get isCancelled() {\n return this.status === 'cancelled';\n }\n\n /**\n * Check if the event is tentative\n * @returns {boolean} True if event is tentative\n */\n get isTentative() {\n return this.status === 'tentative';\n }\n\n /**\n * Check if the event is confirmed\n * @returns {boolean} True if event is confirmed\n */\n get isConfirmed() {\n return this.status === 'confirmed';\n }\n\n /**\n * Check if the event is private\n * @returns {boolean} True if event is private\n */\n get isPrivate() {\n return this.visibility === 'private';\n }\n\n /**\n * Check if the event is public\n * @returns {boolean} True if event is public\n */\n get isPublic() {\n return this.visibility === 'public';\n }\n\n /**\n * Check if the event has attendees\n * @returns {boolean} True if event has attendees\n */\n get hasAttendees() {\n return this.attendees.length > 0;\n }\n\n /**\n * Check if the event has reminders\n * @returns {boolean} True if event has reminders\n */\n get hasReminders() {\n return this.reminders.length > 0;\n }\n\n /**\n * Check if the event is a meeting (has attendees or conference data)\n * @returns {boolean} True if event is a meeting\n */\n get isMeeting() {\n return this.hasAttendees || this.conferenceData !== null;\n }\n\n /**\n * Check if the event is virtual (has conference data)\n * @returns {boolean} True if event is virtual\n */\n get isVirtual() {\n return this.conferenceData !== null;\n }\n}\n","/**\n * DateUtils - Date manipulation utilities\n * Pure functions, no external dependencies\n * Locker Service compatible\n */\nexport class DateUtils {\n /**\n * Get the start of a day\n * @param {Date} date - The date\n * @returns {Date}\n */\n static startOfDay(date) {\n const result = new Date(date);\n result.setHours(0, 0, 0, 0);\n return result;\n }\n\n /**\n * Get the end of a day\n * @param {Date} date - The date\n * @returns {Date}\n */\n static endOfDay(date) {\n const result = new Date(date);\n result.setHours(23, 59, 59, 999);\n return result;\n }\n\n /**\n * Get the start of a week\n * @param {Date} date - The date\n * @param {number} [weekStartsOn=0] - 0 = Sunday, 1 = Monday, etc.\n * @returns {Date} Start of the week\n */\n static startOfWeek(date, weekStartsOn = 0) {\n const result = new Date(date);\n const day = result.getDay();\n const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;\n\n // Use setDate() to handle DST transitions correctly\n // (millisecond arithmetic fails when days are 23 or 25 hours)\n result.setDate(result.getDate() - diff);\n result.setHours(0, 0, 0, 0);\n return result;\n }\n\n /**\n * Get the end of a week\n * @param {Date} date - The date\n * @param {number} weekStartsOn - 0 = Sunday, 1 = Monday, etc.\n * @returns {Date}\n */\n static endOfWeek(date, weekStartsOn = 0) {\n const result = DateUtils.startOfWeek(date, weekStartsOn);\n // Use setDate() to handle DST transitions correctly\n // (millisecond arithmetic fails when days are 23 or 25 hours)\n result.setDate(result.getDate() + 6);\n result.setHours(23, 59, 59, 999);\n return result;\n }\n\n /**\n * Get the start of a month\n * @param {Date} date - The date\n * @returns {Date}\n */\n static startOfMonth(date) {\n return new Date(date.getFullYear(), date.getMonth(), 1, 0, 0, 0, 0);\n }\n\n /**\n * Get the end of a month\n * @param {Date} date - The date\n * @returns {Date}\n */\n static endOfMonth(date) {\n return new Date(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59, 999);\n }\n\n /**\n * Get the start of a year\n * @param {Date} date - The date\n * @returns {Date}\n */\n static startOfYear(date) {\n return new Date(date.getFullYear(), 0, 1, 0, 0, 0, 0);\n }\n\n /**\n * Get the end of a year\n * @param {Date} date - The date\n * @returns {Date}\n */\n static endOfYear(date) {\n return new Date(date.getFullYear(), 11, 31, 23, 59, 59, 999);\n }\n\n /**\n * Add days to a date\n * @param {Date} date - The date\n * @param {number} days - Number of days to add (can be negative)\n * @returns {Date}\n */\n static addDays(date, days) {\n const result = new Date(date);\n // Use setDate() to handle DST transitions correctly\n // (millisecond arithmetic fails when days are 23 or 25 hours)\n result.setDate(result.getDate() + days);\n return result;\n }\n\n /**\n * Add weeks to a date\n * @param {Date} date - The date\n * @param {number} weeks - Number of weeks to add\n * @returns {Date}\n */\n static addWeeks(date, weeks) {\n return DateUtils.addDays(date, weeks * 7);\n }\n\n /**\n * Add months to a date\n * @param {Date} date - The date\n * @param {number} months - Number of months to add\n * @returns {Date}\n */\n static addMonths(date, months) {\n const result = new Date(date);\n const dayOfMonth = result.getDate();\n result.setMonth(result.getMonth() + months);\n\n // Handle edge case where day doesn't exist in new month\n if (result.getDate() !== dayOfMonth) {\n result.setDate(0); // Go to last day of previous month\n }\n\n return result;\n }\n\n /**\n * Add years to a date\n * @param {Date} date - The date\n * @param {number} years - Number of years to add\n * @returns {Date}\n */\n static addYears(date, years) {\n const result = new Date(date);\n result.setFullYear(result.getFullYear() + years);\n return result;\n }\n\n /**\n * Get a consistent UTC date string for indexing (YYYY-MM-DD format)\n * @param {Date} date - The date\n * @returns {string} UTC date string\n */\n static getUTCDateString(date) {\n const year = date.getUTCFullYear();\n const month = String(date.getUTCMonth() + 1).padStart(2, '0');\n const day = String(date.getUTCDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n /**\n * Get a consistent local date string for indexing (YYYY-MM-DD format)\n * @param {Date} date - The date\n * @returns {string} Local date string\n */\n static getLocalDateString(date) {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n /**\n * Check if a date is today\n * @param {Date} date - The date to check\n * @returns {boolean}\n */\n static isToday(date) {\n const today = new Date();\n return date.toDateString() === today.toDateString();\n }\n\n /**\n * Check if a date is in the past\n * @param {Date} date - The date to check\n * @returns {boolean}\n */\n static isPast(date) {\n return date < new Date();\n }\n\n /**\n * Check if a date is in the future\n * @param {Date} date - The date to check\n * @returns {boolean}\n */\n static isFuture(date) {\n return date > new Date();\n }\n\n /**\n * Check if two dates are on the same day\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {boolean}\n */\n static isSameDay(date1, date2) {\n return (\n date1.getFullYear() === date2.getFullYear() &&\n date1.getMonth() === date2.getMonth() &&\n date1.getDate() === date2.getDate()\n );\n }\n\n /**\n * Check if two dates are in the same week\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @param {number} weekStartsOn - 0 = Sunday, 1 = Monday, etc.\n * @returns {boolean}\n */\n static isSameWeek(date1, date2, weekStartsOn = 0) {\n const week1Start = DateUtils.startOfWeek(date1, weekStartsOn);\n const week2Start = DateUtils.startOfWeek(date2, weekStartsOn);\n return week1Start.toDateString() === week2Start.toDateString();\n }\n\n /**\n * Check if two dates are in the same month\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {boolean}\n */\n static isSameMonth(date1, date2) {\n return date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth();\n }\n\n /**\n * Check if two dates are in the same year\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {boolean}\n */\n static isSameYear(date1, date2) {\n return date1.getFullYear() === date2.getFullYear();\n }\n\n /**\n * Get the difference in days between two dates\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {number}\n */\n static differenceInDays(date1, date2) {\n const diff = date1.getTime() - date2.getTime();\n return Math.floor(diff / (1000 * 60 * 60 * 24));\n }\n\n /**\n * Get the difference in weeks between two dates\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {number}\n */\n static differenceInWeeks(date1, date2) {\n return Math.floor(DateUtils.differenceInDays(date1, date2) / 7);\n }\n\n /**\n * Get the difference in months between two dates\n * @param {Date} date1 - First date\n * @param {Date} date2 - Second date\n * @returns {number}\n */\n static differenceInMonths(date1, date2) {\n const yearDiff = date1.getFullYear() - date2.getFullYear();\n const monthDiff = date1.getMonth() - date2.getMonth();\n return yearDiff * 12 + monthDiff;\n }\n\n /**\n * Get the week number of a date\n * @param {Date} date - The date\n * @returns {number}\n */\n static getWeekNumber(date) {\n const firstDayOfYear = new Date(date.getFullYear(), 0, 1);\n const pastDaysOfYear = (date - firstDayOfYear) / 86400000;\n return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);\n }\n\n /**\n * Get the day of week for a date\n * @param {Date} date - The date\n * @param {number} weekStartsOn - 0 = Sunday, 1 = Monday, etc.\n * @returns {number} 0-6 where 0 is the first day of the week\n */\n static getDayOfWeek(date, weekStartsOn = 0) {\n const day = date.getDay();\n return (day - weekStartsOn + 7) % 7;\n }\n\n /**\n * Get days in a month\n * @param {Date} date - Any date in the month\n * @returns {number}\n */\n static getDaysInMonth(date) {\n return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();\n }\n\n /**\n * Format a date using Intl.DateTimeFormat\n * @param {Date} date - The date to format\n * @param {string} locale - The locale\n * @param {Object} options - Intl.DateTimeFormat options\n * @returns {string}\n */\n static format(date, locale = 'en-US', options = {}) {\n return new Intl.DateTimeFormat(locale, options).format(date);\n }\n\n /**\n * Get month name\n * @param {Date} date - The date\n * @param {string} locale - The locale\n * @param {string} format - 'long', 'short', or 'narrow'\n * @returns {string}\n */\n static getMonthName(date, locale = 'en-US', format = 'long') {\n return DateUtils.format(date, locale, { month: format });\n }\n\n /**\n * Get day name\n * @param {Date} date - The date\n * @param {string} locale - The locale\n * @param {string} format - 'long', 'short', or 'narrow'\n * @returns {string}\n */\n static getDayName(date, locale = 'en-US', format = 'long') {\n return DateUtils.format(date, locale, { weekday: format });\n }\n\n /**\n * Format time\n * @param {Date} date - The date\n * @param {string} locale - The locale\n * @param {boolean} use24Hour - Use 24-hour format\n * @returns {string}\n */\n static formatTime(date, locale = 'en-US', use24Hour = false) {\n return DateUtils.format(date, locale, {\n hour: 'numeric',\n minute: '2-digit',\n hour12: !use24Hour\n });\n }\n\n /**\n * Parse a time string (HH:MM) to hours and minutes\n * @param {string} timeString - Time string like \"09:30\"\n * @returns {{hours: number, minutes: number}}\n */\n static parseTime(timeString) {\n const [hours, minutes] = timeString.split(':').map(Number);\n return { hours, minutes };\n }\n\n /**\n * Set time on a date\n * @param {Date} date - The date\n * @param {string} timeString - Time string like \"09:30\"\n * @returns {Date}\n */\n static setTime(date, timeString) {\n const result = new Date(date);\n const { hours, minutes } = DateUtils.parseTime(timeString);\n result.setHours(hours, minutes, 0, 0);\n return result;\n }\n\n /**\n * Check if a year is a leap year\n * @param {number} year - The year\n * @returns {boolean}\n */\n static isLeapYear(year) {\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n }\n\n /**\n * Get an array of dates between start and end\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @returns {Date[]}\n */\n static getDateRange(start, end) {\n const dates = [];\n const current = new Date(start);\n const endTime = end.getTime();\n\n while (current.getTime() <= endTime) {\n dates.push(new Date(current));\n // Use setDate() to handle DST transitions correctly\n // (millisecond arithmetic fails when days are 23 or 25 hours)\n current.setDate(current.getDate() + 1);\n }\n\n return dates;\n }\n\n /**\n * Clone a date\n * @param {Date} date - The date to clone\n * @returns {Date}\n */\n static clone(date) {\n return new Date(date);\n }\n\n /**\n * Validate if a value is a valid date\n * @param {*} value - Value to check\n * @returns {boolean}\n */\n static isValidDate(value) {\n return value instanceof Date && !isNaN(value.getTime());\n }\n\n /**\n * Convert a date to a specific timezone\n * @param {Date} date - The date to convert\n * @param {string} timeZone - IANA timezone string (e.g., 'America/New_York')\n * @returns {Date} - Date object adjusted for timezone\n */\n static toTimeZone(date, timeZone) {\n // Get the date string in the target timezone\n const formatter = new Intl.DateTimeFormat('en-US', {\n timeZone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false\n });\n\n const parts = formatter.formatToParts(date);\n const dateObj = {};\n parts.forEach(part => {\n if (part.type !== 'literal') {\n dateObj[part.type] = part.value;\n }\n });\n\n // Create new date in the target timezone\n return new Date(\n `${dateObj.year}-${dateObj.month}-${dateObj.day}T${dateObj.hour}:${dateObj.minute}:${dateObj.second}`\n );\n }\n\n /**\n * Get timezone offset in minutes for a date\n * @param {Date} date - The date\n * @param {string} timeZone - IANA timezone string\n * @returns {number} - Offset in minutes\n */\n static getTimezoneOffset(date, timeZone) {\n const utcDate = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));\n const tzDate = new Date(date.toLocaleString('en-US', { timeZone }));\n return (utcDate.getTime() - tzDate.getTime()) / 60000;\n }\n\n /**\n * Check if DST is in effect for a date in a timezone\n * @param {Date} date - The date to check\n * @param {string} timeZone - IANA timezone string\n * @returns {boolean}\n */\n static isDST(date, timeZone) {\n const jan = new Date(date.getFullYear(), 0, 1);\n const jul = new Date(date.getFullYear(), 6, 1);\n const janOffset = DateUtils.getTimezoneOffset(jan, timeZone);\n const julOffset = DateUtils.getTimezoneOffset(jul, timeZone);\n const currentOffset = DateUtils.getTimezoneOffset(date, timeZone);\n\n return Math.max(janOffset, julOffset) === currentOffset;\n }\n\n /**\n * Add time accounting for DST transitions\n * @param {Date} date - The date\n * @param {number} hours - Hours to add\n * @param {string} timeZone - IANA timezone string\n * @returns {Date}\n */\n static addHoursWithDST(date, hours, timeZone) {\n const result = new Date(date);\n const originalOffset = DateUtils.getTimezoneOffset(date, timeZone);\n\n // Add hours\n result.setTime(result.getTime() + hours * 60 * 60 * 1000);\n\n // Check if DST transition occurred\n const newOffset = DateUtils.getTimezoneOffset(result, timeZone);\n if (originalOffset !== newOffset) {\n // Adjust for DST change\n const dstAdjustment = (newOffset - originalOffset) * 60000;\n result.setTime(result.getTime() + dstAdjustment);\n }\n\n return result;\n }\n\n /**\n * Create a date in a specific timezone\n * @param {number} year\n * @param {number} month - 0-indexed\n * @param {number} day\n * @param {number} hour\n * @param {number} minute\n * @param {number} second\n * @param {string} timeZone - IANA timezone string\n * @returns {Date}\n */\n static createInTimeZone(year, month, day, hour = 0, minute = 0, second = 0, timeZone) {\n // Create date string in ISO format\n const dateStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;\n const timeStr = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}:${String(second).padStart(2, '0')}`;\n\n // Use Intl API to get the UTC time for this local time in the timezone\n const formatter = new Intl.DateTimeFormat('en-US', {\n timeZone,\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false\n });\n\n // Parse the local date in the target timezone\n const localDate = new Date(`${dateStr}T${timeStr}`);\n\n // Get offset and adjust\n const offset = DateUtils.getTimezoneOffset(localDate, timeZone);\n const utcTime = localDate.getTime() + offset * 60000;\n\n return new Date(utcTime);\n }\n}\n","/**\n * RRuleParser - Full RFC 5545 compliant RRULE parser\n * Supports all RFC 5545 recurrence rule features\n */\n\nexport class RRuleParser {\n /**\n * Parse an RRULE string into a structured rule object\n * @param {string|Object} rrule - RRULE string or rule object\n * @returns {Object} Parsed rule object\n */\n static parse(rrule) {\n // If already an object, validate and return\n if (typeof rrule === 'object') {\n return this.validateRule(rrule);\n }\n\n const rule = {\n freq: null,\n interval: 1,\n count: null,\n until: null,\n byDay: [],\n byWeekNo: [],\n byMonth: [],\n byMonthDay: [],\n byYearDay: [],\n bySetPos: [],\n byHour: [],\n byMinute: [],\n bySecond: [],\n wkst: 'MO', // Week start day\n exceptions: [],\n tzid: null\n };\n\n // Parse RRULE string\n const parts = rrule.toUpperCase().split(';');\n\n for (const part of parts) {\n const [key, value] = part.split('=');\n\n switch (key) {\n case 'FREQ':\n rule.freq = this.parseFrequency(value);\n break;\n\n case 'INTERVAL':\n rule.interval = parseInt(value, 10);\n if (rule.interval < 1) rule.interval = 1;\n break;\n\n case 'COUNT':\n rule.count = parseInt(value, 10);\n break;\n\n case 'UNTIL':\n rule.until = this.parseDateTime(value);\n break;\n\n case 'BYDAY':\n rule.byDay = this.parseByDay(value);\n break;\n\n case 'BYWEEKNO':\n rule.byWeekNo = this.parseIntList(value);\n break;\n\n case 'BYMONTH':\n rule.byMonth = this.parseIntList(value);\n break;\n\n case 'BYMONTHDAY':\n rule.byMonthDay = this.parseIntList(value);\n break;\n\n case 'BYYEARDAY':\n rule.byYearDay = this.parseIntList(value);\n break;\n\n case 'BYSETPOS':\n rule.bySetPos = this.parseIntList(value);\n break;\n\n case 'BYHOUR':\n rule.byHour = this.parseIntList(value);\n break;\n\n case 'BYMINUTE':\n rule.byMinute = this.parseIntList(value);\n break;\n\n case 'BYSECOND':\n rule.bySecond = this.parseIntList(value);\n break;\n\n case 'WKST':\n rule.wkst = value;\n break;\n\n case 'EXDATE':\n rule.exceptions = this.parseExceptionDates(value);\n break;\n\n case 'TZID':\n rule.tzid = value;\n break;\n }\n }\n\n return this.validateRule(rule);\n }\n\n /**\n * Parse frequency value\n * @private\n */\n static parseFrequency(freq) {\n const validFrequencies = [\n 'SECONDLY',\n 'MINUTELY',\n 'HOURLY',\n 'DAILY',\n 'WEEKLY',\n 'MONTHLY',\n 'YEARLY'\n ];\n return validFrequencies.includes(freq) ? freq : 'DAILY';\n }\n\n /**\n * Parse BYDAY value\n * Returns array of strings like ['MO', '2TU', '-1FR'] for compatibility with RecurrenceEngine\n * @private\n */\n static parseByDay(value) {\n const days = value.split(',');\n const weekDays = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'];\n const result = [];\n\n for (const day of days) {\n const trimmed = day.trim().toUpperCase();\n const match = trimmed.match(/^([+-]?\\d*)([A-Z]{2})$/);\n if (match) {\n const [_, nth, weekday] = match;\n if (weekDays.includes(weekday)) {\n // Return string format for RecurrenceEngine compatibility\n // e.g., 'MO', '2MO', '-1FR'\n result.push(nth ? `${nth}${weekday}` : weekday);\n }\n }\n }\n\n return result;\n }\n\n /**\n * Parse comma-separated integer list\n * @private\n */\n static parseIntList(value) {\n return value\n .split(',')\n .map(v => parseInt(v.trim(), 10))\n .filter(v => !isNaN(v));\n }\n\n /**\n * Parse date/datetime value\n * @private\n */\n static parseDateTime(value) {\n // Handle different date formats\n // YYYYMMDD\n if (value.length === 8) {\n const year = parseInt(value.substr(0, 4), 10);\n const month = parseInt(value.substr(4, 2), 10) - 1;\n const day = parseInt(value.substr(6, 2), 10);\n return new Date(year, month, day);\n }\n\n // YYYYMMDDTHHMMSS\n if (value.length === 15 && value[8] === 'T') {\n const year = parseInt(value.substr(0, 4), 10);\n const month = parseInt(value.substr(4, 2), 10) - 1;\n const day = parseInt(value.substr(6, 2), 10);\n const hour = parseInt(value.substr(9, 2), 10);\n const minute = parseInt(value.substr(11, 2), 10);\n const second = parseInt(value.substr(13, 2), 10);\n return new Date(year, month, day, hour, minute, second);\n }\n\n // YYYYMMDDTHHMMSSZ (UTC)\n if (value.length === 16 && value[8] === 'T' && value[15] === 'Z') {\n const year = parseInt(value.substr(0, 4), 10);\n const month = parseInt(value.substr(4, 2), 10) - 1;\n const day = parseInt(value.substr(6, 2), 10);\n const hour = parseInt(value.substr(9, 2), 10);\n const minute = parseInt(value.substr(11, 2), 10);\n const second = parseInt(value.substr(13, 2), 10);\n return new Date(Date.UTC(year, month, day, hour, minute, second));\n }\n\n // Try standard date parse as fallback\n return new Date(value);\n }\n\n /**\n * Parse exception dates\n * @private\n */\n static parseExceptionDates(value) {\n const dates = value.split(',');\n return dates.map(date => this.parseDateTime(date.trim()));\n }\n\n /**\n * Validate and normalize rule\n * @private\n */\n static validateRule(rule) {\n // Ensure frequency is set\n if (!rule.freq) {\n rule.freq = 'DAILY';\n }\n\n // Cannot have both COUNT and UNTIL\n if (rule.count && rule.until) {\n throw new Error('RRULE cannot have both COUNT and UNTIL');\n }\n\n // Validate interval\n if (rule.interval < 1) {\n rule.interval = 1;\n }\n\n // Validate by* arrays\n const validateArray = (arr, min, max) => {\n return arr.filter(v => v >= min && v <= max);\n };\n\n rule.byMonth = validateArray(rule.byMonth || [], 1, 12);\n rule.byMonthDay = validateArray(rule.byMonthDay || [], -31, 31).filter(v => v !== 0);\n rule.byYearDay = validateArray(rule.byYearDay || [], -366, 366).filter(v => v !== 0);\n rule.byWeekNo = validateArray(rule.byWeekNo || [], -53, 53).filter(v => v !== 0);\n rule.byHour = validateArray(rule.byHour || [], 0, 23);\n rule.byMinute = validateArray(rule.byMinute || [], 0, 59);\n rule.bySecond = validateArray(rule.bySecond || [], 0, 59);\n\n return rule;\n }\n\n /**\n * Build RRULE string from rule object\n * @param {Object} rule - Rule object\n * @returns {string} RRULE string\n */\n static buildRRule(rule) {\n const parts = [];\n\n // Required frequency\n parts.push(`FREQ=${rule.freq}`);\n\n // Optional interval\n if (rule.interval && rule.interval > 1) {\n parts.push(`INTERVAL=${rule.interval}`);\n }\n\n // Count or until\n if (rule.count) {\n parts.push(`COUNT=${rule.count}`);\n } else if (rule.until) {\n parts.push(`UNTIL=${this.formatDateTime(rule.until)}`);\n }\n\n // By* rules\n if (rule.byDay && rule.byDay.length > 0) {\n const dayStr = rule.byDay\n .map(d => {\n // Handle both string format ('MO', '2TU', '-1FR') from parseByDay\n // and object format ({nth: 2, weekday: 'MO'})\n if (typeof d === 'string') {\n return d;\n }\n return d.nth ? `${d.nth}${d.weekday}` : d.weekday;\n })\n .join(',');\n parts.push(`BYDAY=${dayStr}`);\n }\n\n if (rule.byMonth && rule.byMonth.length > 0) {\n parts.push(`BYMONTH=${rule.byMonth.join(',')}`);\n }\n\n if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n parts.push(`BYMONTHDAY=${rule.byMonthDay.join(',')}`);\n }\n\n if (rule.byYearDay && rule.byYearDay.length > 0) {\n parts.push(`BYYEARDAY=${rule.byYearDay.join(',')}`);\n }\n\n if (rule.byWeekNo && rule.byWeekNo.length > 0) {\n parts.push(`BYWEEKNO=${rule.byWeekNo.join(',')}`);\n }\n\n if (rule.bySetPos && rule.bySetPos.length > 0) {\n parts.push(`BYSETPOS=${rule.bySetPos.join(',')}`);\n }\n\n if (rule.byHour && rule.byHour.length > 0) {\n parts.push(`BYHOUR=${rule.byHour.join(',')}`);\n }\n\n if (rule.byMinute && rule.byMinute.length > 0) {\n parts.push(`BYMINUTE=${rule.byMinute.join(',')}`);\n }\n\n if (rule.bySecond && rule.bySecond.length > 0) {\n parts.push(`BYSECOND=${rule.bySecond.join(',')}`);\n }\n\n // Week start\n if (rule.wkst && rule.wkst !== 'MO') {\n parts.push(`WKST=${rule.wkst}`);\n }\n\n return parts.join(';');\n }\n\n /**\n * Format date/datetime for RRULE\n * @private\n */\n static formatDateTime(date) {\n const year = date.getUTCFullYear();\n const month = String(date.getUTCMonth() + 1).padStart(2, '0');\n const day = String(date.getUTCDate()).padStart(2, '0');\n const hour = String(date.getUTCHours()).padStart(2, '0');\n const minute = String(date.getUTCMinutes()).padStart(2, '0');\n const second = String(date.getUTCSeconds()).padStart(2, '0');\n\n return `${year}${month}${day}T${hour}${minute}${second}Z`;\n }\n\n /**\n * Get human-readable description of rule\n * @param {Object} rule - Parsed rule object\n * @returns {string} Human-readable description\n */\n static getDescription(rule) {\n const freqMap = {\n SECONDLY: 'second',\n MINUTELY: 'minute',\n HOURLY: 'hour',\n DAILY: 'day',\n WEEKLY: 'week',\n MONTHLY: 'month',\n YEARLY: 'year'\n };\n\n const weekdayMap = {\n SU: 'Sunday',\n MO: 'Monday',\n TU: 'Tuesday',\n WE: 'Wednesday',\n TH: 'Thursday',\n FR: 'Friday',\n SA: 'Saturday'\n };\n\n const nthMap = {\n 1: 'first',\n 2: 'second',\n 3: 'third',\n 4: 'fourth',\n 5: 'fifth',\n '-1': 'last',\n '-2': 'second to last'\n };\n\n let description = 'Every';\n\n // Interval\n if (rule.interval > 1) {\n description += ` ${rule.interval}`;\n }\n\n // Frequency\n description += ` ${freqMap[rule.freq]}`;\n if (rule.interval > 1) {\n description += 's';\n }\n\n // By day - handle both string format ('MO', '2TU') and object format ({nth, weekday})\n if (rule.byDay && rule.byDay.length > 0) {\n // Helper to extract weekday and nth from string or object\n const parseDay = d => {\n if (typeof d === 'string') {\n const match = d.match(/^(-?\\d+)?([A-Z]{2})$/);\n if (match) {\n return { nth: match[1] ? parseInt(match[1], 10) : null, weekday: match[2] };\n }\n return { nth: null, weekday: d };\n }\n return d;\n };\n\n if (rule.freq === 'WEEKLY') {\n const days = rule.byDay.map(d => weekdayMap[parseDay(d).weekday]).join(', ');\n description += ` on ${days}`;\n } else if (rule.freq === 'MONTHLY' || rule.freq === 'YEARLY') {\n const dayDescs = rule.byDay\n .map(d => {\n const parsed = parseDay(d);\n if (parsed.nth) {\n return `the ${nthMap[parsed.nth] || parsed.nth} ${weekdayMap[parsed.weekday]}`;\n }\n return weekdayMap[parsed.weekday];\n })\n .join(', ');\n description += ` on ${dayDescs}`;\n }\n }\n\n // By month day\n if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n const days = rule.byMonthDay\n .map(d => {\n if (d < 0) {\n return `${Math.abs(d)} day(s) from the end`;\n }\n return `day ${d}`;\n })\n .join(', ');\n description += ` on ${days}`;\n }\n\n // By month\n if (rule.byMonth && rule.byMonth.length > 0) {\n const monthNames = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December'\n ];\n const months = rule.byMonth.map(m => monthNames[m - 1]).join(', ');\n description += ` in ${months}`;\n }\n\n // Count or until\n if (rule.count) {\n description += `, ${rule.count} time${rule.count > 1 ? 's' : ''}`;\n } else if (rule.until) {\n description += `, until ${rule.until.toLocaleDateString()}`;\n }\n\n return description;\n }\n}\n","import { DateUtils } from '../calendar/DateUtils.js';\nimport { TimezoneManager } from '../timezone/TimezoneManager.js';\nimport { RRuleParser } from './RRuleParser.js';\n\n/**\n * RecurrenceEngine - Handles expansion of recurring events\n * Full support for RFC 5545 (iCalendar) RRULE specification\n */\nexport class RecurrenceEngine {\n /**\n * Expand a recurring event into individual occurrences\n * @param {import('./Event.js').Event} event - The recurring event\n * @param {Date} rangeStart - Start of the expansion range\n * @param {Date} rangeEnd - End of the expansion range\n * @param {number} [maxOccurrences=365] - Maximum number of occurrences to generate\n * @param {string} [timezone] - Timezone for expansion (important for DST)\n * @returns {import('../../types.js').EventOccurrence[]} Array of occurrence objects with start/end dates\n */\n static expandEvent(event, rangeStart, rangeEnd, maxOccurrences = 365, timezone = null) {\n if (!event.recurring || !event.recurrenceRule) {\n return [{ start: event.start, end: event.end, timezone: event.timeZone }];\n }\n\n const rule = this.parseRule(event.recurrenceRule);\n const occurrences = [];\n const duration = event.end - event.start;\n const eventTimezone = timezone || event.timeZone || 'UTC';\n const tzManager = TimezoneManager.getInstance();\n\n // Work in event's timezone for accurate recurrence calculation\n let currentDate = new Date(event.start);\n let count = 0;\n\n // If UNTIL is specified, use it as the range end\n if (rule.until && rule.until < rangeEnd) {\n rangeEnd = rule.until;\n }\n\n // Track DST transitions for proper timezone handling\n let lastOffset = tzManager.getTimezoneOffset(currentDate, eventTimezone);\n\n // Track last date to detect infinite loop (date not advancing)\n const lastDateTimestamp = null;\n let stuckCount = 0;\n const maxStuckIterations = 3;\n\n while (currentDate <= rangeEnd && count < maxOccurrences) {\n // Check if this occurrence is within the range\n if (currentDate >= rangeStart) {\n const occurrenceStart = new Date(currentDate);\n const occurrenceEnd = new Date(currentDate.getTime() + duration);\n\n // Handle DST transitions\n const currentOffset = tzManager.getTimezoneOffset(occurrenceStart, eventTimezone);\n if (currentOffset !== lastOffset) {\n // Adjust for DST change\n const offsetDiff = lastOffset - currentOffset;\n occurrenceStart.setMinutes(occurrenceStart.getMinutes() + offsetDiff);\n occurrenceEnd.setMinutes(occurrenceEnd.getMinutes() + offsetDiff);\n }\n lastOffset = currentOffset;\n\n // Apply exceptions if any\n if (!this.isException(occurrenceStart, rule, event.id)) {\n occurrences.push({\n start: occurrenceStart,\n end: occurrenceEnd,\n recurringEventId: event.id,\n timezone: eventTimezone,\n originalStart: event.start\n });\n }\n }\n\n // Calculate next occurrence\n const previousTimestamp = currentDate.getTime();\n currentDate = this.getNextOccurrence(currentDate, rule, eventTimezone);\n count++;\n\n // Safeguard: detect if date is not advancing (infinite loop risk)\n if (currentDate.getTime() === previousTimestamp) {\n stuckCount++;\n if (stuckCount >= maxStuckIterations) {\n console.warn('RecurrenceEngine: Date not advancing, breaking to prevent infinite loop');\n break;\n }\n } else {\n stuckCount = 0;\n }\n\n // Check COUNT limit\n if (rule.count && count >= rule.count) {\n break;\n }\n }\n\n return occurrences;\n }\n\n /**\n * Parse an RRULE string into a rule object\n * @param {string|import('../../types.js').RecurrenceRule} ruleString - RRULE string (e.g., \"FREQ=DAILY;INTERVAL=1;COUNT=10\") or rule object\n * @returns {import('../../types.js').RecurrenceRule} Parsed rule object\n */\n static parseRule(ruleString) {\n // Use the new comprehensive parser\n return RRuleParser.parse(ruleString);\n }\n\n /**\n * Calculate the next occurrence based on the rule\n * @param {Date} currentDate - Current occurrence date\n * @param {Object} rule - Recurrence rule object\n * @param {string} [timezone] - Timezone for calculation\n * @returns {Date} Next occurrence date\n */\n static getNextOccurrence(currentDate, rule, timezone = 'UTC') {\n const next = new Date(currentDate);\n\n switch (rule.freq) {\n case 'DAILY':\n next.setDate(next.getDate() + rule.interval);\n break;\n\n case 'WEEKLY':\n if (rule.byDay && rule.byDay.length > 0) {\n // Find next day that matches byDay\n // Limit iterations to prevent infinite loop with malformed byDay\n const maxIterations = 8; // 7 days + 1 for safety\n let iterations = 0;\n const originalDate = next.getDate();\n next.setDate(next.getDate() + 1);\n while (!this.matchesByDay(next, rule.byDay) && iterations < maxIterations) {\n next.setDate(next.getDate() + 1);\n iterations++;\n }\n // If no match found, fall back to simple weekly interval from original date\n if (iterations >= maxIterations) {\n console.warn('RecurrenceEngine: Invalid byDay rule, falling back to weekly interval');\n // Reset to original and add weekly interval\n next.setDate(originalDate + 7 * rule.interval);\n }\n } else {\n // Simple weekly recurrence\n next.setDate(next.getDate() + 7 * rule.interval);\n }\n break;\n\n case 'MONTHLY':\n if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n // Specific day(s) of month\n const currentMonth = next.getMonth();\n next.setMonth(currentMonth + rule.interval);\n next.setDate(rule.byMonthDay[0]); // Use first specified day\n } else if (rule.byDay && rule.byDay.length > 0) {\n // Specific weekday of month (e.g., \"2nd Tuesday\")\n next.setMonth(next.getMonth() + rule.interval);\n this.setToWeekdayOfMonth(next, rule.byDay[0], rule.bySetPos[0] || 1);\n } else {\n // Same day of month\n next.setMonth(next.getMonth() + rule.interval);\n }\n break;\n\n case 'YEARLY':\n if (rule.byMonth && rule.byMonth.length > 0) {\n next.setFullYear(next.getFullYear() + rule.interval);\n next.setMonth(rule.byMonth[0] - 1); // Months are 0-indexed\n } else {\n next.setFullYear(next.getFullYear() + rule.interval);\n }\n break;\n\n default:\n // Unsupported frequency\n next.setTime(next.getTime() + 24 * 60 * 60 * 1000); // Daily fallback\n }\n\n return next;\n }\n\n /**\n * Check if a date matches the BYDAY rule\n * @param {Date} date - Date to check\n * @param {Array<string>} byDay - Array of day codes (e.g., ['MO', 'WE', 'FR'])\n * @returns {boolean}\n */\n static matchesByDay(date, byDay) {\n const dayMap = {\n SU: 0,\n MO: 1,\n TU: 2,\n WE: 3,\n TH: 4,\n FR: 5,\n SA: 6\n };\n\n const dayOfWeek = date.getDay();\n return byDay.some(day => {\n // Handle numbered weekdays (e.g., \"2MO\" for 2nd Monday)\n const match = day.match(/^(-?\\d+)?([A-Z]{2})$/);\n if (match) {\n const weekdayCode = match[2];\n return dayMap[weekdayCode] === dayOfWeek;\n }\n return false;\n });\n }\n\n /**\n * Set date to specific weekday of month\n * @param {Date} date - Date to modify\n * @param {string} weekday - Weekday code (e.g., 'MO', 'TU')\n * @param {number} position - Position in month (1-5, or -1 for last)\n */\n static setToWeekdayOfMonth(date, weekday, position = 1) {\n const dayMap = {\n SU: 0,\n MO: 1,\n TU: 2,\n WE: 3,\n TH: 4,\n FR: 5,\n SA: 6\n };\n\n // Extract weekday code if it has a number prefix\n const match = weekday.match(/^(-?\\d+)?([A-Z]{2})$/);\n const weekdayCode = match ? match[2] : weekday;\n const targetDay = dayMap[weekdayCode];\n\n date.setDate(1); // Start at first of month\n\n // Find first occurrence of the weekday\n while (date.getDay() !== targetDay) {\n date.setDate(date.getDate() + 1);\n }\n\n // Move to the nth occurrence\n if (position > 1) {\n date.setDate(date.getDate() + 7 * (position - 1));\n } else if (position === -1) {\n // Last occurrence of the month\n const nextMonth = new Date(date);\n nextMonth.setMonth(nextMonth.getMonth() + 1);\n nextMonth.setDate(0); // Last day of current month\n\n while (nextMonth.getDay() !== targetDay) {\n nextMonth.setDate(nextMonth.getDate() - 1);\n }\n date.setTime(nextMonth.getTime());\n }\n }\n\n /**\n * Check if a date is an exception\n * @param {Date} date - Date to check\n * @param {Object} rule - Rule object with exceptions\n * @param {string} [eventId] - Event ID for better exception tracking\n * @returns {boolean}\n */\n static isException(date, rule, eventId = null) {\n if (!rule.exceptions || rule.exceptions.length === 0) {\n return false;\n }\n\n // Support both date-only and date-time exceptions\n const dateStr = date.toDateString();\n const dateTime = date.getTime();\n\n return rule.exceptions.some(exDate => {\n if (typeof exDate === 'object' && exDate.date) {\n // Enhanced exception format with reason\n const exceptionDate = exDate.date instanceof Date ? exDate.date : new Date(exDate.date);\n if (exDate.matchTime) {\n return Math.abs(exceptionDate.getTime() - dateTime) < 1000; // Within 1 second\n }\n return exceptionDate.toDateString() === dateStr;\n }\n // Simple date exception\n const exceptionDate = exDate instanceof Date ? exDate : new Date(exDate);\n return exceptionDate.toDateString() === dateStr;\n });\n }\n\n /**\n * Add exception dates to a recurrence rule\n * @param {Object} rule - Recurrence rule\n * @param {Date|Date[]} exceptions - Exception date(s) to add\n * @param {Object} [options] - Options for exception\n * @returns {Object} Updated rule\n */\n static addExceptions(rule, exceptions, options = {}) {\n if (!rule.exceptions) {\n rule.exceptions = [];\n }\n\n const exceptionArray = Array.isArray(exceptions) ? exceptions : [exceptions];\n\n exceptionArray.forEach(date => {\n if (options.reason || options.matchTime) {\n rule.exceptions.push({\n date: date,\n reason: options.reason,\n matchTime: options.matchTime || false\n });\n } else {\n rule.exceptions.push(date);\n }\n });\n\n return rule;\n }\n\n /**\n * Parse date from RRULE format (YYYYMMDDTHHMMSSZ)\n * @param {string} dateStr - Date string in RRULE format\n * @returns {Date}\n */\n static parseDate(dateStr) {\n if (dateStr.length === 8) {\n // YYYYMMDD\n const year = parseInt(dateStr.substr(0, 4), 10);\n const month = parseInt(dateStr.substr(4, 2), 10) - 1;\n const day = parseInt(dateStr.substr(6, 2), 10);\n return new Date(year, month, day);\n } else if (dateStr.length === 15 || dateStr.length === 16) {\n // YYYYMMDDTHHMMSS[Z]\n const year = parseInt(dateStr.substr(0, 4), 10);\n const month = parseInt(dateStr.substr(4, 2), 10) - 1;\n const day = parseInt(dateStr.substr(6, 2), 10);\n const hour = parseInt(dateStr.substr(9, 2), 10);\n const minute = parseInt(dateStr.substr(11, 2), 10);\n const second = parseInt(dateStr.substr(13, 2), 10);\n\n if (dateStr.endsWith('Z')) {\n return new Date(Date.UTC(year, month, day, hour, minute, second));\n }\n return new Date(year, month, day, hour, minute, second);\n }\n\n // Fallback to standard date parsing\n return new Date(dateStr);\n }\n\n /**\n * Generate a human-readable description of the recurrence rule\n * @param {Object|string} rule - Recurrence rule\n * @returns {string} Human-readable description\n */\n static getDescription(rule) {\n if (typeof rule === 'string') {\n rule = this.parseRule(rule);\n }\n\n let description = '';\n const interval = rule.interval || 1;\n\n switch (rule.freq) {\n case 'DAILY':\n description = interval === 1 ? 'Daily' : `Every ${interval} days`;\n break;\n case 'WEEKLY':\n description = interval === 1 ? 'Weekly' : `Every ${interval} weeks`;\n if (rule.byDay && rule.byDay.length > 0) {\n const days = rule.byDay.map(d => this.getDayName(d)).join(', ');\n description += ` on ${days}`;\n }\n break;\n case 'MONTHLY':\n description = interval === 1 ? 'Monthly' : `Every ${interval} months`;\n if (rule.byMonthDay && rule.byMonthDay.length > 0) {\n description += ` on day ${rule.byMonthDay.join(', ')}`;\n }\n break;\n case 'YEARLY':\n description = interval === 1 ? 'Yearly' : `Every ${interval} years`;\n break;\n }\n\n if (rule.count) {\n description += `, ${rule.count} times`;\n } else if (rule.until) {\n description += `, until ${rule.until.toLocaleDateString()}`;\n }\n\n return description;\n }\n\n /**\n * Get day name from RRULE day code\n * @param {string} dayCode - Day code (e.g., 'MO', '2TU')\n * @returns {string} Day name\n */\n static getDayName(dayCode) {\n const dayNames = {\n SU: 'Sunday',\n MO: 'Monday',\n TU: 'Tuesday',\n WE: 'Wednesday',\n TH: 'Thursday',\n FR: 'Friday',\n SA: 'Saturday'\n };\n\n // Extract day code if it has a number prefix\n const match = dayCode.match(/^(-?\\d+)?([A-Z]{2})$/);\n const code = match ? match[2] : dayCode;\n const position = match && match[1] ? parseInt(match[1], 10) : null;\n\n let name = dayNames[code] || dayCode;\n\n if (position) {\n const ordinals = ['', '1st', '2nd', '3rd', '4th', '5th'];\n const ordinal = position === -1 ? 'Last' : ordinals[position] || `${position}th`;\n name = `${ordinal} ${name}`;\n }\n\n return name;\n }\n}\n","/**\n * LRU (Least Recently Used) Cache implementation\n * Provides O(1) get and put operations\n */\nexport class LRUCache {\n /**\n * Create a new LRU Cache\n * @param {number} capacity - Maximum number of items in cache\n */\n constructor(capacity = 100) {\n this.capacity = capacity;\n this.cache = new Map();\n this.hits = 0;\n this.misses = 0;\n this.evictions = 0;\n }\n\n /**\n * Get a value from the cache\n * @param {string} key - Cache key\n * @returns {*} Cached value or undefined\n */\n get(key) {\n if (!this.cache.has(key)) {\n this.misses++;\n return undefined;\n }\n\n // Move to end (most recently used)\n const value = this.cache.get(key);\n this.cache.delete(key);\n this.cache.set(key, value);\n this.hits++;\n return value;\n }\n\n /**\n * Put a value in the cache\n * @param {string} key - Cache key\n * @param {*} value - Value to cache\n */\n put(key, value) {\n // Remove if exists to update position\n if (this.cache.has(key)) {\n this.cache.delete(key);\n } else if (this.cache.size >= this.capacity) {\n // Remove least recently used (first item)\n const firstKey = this.cache.keys().next().value;\n this.cache.delete(firstKey);\n this.evictions++;\n }\n\n this.cache.set(key, value);\n }\n\n /**\n * Check if key exists in cache\n * @param {string} key - Cache key\n * @returns {boolean} True if key exists\n */\n has(key) {\n return this.cache.has(key);\n }\n\n /**\n * Remove a key from the cache\n * @param {string} key - Cache key\n * @returns {boolean} True if key was removed\n */\n delete(key) {\n return this.cache.delete(key);\n }\n\n /**\n * Clear all cached items\n */\n clear() {\n this.cache.clear();\n this.hits = 0;\n this.misses = 0;\n this.evictions = 0;\n }\n\n /**\n * Get cache statistics\n * @returns {Object} Cache stats\n */\n getStats() {\n const hitRate =\n this.hits + this.misses > 0 ? ((this.hits / (this.hits + this.misses)) * 100).toFixed(2) : 0;\n\n return {\n size: this.cache.size,\n capacity: this.capacity,\n hits: this.hits,\n misses: this.misses,\n evictions: this.evictions,\n hitRate: `${hitRate}%`\n };\n }\n\n /**\n * Get all keys in order (least to most recently used)\n * @returns {string[]} Array of keys\n */\n keys() {\n return Array.from(this.cache.keys());\n }\n\n /**\n * Get cache size\n * @returns {number} Number of items in cache\n */\n get size() {\n return this.cache.size;\n }\n}\n","/**\n * AdaptiveMemoryManager - Dynamically manages cache sizes based on memory pressure\n * Monitors memory usage and adjusts cache capacity to prevent memory issues\n */\n\nexport class AdaptiveMemoryManager {\n constructor(config = {}) {\n this.config = {\n checkInterval: 30000, // Check memory every 30 seconds\n memoryThreshold: 0.8, // Start reducing cache at 80% memory usage\n criticalThreshold: 0.95, // Emergency clear at 95% memory usage\n minCacheSize: 10, // Minimum cache size to maintain\n maxCacheSize: 10000, // Maximum cache size allowed\n adaptiveScaling: true, // Enable/disable adaptive scaling\n ...config\n };\n\n // Cache references\n this.caches = new Map();\n\n // Memory statistics\n this.stats = {\n adjustments: 0,\n emergencyClears: 0,\n lastMemoryUsage: 0,\n lastCheckTime: null,\n cacheResizes: []\n };\n\n // Start monitoring if enabled\n this.monitoringInterval = null;\n if (this.config.adaptiveScaling) {\n this.startMonitoring();\n }\n }\n\n /**\n * Register a cache for management\n * @param {string} name - Cache identifier\n * @param {Object} cache - Cache instance with size/clear methods\n * @param {Object} [options] - Cache-specific options\n */\n registerCache(name, cache, options = {}) {\n this.caches.set(name, {\n cache,\n priority: options.priority || 1, // Higher priority = less likely to be reduced\n currentCapacity: options.initialCapacity || 100,\n minCapacity: options.minCapacity || this.config.minCacheSize,\n maxCapacity: options.maxCapacity || this.config.maxCacheSize,\n scaleFactor: options.scaleFactor || 0.5, // How much to reduce on pressure\n lastAccess: Date.now()\n });\n }\n\n /**\n * Unregister a cache\n * @param {string} name - Cache identifier\n */\n unregisterCache(name) {\n this.caches.delete(name);\n }\n\n /**\n * Start memory monitoring\n */\n startMonitoring() {\n if (this.monitoringInterval) {\n return;\n }\n\n this.monitoringInterval = setInterval(() => {\n this.checkMemoryPressure();\n }, this.config.checkInterval);\n\n // Initial check\n this.checkMemoryPressure();\n }\n\n /**\n * Stop memory monitoring\n */\n stopMonitoring() {\n if (this.monitoringInterval) {\n clearInterval(this.monitoringInterval);\n this.monitoringInterval = null;\n }\n }\n\n /**\n * Check memory pressure and adjust caches\n */\n async checkMemoryPressure() {\n const memoryUsage = await this.getMemoryUsage();\n this.stats.lastMemoryUsage = memoryUsage;\n this.stats.lastCheckTime = new Date();\n\n if (memoryUsage > this.config.criticalThreshold) {\n // Emergency clear - clear all caches\n this.emergencyClear();\n } else if (memoryUsage > this.config.memoryThreshold) {\n // Memory pressure - reduce cache sizes\n this.reduceCacheSizes(memoryUsage);\n } else if (memoryUsage < this.config.memoryThreshold - 0.2) {\n // Memory available - can increase cache sizes\n this.increaseCacheSizes();\n }\n }\n\n /**\n * Get current memory usage percentage\n * @returns {Promise<number>} Memory usage as percentage (0-1)\n */\n async getMemoryUsage() {\n // Browser environment\n if (typeof performance !== 'undefined' && performance.memory) {\n const memInfo = performance.memory;\n if (memInfo.jsHeapSizeLimit && memInfo.usedJSHeapSize) {\n return memInfo.usedJSHeapSize / memInfo.jsHeapSizeLimit;\n }\n }\n\n // Node.js environment - use fully indirect access to avoid LWC static analysis\n // Salesforce Locker Service blocks any reference to process.memoryUsage\n try {\n const g = typeof globalThis !== 'undefined' ? globalThis : {};\n const procKey = 'proc' + 'ess';\n const memKey = 'mem' + 'oryUsage';\n const p = g[procKey];\n if (p && typeof p === 'object') {\n const memFn = p[memKey];\n if (typeof memFn === 'function') {\n const usage = memFn.call(p);\n return usage.heapUsed / usage.heapTotal;\n }\n }\n } catch (e) {\n // Ignore - not in Node.js environment\n }\n\n // Fallback - estimate based on cache sizes\n return this.estimateMemoryUsage();\n }\n\n /**\n * Estimate memory usage based on cache sizes\n * @private\n */\n estimateMemoryUsage() {\n let totalItems = 0;\n let maxItems = 0;\n\n for (const [_, cacheInfo] of this.caches) {\n if (cacheInfo.cache.size !== undefined) {\n totalItems += cacheInfo.cache.size;\n maxItems += cacheInfo.maxCapacity;\n }\n }\n\n return maxItems > 0 ? totalItems / maxItems : 0.5;\n }\n\n /**\n * Reduce cache sizes based on memory pressure\n * @param {number} memoryUsage - Current memory usage percentage\n */\n reduceCacheSizes(memoryUsage) {\n const pressureLevel =\n (memoryUsage - this.config.memoryThreshold) /\n (this.config.criticalThreshold - this.config.memoryThreshold);\n\n // Sort caches by priority (lower priority first)\n const sortedCaches = Array.from(this.caches.entries()).sort(\n (a, b) => a[1].priority - b[1].priority\n );\n\n for (const [name, cacheInfo] of sortedCaches) {\n const reduction = Math.floor(\n cacheInfo.currentCapacity * cacheInfo.scaleFactor * pressureLevel\n );\n const newCapacity = Math.max(cacheInfo.minCapacity, cacheInfo.currentCapacity - reduction);\n\n if (newCapacity < cacheInfo.currentCapacity) {\n this.resizeCache(name, cacheInfo, newCapacity);\n }\n }\n\n this.stats.adjustments++;\n }\n\n /**\n * Increase cache sizes when memory is available\n */\n increaseCacheSizes() {\n for (const [name, cacheInfo] of this.caches) {\n // Only increase if cache is being actively used\n const timeSinceAccess = Date.now() - cacheInfo.lastAccess;\n if (timeSinceAccess < 60000) {\n // Used in last minute\n const increase = Math.floor(cacheInfo.currentCapacity * 0.2);\n const newCapacity = Math.min(cacheInfo.maxCapacity, cacheInfo.currentCapacity + increase);\n\n if (newCapacity > cacheInfo.currentCapacity) {\n this.resizeCache(name, cacheInfo, newCapacity);\n }\n }\n }\n }\n\n /**\n * Resize a cache\n * @private\n */\n resizeCache(name, cacheInfo, newCapacity) {\n const oldCapacity = cacheInfo.currentCapacity;\n cacheInfo.currentCapacity = newCapacity;\n\n // If cache has a capacity property, update it\n if (cacheInfo.cache.capacity !== undefined) {\n cacheInfo.cache.capacity = newCapacity;\n }\n\n // If cache is now over capacity, evict excess items\n if (cacheInfo.cache.size > newCapacity) {\n this.evictExcessItems(cacheInfo.cache, newCapacity);\n }\n\n // Record resize event\n this.stats.cacheResizes.push({\n cache: name,\n timestamp: new Date(),\n oldCapacity,\n newCapacity,\n reason: newCapacity < oldCapacity ? 'pressure' : 'available'\n });\n\n // Keep only last 100 resize events\n if (this.stats.cacheResizes.length > 100) {\n this.stats.cacheResizes.shift();\n }\n }\n\n /**\n * Evict excess items from cache\n * @private\n */\n evictExcessItems(cache, targetSize) {\n if (cache.size <= targetSize) {\n return;\n }\n\n const itemsToRemove = cache.size - targetSize;\n\n // If cache is a Map or has keys method\n if (cache.keys) {\n const keys = Array.from(cache.keys());\n for (let i = 0; i < itemsToRemove; i++) {\n cache.delete(keys[i]);\n }\n } else if (cache.clear) {\n // Last resort - clear the cache\n cache.clear();\n }\n }\n\n /**\n * Emergency clear all caches\n */\n emergencyClear() {\n for (const [name, cacheInfo] of this.caches) {\n if (cacheInfo.cache.clear) {\n cacheInfo.cache.clear();\n }\n // Reset to minimum capacity\n cacheInfo.currentCapacity = cacheInfo.minCapacity;\n }\n\n this.stats.emergencyClears++;\n console.warn('AdaptiveMemoryManager: Emergency cache clear triggered');\n }\n\n /**\n * Update cache access time\n * @param {string} name - Cache name\n */\n touchCache(name) {\n const cacheInfo = this.caches.get(name);\n if (cacheInfo) {\n cacheInfo.lastAccess = Date.now();\n }\n }\n\n /**\n * Get memory management statistics\n * @returns {Object} Statistics object\n */\n getStats() {\n const cacheStats = {};\n for (const [name, cacheInfo] of this.caches) {\n cacheStats[name] = {\n size: cacheInfo.cache.size || 0,\n capacity: cacheInfo.currentCapacity,\n priority: cacheInfo.priority,\n lastAccess: new Date(cacheInfo.lastAccess)\n };\n }\n\n return {\n ...this.stats,\n memoryUsagePercent: `${(this.stats.lastMemoryUsage * 100).toFixed(2)}%`,\n totalCaches: this.caches.size,\n cacheStats,\n monitoring: this.monitoringInterval !== null\n };\n }\n\n /**\n * Manual trigger for memory pressure check\n */\n async checkNow() {\n await this.checkMemoryPressure();\n }\n\n /**\n * Set memory thresholds\n * @param {Object} thresholds - New threshold values\n */\n setThresholds(thresholds) {\n if (thresholds.memoryThreshold !== undefined) {\n this.config.memoryThreshold = Math.max(0.5, Math.min(0.95, thresholds.memoryThreshold));\n }\n if (thresholds.criticalThreshold !== undefined) {\n this.config.criticalThreshold = Math.max(\n this.config.memoryThreshold + 0.05,\n Math.min(1.0, thresholds.criticalThreshold)\n );\n }\n }\n\n /**\n * Destroy manager and clean up\n */\n destroy() {\n this.stopMonitoring();\n this.caches.clear();\n }\n}\n","/**\n * PerformanceOptimizer - Optimizes calendar operations for large datasets\n * Includes caching, lazy loading, and batch processing with adaptive memory management\n */\n\nimport { LRUCache } from './LRUCache.js';\nimport { AdaptiveMemoryManager } from './AdaptiveMemoryManager.js';\n\nexport class PerformanceOptimizer {\n constructor(config = {}) {\n // Configuration\n this.config = {\n enableCache: true,\n cacheCapacity: 500,\n maxIndexDays: 365,\n batchSize: 100,\n enableMetrics: true,\n cleanupInterval: 3600000, // 1 hour in ms\n maxIndexAge: 30 * 24 * 60 * 60 * 1000, // 30 days in ms\n enableAdaptiveMemory: true, // Enable adaptive memory management\n ...config\n };\n\n // Caches with initial capacities\n this.eventCache = new LRUCache(this.config.cacheCapacity);\n this.queryCache = new LRUCache(Math.floor(this.config.cacheCapacity / 2));\n this.dateRangeCache = new LRUCache(Math.floor(this.config.cacheCapacity / 4));\n\n // Adaptive memory manager\n if (this.config.enableAdaptiveMemory) {\n this.memoryManager = new AdaptiveMemoryManager({\n checkInterval: 30000,\n memoryThreshold: 0.75,\n criticalThreshold: 0.9\n });\n\n // Register caches with memory manager\n this.memoryManager.registerCache('events', this.eventCache, {\n priority: 3, // Highest priority\n initialCapacity: this.config.cacheCapacity,\n minCapacity: 50,\n maxCapacity: 2000\n });\n\n this.memoryManager.registerCache('queries', this.queryCache, {\n priority: 2,\n initialCapacity: Math.floor(this.config.cacheCapacity / 2),\n minCapacity: 25,\n maxCapacity: 1000\n });\n\n this.memoryManager.registerCache('dateRanges', this.dateRangeCache, {\n priority: 1,\n initialCapacity: Math.floor(this.config.cacheCapacity / 4),\n minCapacity: 10,\n maxCapacity: 500\n });\n }\n\n // Lazy loading tracking\n this.lazyIndexes = new Map(); // eventId -> Set of date strings\n this.pendingIndexes = new Map(); // eventId -> Promise\n\n // Batch processing\n this.batchQueue = [];\n this.batchTimer = null;\n this.batchCallbacks = [];\n\n // Performance metrics\n this.metrics = {\n operations: {},\n averageTimes: {},\n slowQueries: []\n };\n\n // Cleanup timer\n this.cleanupTimer = null;\n if (this.config.cleanupInterval > 0) {\n this.startCleanupTimer();\n }\n }\n\n /**\n * Measure operation performance\n * @param {string} operation - Operation name\n * @param {Function} fn - Function to measure\n * @returns {*} Function result\n */\n measure(operation, fn) {\n if (!this.config.enableMetrics) {\n return fn();\n }\n\n const start = performance.now();\n try {\n const result = fn();\n const duration = performance.now() - start;\n this.recordMetric(operation, duration);\n return result;\n } catch (error) {\n const duration = performance.now() - start;\n this.recordMetric(operation, duration, true);\n throw error;\n }\n }\n\n /**\n * Measure async operation performance\n * @param {string} operation - Operation name\n * @param {Function} fn - Async function to measure\n * @returns {Promise<*>} Function result\n */\n async measureAsync(operation, fn) {\n if (!this.config.enableMetrics) {\n return await fn();\n }\n\n const start = performance.now();\n try {\n const result = await fn();\n const duration = performance.now() - start;\n this.recordMetric(operation, duration);\n return result;\n } catch (error) {\n const duration = performance.now() - start;\n this.recordMetric(operation, duration, true);\n throw error;\n }\n }\n\n /**\n * Record performance metric\n * @private\n */\n recordMetric(operation, duration, isError = false) {\n if (!this.metrics.operations[operation]) {\n this.metrics.operations[operation] = {\n count: 0,\n totalTime: 0,\n errors: 0,\n min: Infinity,\n max: 0\n };\n }\n\n const metric = this.metrics.operations[operation];\n metric.count++;\n metric.totalTime += duration;\n metric.min = Math.min(metric.min, duration);\n metric.max = Math.max(metric.max, duration);\n\n if (isError) {\n metric.errors++;\n }\n\n // Update average\n this.metrics.averageTimes[operation] = metric.totalTime / metric.count;\n\n // Track slow queries\n if (duration > 100) {\n this.metrics.slowQueries.push({\n operation,\n duration,\n timestamp: new Date(),\n isError\n });\n\n // Keep only last 100 slow queries\n if (this.metrics.slowQueries.length > 100) {\n this.metrics.slowQueries.shift();\n }\n }\n }\n\n /**\n * Get performance metrics\n * @returns {Object} Performance metrics\n */\n getMetrics() {\n const summary = {\n cacheStats: {\n event: this.eventCache.getStats(),\n query: this.queryCache.getStats(),\n dateRange: this.dateRangeCache.getStats()\n },\n operations: {},\n slowestOperations: [],\n recentSlowQueries: this.metrics.slowQueries.slice(-10),\n memoryManagement: this.memoryManager ? this.memoryManager.getStats() : null\n };\n\n // Process operations\n for (const [op, data] of Object.entries(this.metrics.operations)) {\n summary.operations[op] = {\n count: data.count,\n avgTime: `${(data.totalTime / data.count).toFixed(2)}ms`,\n minTime: `${data.min.toFixed(2)}ms`,\n maxTime: `${data.max.toFixed(2)}ms`,\n totalTime: `${data.totalTime.toFixed(2)}ms`,\n errors: data.errors,\n errorRate: `${((data.errors / data.count) * 100).toFixed(2)}%`\n };\n }\n\n // Find slowest operations\n summary.slowestOperations = Object.entries(this.metrics.averageTimes)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([op, time]) => ({\n operation: op,\n avgTime: `${time.toFixed(2)}ms`\n }));\n\n return summary;\n }\n\n /**\n * Check if event should use lazy indexing\n * @param {import('../events/Event.js').Event} event - Event to check\n * @returns {boolean} True if should use lazy indexing\n */\n shouldUseLazyIndexing(event) {\n const daySpan = Math.ceil((event.end - event.start) / (24 * 60 * 60 * 1000));\n return daySpan > this.config.maxIndexDays;\n }\n\n /**\n * Create lazy index markers for large events\n * @param {import('../events/Event.js').Event} event - Event to index\n * @returns {Object} Index boundaries\n */\n createLazyIndexMarkers(event) {\n const markers = {\n eventId: event.id,\n start: event.start,\n end: event.end,\n indexed: new Set(),\n pending: false\n };\n\n // Index first and last month only initially\n const startMonth = new Date(event.start.getFullYear(), event.start.getMonth(), 1);\n const endMonth = new Date(event.end.getFullYear(), event.end.getMonth(), 1);\n\n markers.indexed.add(this.getMonthKey(startMonth));\n if (this.getMonthKey(startMonth) !== this.getMonthKey(endMonth)) {\n markers.indexed.add(this.getMonthKey(endMonth));\n }\n\n this.lazyIndexes.set(event.id, markers);\n return markers;\n }\n\n /**\n * Expand lazy index for a specific date range\n * @param {string} eventId - Event ID\n * @param {Date} rangeStart - Start of range to index\n * @param {Date} rangeEnd - End of range to index\n * @returns {Promise<Set<string>>} Indexed date strings\n */\n async expandLazyIndex(eventId, rangeStart, rangeEnd) {\n const markers = this.lazyIndexes.get(eventId);\n if (!markers) {\n return new Set();\n }\n\n // Check if already pending\n if (markers.pending) {\n return this.pendingIndexes.get(eventId);\n }\n\n markers.pending = true;\n\n const promise = new Promise(resolve => {\n // Simulate async indexing (in real app, could be in worker)\n setTimeout(() => {\n const indexed = new Set();\n const current = new Date(rangeStart);\n\n while (current <= rangeEnd) {\n const dateStr = current.toDateString();\n if (!markers.indexed.has(dateStr)) {\n indexed.add(dateStr);\n markers.indexed.add(dateStr);\n }\n current.setDate(current.getDate() + 1);\n }\n\n markers.pending = false;\n this.pendingIndexes.delete(eventId);\n resolve(indexed);\n }, 0);\n });\n\n this.pendingIndexes.set(eventId, promise);\n return promise;\n }\n\n /**\n * Get month key for date\n * @private\n */\n getMonthKey(date) {\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n }\n\n /**\n * Cache event with TTL\n * @param {string} key - Cache key\n * @param {*} value - Value to cache\n * @param {string} cacheType - Type of cache to use\n */\n cache(key, value, cacheType = 'event') {\n if (!this.config.enableCache) return;\n\n let cache;\n let cacheManagerName;\n\n switch (cacheType) {\n case 'event':\n cache = this.eventCache;\n cacheManagerName = 'events';\n break;\n case 'query':\n cache = this.queryCache;\n cacheManagerName = 'queries';\n break;\n case 'dateRange':\n cache = this.dateRangeCache;\n cacheManagerName = 'dateRanges';\n break;\n default:\n return;\n }\n\n cache.put(key, value);\n\n // Update access time in memory manager\n if (this.memoryManager) {\n this.memoryManager.touchCache(cacheManagerName);\n }\n }\n\n /**\n * Get from cache\n * @param {string} key - Cache key\n * @param {string} cacheType - Type of cache\n * @returns {*} Cached value or undefined\n */\n getFromCache(key, cacheType = 'event') {\n if (!this.config.enableCache) return undefined;\n\n let result;\n let cacheManagerName;\n\n switch (cacheType) {\n case 'event':\n result = this.eventCache.get(key);\n cacheManagerName = 'events';\n break;\n case 'query':\n result = this.queryCache.get(key);\n cacheManagerName = 'queries';\n break;\n case 'dateRange':\n result = this.dateRangeCache.get(key);\n cacheManagerName = 'dateRanges';\n break;\n default:\n return undefined;\n }\n\n // Update access time on cache hit\n if (result !== undefined && this.memoryManager) {\n this.memoryManager.touchCache(cacheManagerName);\n }\n\n return result;\n }\n\n /**\n * Invalidate caches for an event\n * @param {string} eventId - Event ID\n */\n invalidateEventCaches(eventId) {\n // Remove from event cache\n this.eventCache.delete(eventId);\n\n // Clear query cache (conservative approach)\n // In production, track which queries include this event\n this.queryCache.clear();\n this.dateRangeCache.clear();\n }\n\n /**\n * Batch operation for efficiency\n * @param {Function} operation - Operation to batch\n * @returns {Promise} Batch result\n */\n batch(operation) {\n return new Promise((resolve, reject) => {\n this.batchQueue.push(operation);\n this.batchCallbacks.push({ resolve, reject });\n\n if (this.batchQueue.length >= this.config.batchSize) {\n this.processBatch();\n } else if (!this.batchTimer) {\n // Process batch after 10ms if not full\n this.batchTimer = setTimeout(() => this.processBatch(), 10);\n }\n });\n }\n\n /**\n * Process batched operations\n * @private\n */\n processBatch() {\n if (this.batchTimer) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n\n if (this.batchQueue.length === 0) return;\n\n const operations = this.batchQueue.splice(0);\n const callbacks = this.batchCallbacks.splice(0);\n\n // Process all operations\n const results = [];\n const errors = [];\n\n operations.forEach((op, index) => {\n try {\n results[index] = op();\n } catch (error) {\n errors[index] = error;\n }\n });\n\n // Resolve callbacks\n callbacks.forEach((callback, index) => {\n if (errors[index]) {\n callback.reject(errors[index]);\n } else {\n callback.resolve(results[index]);\n }\n });\n }\n\n /**\n * Start cleanup timer for old indexes\n * @private\n */\n startCleanupTimer() {\n this.cleanupTimer = setInterval(() => {\n this.cleanupOldIndexes();\n }, this.config.cleanupInterval);\n }\n\n /**\n * Clean up old indexes\n * @private\n */\n cleanupOldIndexes() {\n const now = Date.now();\n const maxAge = this.config.maxIndexAge;\n\n // Clean up lazy indexes for events that are too old\n for (const [eventId, markers] of this.lazyIndexes) {\n if (markers.end.getTime() < now - maxAge) {\n this.lazyIndexes.delete(eventId);\n }\n }\n\n // Clean up slow query log\n if (this.metrics.slowQueries.length > 100) {\n this.metrics.slowQueries = this.metrics.slowQueries.slice(-100);\n }\n }\n\n /**\n * Optimize query by checking cache first\n * @param {string} queryKey - Unique query identifier\n * @param {Function} queryFn - Function to execute if not cached\n * @returns {*} Query result\n */\n optimizeQuery(queryKey, queryFn) {\n // Check cache first\n const cached = this.getFromCache(queryKey, 'query');\n if (cached !== undefined) {\n return cached;\n }\n\n // Execute query and cache result\n const result = this.measure(`query:${queryKey}`, queryFn);\n this.cache(queryKey, result, 'query');\n return result;\n }\n\n /**\n * Destroy optimizer and clean up resources\n */\n destroy() {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = null;\n }\n\n if (this.batchTimer) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n\n this.eventCache.clear();\n this.queryCache.clear();\n this.dateRangeCache.clear();\n this.lazyIndexes.clear();\n this.pendingIndexes.clear();\n }\n}\n","/**\n * ConflictDetector - Detects scheduling conflicts between events\n * Checks for time overlaps, attendee conflicts, and resource conflicts\n */\n\nimport { DateUtils } from '../calendar/DateUtils.js';\n\nexport class ConflictDetector {\n /**\n * Create a new ConflictDetector\n * @param {import('../events/EventStore.js').EventStore} eventStore - Event store instance\n */\n constructor(eventStore) {\n this.eventStore = eventStore;\n this.conflictIdCounter = 0;\n }\n\n /**\n * Check for conflicts for a specific event\n * @param {import('../events/Event.js').Event|import('../../types.js').EventData} event - Event to check\n * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options\n * @returns {import('../../types.js').ConflictSummary} Conflict summary\n */\n checkConflicts(event, options = {}) {\n // Default options\n const opts = {\n checkAttendees: true,\n checkResources: true,\n checkLocation: true,\n ignoreAllDay: false,\n excludeEventIds: [],\n includeStatuses: ['confirmed', 'tentative'],\n bufferMinutes: 0,\n ...options\n };\n\n // Ensure we have an Event object\n if (!event.start || !event.end) {\n throw new Error('Event must have start and end dates');\n }\n\n const conflicts = [];\n const affectedEventIds = new Set();\n const affectedAttendees = new Set();\n\n // Get potential conflicting events in the time range\n const searchStart = new Date(event.start.getTime() - opts.bufferMinutes * 60000);\n const searchEnd = new Date(event.end.getTime() + opts.bufferMinutes * 60000);\n\n const potentialConflicts = this.eventStore\n .getEventsInRange(searchStart, searchEnd, false)\n .filter(e => {\n // Exclude self\n if (e.id === event.id) return false;\n // Exclude specified event IDs\n if (opts.excludeEventIds.includes(e.id)) return false;\n // Filter by status\n if (!opts.includeStatuses.includes(e.status)) return false;\n // Ignore all-day events if specified\n if (opts.ignoreAllDay && (e.allDay || event.allDay)) return false;\n // Ignore cancelled events\n if (e.status === 'cancelled') return false;\n return true;\n });\n\n // Check each potential conflict\n for (const conflictingEvent of potentialConflicts) {\n const eventConflicts = this._detectEventConflicts(event, conflictingEvent, opts);\n\n if (eventConflicts.length > 0) {\n conflicts.push(...eventConflicts);\n affectedEventIds.add(event.id);\n affectedEventIds.add(conflictingEvent.id);\n\n // Track affected attendees\n if (event.attendees) {\n event.attendees.forEach(a => affectedAttendees.add(a.email));\n }\n if (conflictingEvent.attendees) {\n conflictingEvent.attendees.forEach(a => affectedAttendees.add(a.email));\n }\n }\n }\n\n // Build summary\n return this._buildConflictSummary(conflicts, affectedEventIds, affectedAttendees);\n }\n\n /**\n * Check for conflicts between two specific events\n * @param {import('../events/Event.js').Event} event1 - First event\n * @param {import('../events/Event.js').Event} event2 - Second event\n * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options\n * @returns {import('../../types.js').ConflictDetails[]} Array of conflicts\n */\n checkEventPairConflicts(event1, event2, options = {}) {\n const opts = {\n checkAttendees: true,\n checkResources: true,\n checkLocation: true,\n bufferMinutes: 0,\n ...options\n };\n\n return this._detectEventConflicts(event1, event2, opts);\n }\n\n /**\n * Get busy periods for a set of attendees\n * @param {string[]} attendeeEmails - Attendee email addresses\n * @param {Date} start - Start of period\n * @param {Date} end - End of period\n * @param {Object} [options={}] - Options\n * @returns {Array<{start: Date, end: Date, eventIds: string[]}>} Busy periods\n */\n getBusyPeriods(attendeeEmails, start, end, options = {}) {\n const opts = {\n includeStatuses: ['confirmed', 'tentative'],\n mergePeriods: true,\n ...options\n };\n\n const busyPeriods = [];\n const events = this.eventStore.getEventsInRange(start, end, false);\n\n // Find events with these attendees\n const attendeeEvents = events.filter(event => {\n if (!opts.includeStatuses.includes(event.status)) return false;\n if (event.status === 'cancelled') return false;\n\n return (\n event.attendees && event.attendees.some(attendee => attendeeEmails.includes(attendee.email))\n );\n });\n\n // Convert to busy periods\n attendeeEvents.forEach(event => {\n busyPeriods.push({\n start: event.start,\n end: event.end,\n eventIds: [event.id]\n });\n });\n\n // Merge overlapping periods if requested\n if (opts.mergePeriods && busyPeriods.length > 1) {\n return this._mergeBusyPeriods(busyPeriods);\n }\n\n return busyPeriods.sort((a, b) => a.start - b.start);\n }\n\n /**\n * Get free time slots\n * @param {Date} start - Start of search period\n * @param {Date} end - End of search period\n * @param {number} duration - Required duration in minutes\n * @param {Object} [options={}] - Options\n * @returns {Array<{start: Date, end: Date}>} Free time slots\n */\n getFreePeriods(start, end, duration, options = {}) {\n const opts = {\n attendeeEmails: [],\n businessHoursOnly: false,\n businessHours: { start: '09:00', end: '17:00' },\n excludeWeekends: false,\n ...options\n };\n\n const freePeriods = [];\n\n // Get busy periods\n const busyPeriods =\n opts.attendeeEmails.length > 0\n ? this.getBusyPeriods(opts.attendeeEmails, start, end)\n : this._getAllBusyPeriods(start, end);\n\n // Find gaps between busy periods\n let currentTime = new Date(start);\n\n for (const busy of busyPeriods) {\n if (currentTime < busy.start) {\n // Found a gap\n const gapDuration = (busy.start - currentTime) / 60000; // minutes\n if (gapDuration >= duration) {\n // Check if within business hours if required\n if (\n !opts.businessHoursOnly ||\n this._isWithinBusinessHours(currentTime, busy.start, opts)\n ) {\n freePeriods.push({\n start: new Date(currentTime),\n end: new Date(busy.start)\n });\n }\n }\n }\n currentTime = new Date(Math.max(currentTime.getTime(), busy.end.getTime()));\n }\n\n // Check final period\n if (currentTime < end) {\n const gapDuration = (end - currentTime) / 60000;\n if (gapDuration >= duration) {\n if (!opts.businessHoursOnly || this._isWithinBusinessHours(currentTime, end, opts)) {\n freePeriods.push({\n start: new Date(currentTime),\n end: new Date(end)\n });\n }\n }\n }\n\n return freePeriods;\n }\n\n /**\n * Detect conflicts between two events\n * @private\n */\n _detectEventConflicts(event1, event2, options) {\n const conflicts = [];\n\n // Check time overlap with buffer\n const hasTimeOverlap = this._checkTimeOverlap(event1, event2, options.bufferMinutes);\n\n if (hasTimeOverlap) {\n // Time conflict\n const timeConflict = this._createTimeConflict(event1, event2);\n conflicts.push(timeConflict);\n\n // Check attendee conflicts (only if time overlaps)\n if (options.checkAttendees) {\n const attendeeConflicts = this._checkAttendeeConflicts(event1, event2);\n conflicts.push(...attendeeConflicts);\n }\n\n // Check resource conflicts (only if time overlaps)\n if (options.checkResources) {\n const resourceConflicts = this._checkResourceConflicts(event1, event2);\n conflicts.push(...resourceConflicts);\n }\n\n // Check location conflicts (only if time overlaps)\n if (options.checkLocation) {\n const locationConflict = this._checkLocationConflict(event1, event2);\n if (locationConflict) {\n conflicts.push(locationConflict);\n }\n }\n }\n\n return conflicts;\n }\n\n /**\n * Check for time overlap between events\n * @private\n */\n _checkTimeOverlap(event1, event2, bufferMinutes = 0) {\n const buffer = bufferMinutes * 60000; // Convert to milliseconds\n\n const start1 = event1.start.getTime() - buffer;\n const end1 = event1.end.getTime() + buffer;\n const start2 = event2.start.getTime();\n const end2 = event2.end.getTime();\n\n return !(end1 <= start2 || end2 <= start1);\n }\n\n /**\n * Create time conflict details\n * @private\n */\n _createTimeConflict(event1, event2) {\n const overlapStart = new Date(Math.max(event1.start.getTime(), event2.start.getTime()));\n const overlapEnd = new Date(Math.min(event1.end.getTime(), event2.end.getTime()));\n const overlapMinutes = (overlapEnd - overlapStart) / 60000;\n\n // Determine severity based on overlap duration and event importance\n let severity = 'low';\n if (overlapMinutes >= 60) {\n severity = 'high';\n } else if (overlapMinutes >= 30) {\n severity = 'medium';\n }\n\n // Increase severity for confirmed events\n if (event1.status === 'confirmed' && event2.status === 'confirmed') {\n severity = severity === 'low' ? 'medium' : severity === 'medium' ? 'high' : 'critical';\n }\n\n return {\n id: `conflict_${++this.conflictIdCounter}`,\n type: 'time',\n severity,\n eventId: event1.id,\n conflictingEventId: event2.id,\n description: `Time overlap: ${event1.title} conflicts with ${event2.title}`,\n overlapStart,\n overlapEnd,\n overlapMinutes,\n metadata: {\n event1Title: event1.title,\n event2Title: event2.title,\n event1Status: event1.status,\n event2Status: event2.status\n }\n };\n }\n\n /**\n * Check for attendee conflicts\n * @private\n */\n _checkAttendeeConflicts(event1, event2) {\n const conflicts = [];\n\n if (!event1.attendees || !event2.attendees) {\n return conflicts;\n }\n\n const conflictingAttendees = [];\n\n for (const attendee1 of event1.attendees) {\n for (const attendee2 of event2.attendees) {\n if (attendee1.email === attendee2.email) {\n // Same attendee in both events\n conflictingAttendees.push(attendee1.email);\n }\n }\n }\n\n if (conflictingAttendees.length > 0) {\n // Determine severity based on attendee responses\n let severity = 'medium';\n\n // Check if any conflicting attendee has accepted both\n const hasAcceptedBoth = conflictingAttendees.some(email => {\n const a1 = event1.attendees.find(a => a.email === email);\n const a2 = event2.attendees.find(a => a.email === email);\n return a1?.responseStatus === 'accepted' && a2?.responseStatus === 'accepted';\n });\n\n if (hasAcceptedBoth) {\n severity = 'critical';\n }\n\n conflicts.push({\n id: `conflict_${++this.conflictIdCounter}`,\n type: 'attendee',\n severity,\n eventId: event1.id,\n conflictingEventId: event2.id,\n description: `Attendee conflict: ${conflictingAttendees.length} attendee(s) double-booked`,\n conflictingAttendees,\n metadata: {\n attendeeCount: conflictingAttendees.length,\n attendeeEmails: conflictingAttendees\n }\n });\n }\n\n return conflicts;\n }\n\n /**\n * Check for resource conflicts\n * @private\n */\n _checkResourceConflicts(event1, event2) {\n const conflicts = [];\n\n // Check if events have resource attendees\n const resources1 = event1.attendees?.filter(a => a.resource) || [];\n const resources2 = event2.attendees?.filter(a => a.resource) || [];\n\n for (const resource1 of resources1) {\n for (const resource2 of resources2) {\n if (resource1.email === resource2.email) {\n conflicts.push({\n id: `conflict_${++this.conflictIdCounter}`,\n type: 'resource',\n severity: 'critical', // Resource conflicts are always critical\n eventId: event1.id,\n conflictingEventId: event2.id,\n description: `Resource conflict: ${resource1.name} is double-booked`,\n conflictingResource: resource1.email,\n metadata: {\n resourceName: resource1.name,\n resourceEmail: resource1.email\n }\n });\n }\n }\n }\n\n return conflicts;\n }\n\n /**\n * Check for location conflicts\n * @private\n */\n _checkLocationConflict(event1, event2) {\n if (!event1.location || !event2.location) {\n return null;\n }\n\n // Normalize locations for comparison\n const loc1 = event1.location.trim().toLowerCase();\n const loc2 = event2.location.trim().toLowerCase();\n\n if (loc1 === loc2) {\n return {\n id: `conflict_${++this.conflictIdCounter}`,\n type: 'location',\n severity: 'high', // Location conflicts are typically high severity\n eventId: event1.id,\n conflictingEventId: event2.id,\n description: `Location conflict: ${event1.location} is double-booked`,\n metadata: {\n location: event1.location\n }\n };\n }\n\n return null;\n }\n\n /**\n * Build conflict summary\n * @private\n */\n _buildConflictSummary(conflicts, affectedEventIds, affectedAttendees) {\n const conflictsByType = {};\n const conflictsBySeverity = {};\n\n // Count by type and severity\n for (const conflict of conflicts) {\n conflictsByType[conflict.type] = (conflictsByType[conflict.type] || 0) + 1;\n conflictsBySeverity[conflict.severity] = (conflictsBySeverity[conflict.severity] || 0) + 1;\n }\n\n return {\n hasConflicts: conflicts.length > 0,\n totalConflicts: conflicts.length,\n conflicts,\n conflictsByType,\n conflictsBySeverity,\n affectedEventIds: Array.from(affectedEventIds),\n affectedAttendees: Array.from(affectedAttendees)\n };\n }\n\n /**\n * Merge overlapping busy periods\n * @private\n */\n _mergeBusyPeriods(periods) {\n if (periods.length <= 1) return periods;\n\n // Sort by start time\n periods.sort((a, b) => a.start - b.start);\n\n const merged = [periods[0]];\n\n for (let i = 1; i < periods.length; i++) {\n const current = periods[i];\n const last = merged[merged.length - 1];\n\n if (current.start <= last.end) {\n // Overlapping or adjacent, merge them\n last.end = new Date(Math.max(last.end.getTime(), current.end.getTime()));\n last.eventIds.push(...current.eventIds);\n } else {\n // No overlap, add as new period\n merged.push(current);\n }\n }\n\n return merged;\n }\n\n /**\n * Get all busy periods\n * @private\n */\n _getAllBusyPeriods(start, end) {\n const events = this.eventStore\n .getEventsInRange(start, end, false)\n .filter(e => e.status !== 'cancelled');\n\n return events\n .map(event => ({\n start: event.start,\n end: event.end,\n eventIds: [event.id]\n }))\n .sort((a, b) => a.start - b.start);\n }\n\n /**\n * Check if time period is within business hours\n * @private\n */\n _isWithinBusinessHours(start, end, options) {\n // Simple implementation - can be enhanced\n const startHour = start.getHours();\n const endHour = end.getHours();\n\n const businessStart = parseInt(options.businessHours.start.split(':')[0]);\n const businessEnd = parseInt(options.businessHours.end.split(':')[0]);\n\n return startHour >= businessStart && endHour <= businessEnd;\n }\n}\n","import { Event } from './Event.js';\nimport { DateUtils } from '../calendar/DateUtils.js';\nimport { RecurrenceEngine } from './RecurrenceEngine.js';\nimport { PerformanceOptimizer } from '../performance/PerformanceOptimizer.js';\nimport { ConflictDetector } from '../conflicts/ConflictDetector.js';\nimport { TimezoneManager } from '../timezone/TimezoneManager.js';\n\n/**\n * EventStore - Manages calendar events with efficient querying\n * Uses Map for O(1) lookups and spatial indexing concepts for date queries\n * Now with performance optimizations for large datasets\n */\nexport class EventStore {\n constructor(config = {}) {\n // Primary storage - Map for O(1) ID lookups\n /** @type {Map<string, Event>} */\n this.events = new Map();\n\n // Indices for efficient queries (using UTC for consistent indexing)\n this.indices = {\n /** @type {Map<string, Set<string>>} UTC Date string -> Set of event IDs */\n byDate: new Map(),\n /** @type {Map<string, Set<string>>} YYYY-MM (UTC) -> Set of event IDs */\n byMonth: new Map(),\n /** @type {Set<string>} Set of recurring event IDs */\n recurring: new Set(),\n /** @type {Map<string, Set<string>>} Category -> Set of event IDs */\n byCategory: new Map(),\n /** @type {Map<string, Set<string>>} Status -> Set of event IDs */\n byStatus: new Map()\n };\n\n // Timezone manager for conversions (use singleton to share cache)\n this.timezoneManager = TimezoneManager.getInstance();\n\n // Default timezone for the store (can be overridden)\n this.defaultTimezone = config.timezone || this.timezoneManager.getSystemTimezone();\n\n // Performance optimizer\n this.optimizer = new PerformanceOptimizer(config.performance);\n\n // Conflict detector\n this.conflictDetector = new ConflictDetector(this);\n\n // Batch operation state\n this.isBatchMode = false;\n this.batchNotifications = [];\n this.batchBackup = null; // For rollback support\n\n // Change tracking\n /** @type {number} */\n this.version = 0;\n /** @type {Set<import('../../types.js').EventListener>} */\n this.listeners = new Set();\n }\n\n /**\n * Add an event to the store\n * @param {Event|import('../../types.js').EventData} event - The event to add\n * @returns {Event} The added event\n * @throws {Error} If event with same ID already exists\n */\n addEvent(event) {\n return this.optimizer.measure('addEvent', () => {\n if (!(event instanceof Event)) {\n event = new Event(event);\n }\n\n if (this.events.has(event.id)) {\n throw new Error(`Event with id ${event.id} already exists`);\n }\n\n // Store the event\n this.events.set(event.id, event);\n\n // Cache the event\n this.optimizer.cache(event.id, event, 'event');\n\n // Update indices\n this._indexEvent(event);\n\n // Notify listeners (batch if in batch mode)\n if (this.isBatchMode) {\n this.batchNotifications.push({\n type: 'add',\n event,\n version: ++this.version\n });\n } else {\n this._notifyChange({\n type: 'add',\n event,\n version: ++this.version\n });\n }\n\n return event;\n });\n }\n\n /**\n * Update an existing event\n * @param {string} eventId - The event ID\n * @param {Partial<import('../../types.js').EventData>} updates - Properties to update\n * @returns {Event} The updated event\n * @throws {Error} If event not found\n */\n updateEvent(eventId, updates) {\n const existingEvent = this.events.get(eventId);\n if (!existingEvent) {\n throw new Error(`Event with id ${eventId} not found`);\n }\n\n // Remove old indices\n this._unindexEvent(existingEvent);\n\n // Create updated event\n const updatedEvent = existingEvent.clone(updates);\n\n // Store updated event\n this.events.set(eventId, updatedEvent);\n\n // Re-index\n this._indexEvent(updatedEvent);\n\n // Notify listeners\n this._notifyChange({\n type: 'update',\n event: updatedEvent,\n oldEvent: existingEvent,\n version: ++this.version\n });\n\n return updatedEvent;\n }\n\n /**\n * Remove an event from the store\n * @param {string} eventId - The event ID to remove\n * @returns {boolean} True if removed, false if not found\n */\n removeEvent(eventId) {\n const event = this.events.get(eventId);\n if (!event) {\n return false;\n }\n\n // Remove from primary storage\n this.events.delete(eventId);\n\n // Remove from indices\n this._unindexEvent(event);\n\n // Notify listeners\n this._notifyChange({\n type: 'remove',\n event,\n version: ++this.version\n });\n\n return true;\n }\n\n /**\n * Get an event by ID\n * @param {string} eventId - The event ID\n * @returns {Event|null} The event or null if not found\n */\n getEvent(eventId) {\n // Check cache first\n const cached = this.optimizer.getFromCache(eventId, 'event');\n if (cached) {\n return cached;\n }\n\n // Get from store\n const event = this.events.get(eventId) || null;\n\n // Cache if found\n if (event) {\n this.optimizer.cache(eventId, event, 'event');\n }\n\n return event;\n }\n\n /**\n * Get all events\n * @returns {Event[]} Array of all events\n */\n getAllEvents() {\n return Array.from(this.events.values());\n }\n\n /**\n * Query events with filters\n * @param {import('../../types.js').QueryFilters} [filters={}] - Query filters\n * @returns {Event[]} Filtered events\n */\n queryEvents(filters = {}) {\n let results = Array.from(this.events.values());\n\n // Filter by date range\n if (filters.start || filters.end) {\n const start = filters.start ? new Date(filters.start) : null;\n const end = filters.end ? new Date(filters.end) : null;\n\n results = results.filter(event => {\n if (start && event.end < start) return false;\n if (end && event.start > end) return false;\n return true;\n });\n }\n\n // Filter by specific date\n if (filters.date) {\n const date = new Date(filters.date);\n results = results.filter(event => event.occursOn(date));\n }\n\n // Filter by month\n if (filters.month && filters.year) {\n const monthKey = `${filters.year}-${String(filters.month).padStart(2, '0')}`;\n const eventIds = this.indices.byMonth.get(monthKey) || new Set();\n results = results.filter(event => eventIds.has(event.id));\n }\n\n // Filter by all-day events\n if (Object.prototype.hasOwnProperty.call(filters, 'allDay')) {\n results = results.filter(event => event.allDay === filters.allDay);\n }\n\n // Filter by recurring\n if (Object.prototype.hasOwnProperty.call(filters, 'recurring')) {\n results = results.filter(event => event.recurring === filters.recurring);\n }\n\n // Filter by status\n if (filters.status) {\n results = results.filter(event => event.status === filters.status);\n }\n\n // Filter by categories\n if (filters.categories && filters.categories.length > 0) {\n results = results.filter(event =>\n filters.matchAllCategories\n ? event.hasAllCategories(filters.categories)\n : event.hasAnyCategory(filters.categories)\n );\n }\n\n // Filter by having attendees\n if (Object.prototype.hasOwnProperty.call(filters, 'hasAttendees')) {\n results = results.filter(event =>\n filters.hasAttendees ? event.hasAttendees : !event.hasAttendees\n );\n }\n\n // Filter by organizer email\n if (filters.organizerEmail) {\n results = results.filter(\n event => event.organizer && event.organizer.email === filters.organizerEmail\n );\n }\n\n // Sort results\n if (filters.sort) {\n results.sort((a, b) => {\n switch (filters.sort) {\n case 'start':\n return a.start - b.start;\n case 'end':\n return a.end - b.end;\n case 'duration':\n return a.duration - b.duration;\n case 'title':\n return a.title.localeCompare(b.title);\n default:\n return 0;\n }\n });\n }\n\n return results;\n }\n\n /**\n * Get events for a specific date\n * @param {Date} date - The date to query\n * @param {string} [timezone] - Timezone for the query (defaults to store timezone)\n * @returns {Event[]} Events occurring on the date, sorted by start time\n */\n getEventsForDate(date, timezone = null) {\n timezone = timezone || this.defaultTimezone;\n\n // Use local date string for the query date (in the calendar's timezone)\n const dateStr = DateUtils.getLocalDateString(date);\n\n // Collect candidate event IDs from indices\n const candidateIds = new Set();\n\n // Check byDate index for nearby dates (handles most events)\n const checkDate = new Date(date);\n for (let offset = -1; offset <= 1; offset++) {\n const tempDate = new Date(checkDate);\n tempDate.setDate(tempDate.getDate() + offset);\n const tempDateStr = DateUtils.getLocalDateString(tempDate);\n const eventIds = this.indices.byDate.get(tempDateStr);\n if (eventIds) {\n eventIds.forEach(id => candidateIds.add(id));\n }\n }\n\n // Also check byMonth index to catch long-running events that might not be\n // indexed in byDate for this specific date (lazy indexing only indexes\n // first/last week of multi-week events)\n const monthKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n const monthEventIds = this.indices.byMonth.get(monthKey);\n if (monthEventIds) {\n monthEventIds.forEach(id => candidateIds.add(id));\n }\n\n // Filter candidates to events that actually overlap with the requested date\n const allEvents = [];\n const startOfDay = new Date(date);\n startOfDay.setHours(0, 0, 0, 0);\n const endOfDay = new Date(date);\n endOfDay.setHours(23, 59, 59, 999);\n\n for (const id of candidateIds) {\n const event = this.events.get(id);\n if (event) {\n // Check if event actually occurs on the requested date in the given timezone\n const eventStartLocal = event.getStartInTimezone(timezone);\n const eventEndLocal = event.getEndInTimezone(timezone);\n\n // Event overlaps with this day if it starts before end of day and ends after start of day\n if (eventStartLocal <= endOfDay && eventEndLocal >= startOfDay) {\n allEvents.push(event);\n }\n }\n }\n\n return allEvents.sort((a, b) => {\n // Sort by start time in the specified timezone\n const aStart = a.getStartInTimezone(timezone);\n const bStart = b.getStartInTimezone(timezone);\n const timeCompare = aStart - bStart;\n if (timeCompare !== 0) return timeCompare;\n return b.duration - a.duration; // Longer events first\n });\n }\n\n /**\n * Get events that overlap with a given time range\n * @param {Date} start - Start time\n * @param {Date} end - End time\n * @param {string} [excludeId=null] - Optional event ID to exclude (useful when checking for conflicts)\n * @returns {Event[]} Array of overlapping events\n */\n getOverlappingEvents(start, end, excludeId = null) {\n const overlapping = [];\n\n // Get all events in the date range\n const startDate = DateUtils.startOfDay(start);\n const endDate = DateUtils.endOfDay(end);\n const dates = DateUtils.getDateRange(startDate, endDate);\n\n // Collect all events from those dates\n const checkedIds = new Set();\n dates.forEach(date => {\n // Use getLocalDateString to match the index key format (YYYY-MM-DD)\n const dateStr = DateUtils.getLocalDateString(date);\n const eventIds = this.indices.byDate.get(dateStr) || new Set();\n\n eventIds.forEach(id => {\n if (!checkedIds.has(id) && id !== excludeId) {\n checkedIds.add(id);\n const event = this.events.get(id);\n\n if (event && event.overlaps({ start, end })) {\n overlapping.push(event);\n }\n }\n });\n });\n\n return overlapping.sort((a, b) => a.start - b.start);\n }\n\n /**\n * Check if an event would conflict with existing events\n * @param {Date} start - Start time\n * @param {Date} end - End time\n * @param {string} excludeId - Optional event ID to exclude\n * @returns {boolean} True if there are conflicts\n */\n hasConflicts(start, end, excludeId = null) {\n return this.getOverlappingEvents(start, end, excludeId).length > 0;\n }\n\n /**\n * Get events grouped by overlapping time slots\n * Useful for calculating event positions in week/day views\n * @param {Date} date - The date to analyze\n * @param {boolean} timedOnly - Only include timed events (not all-day)\n * @returns {Array<Event[]>} Array of event groups that overlap\n */\n getOverlapGroups(date, timedOnly = true) {\n let events = this.getEventsForDate(date);\n\n if (timedOnly) {\n events = events.filter(e => !e.allDay);\n }\n\n const groups = [];\n const processed = new Set();\n\n events.forEach(event => {\n if (processed.has(event.id)) return;\n\n // Start a new group with this event\n const group = [event];\n processed.add(event.id);\n\n // Find all events that overlap with any event in this group\n let i = 0;\n while (i < group.length) {\n const currentEvent = group[i];\n\n events.forEach(otherEvent => {\n if (!processed.has(otherEvent.id) && currentEvent.overlaps(otherEvent)) {\n group.push(otherEvent);\n processed.add(otherEvent.id);\n }\n });\n\n i++;\n }\n\n groups.push(group);\n });\n\n return groups;\n }\n\n /**\n * Calculate positions for overlapping events (for rendering)\n * @param {Event[]} events - Array of overlapping events\n * @returns {Map<string, {column: number, totalColumns: number}>} Position data for each event\n */\n calculateEventPositions(events) {\n const positions = new Map();\n\n if (events.length === 0) return positions;\n\n // Sort by start time, then by duration (longer events first)\n events.sort((a, b) => {\n const startDiff = a.start - b.start;\n if (startDiff !== 0) return startDiff;\n return b.end - b.start - (a.end - a.start);\n });\n\n // Track which columns are occupied at each time\n const columns = [];\n\n events.forEach(event => {\n // Find the first available column\n let column = 0;\n while (column < columns.length) {\n const columnEvents = columns[column];\n const hasConflict = columnEvents.some(e => e.overlaps(event));\n\n if (!hasConflict) {\n break;\n }\n column++;\n }\n\n // Add event to the column\n if (!columns[column]) {\n columns[column] = [];\n }\n columns[column].push(event);\n\n positions.set(event.id, {\n column: column,\n totalColumns: 0 // Will be updated after all events are placed\n });\n });\n\n // Update total columns for all events\n const totalColumns = columns.length;\n positions.forEach(pos => {\n pos.totalColumns = totalColumns;\n });\n\n return positions;\n }\n\n /**\n * Get events for a date range\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @param {boolean|string} expandRecurring - Whether to expand recurring events, or timezone string\n * @param {string} [timezone] - Timezone for the query (if expandRecurring is boolean)\n * @returns {Event[]}\n */\n getEventsInRange(start, end, expandRecurring = true, timezone = null) {\n // Handle overloaded parameters\n if (typeof expandRecurring === 'string') {\n timezone = expandRecurring;\n expandRecurring = true;\n }\n\n timezone = timezone || this.defaultTimezone;\n\n // Convert range to UTC for querying\n const startUTC = this.timezoneManager.toUTC(start, timezone);\n const endUTC = this.timezoneManager.toUTC(end, timezone);\n\n // Query using UTC times\n const baseEvents = this.queryEvents({\n start: startUTC,\n end: endUTC,\n sort: 'start'\n });\n\n if (!expandRecurring) {\n return baseEvents;\n }\n\n // Expand recurring events\n const expandedEvents = [];\n baseEvents.forEach(event => {\n if (event.recurring && event.recurrenceRule) {\n const occurrences = this.expandRecurringEvent(event, start, end, timezone);\n expandedEvents.push(...occurrences);\n } else {\n expandedEvents.push(event);\n }\n });\n\n return expandedEvents.sort((a, b) => {\n // Sort by start time in the specified timezone\n const aStart = a.getStartInTimezone(timezone);\n const bStart = b.getStartInTimezone(timezone);\n return aStart - bStart;\n });\n }\n\n /**\n * Expand a recurring event into individual occurrences\n * @param {Event} event - The recurring event\n * @param {Date} rangeStart - Start of the expansion range\n * @param {Date} rangeEnd - End of the expansion range\n * @param {string} [timezone] - Timezone for the expansion\n * @returns {Event[]} Array of event occurrences\n */\n expandRecurringEvent(event, rangeStart, rangeEnd, timezone = null) {\n if (!event.recurring || !event.recurrenceRule) {\n return [event];\n }\n\n timezone = timezone || this.defaultTimezone;\n\n // Expand in the event's timezone for accurate recurrence calculation\n const eventTimezone = event.timeZone || timezone;\n const occurrences = RecurrenceEngine.expandEvent(event, rangeStart, rangeEnd);\n\n return occurrences.map((occurrence, index) => {\n // Create a new event instance for each occurrence\n const occurrenceEvent = event.clone({\n id: `${event.id}_occurrence_${index}`,\n start: occurrence.start,\n end: occurrence.end,\n timeZone: eventTimezone,\n metadata: {\n ...event.metadata,\n recurringEventId: event.id,\n occurrenceIndex: index\n }\n });\n\n return occurrenceEvent;\n });\n }\n\n /**\n * Clear all events\n */\n clear() {\n const oldEvents = this.getAllEvents();\n\n this.events.clear();\n this.indices.byDate.clear();\n this.indices.byMonth.clear();\n this.indices.recurring.clear();\n\n this._notifyChange({\n type: 'clear',\n oldEvents,\n version: ++this.version\n });\n }\n\n /**\n * Bulk load events\n * @param {Event[]} events - Array of events or event data\n */\n loadEvents(events) {\n this.clear();\n\n for (const eventData of events) {\n this.addEvent(eventData);\n }\n }\n\n /**\n * Subscribe to store changes\n * @param {Function} callback - Callback function\n * @returns {Function} Unsubscribe function\n */\n subscribe(callback) {\n this.listeners.add(callback);\n\n return () => {\n this.listeners.delete(callback);\n };\n }\n\n /**\n * Index an event for efficient queries\n * @private\n */\n _indexEvent(event) {\n // Check if should use lazy indexing for large date ranges\n if (this.optimizer.shouldUseLazyIndexing(event)) {\n this._indexEventLazy(event);\n return;\n }\n\n // Index by local dates in the event's timezone\n // This ensures events appear on the correct calendar day\n const eventStartLocal = event.getStartInTimezone(event.timeZone);\n const eventEndLocal = event.getEndInTimezone(event.endTimeZone || event.timeZone);\n\n const startDate = DateUtils.startOfDay(eventStartLocal);\n const endDate = DateUtils.endOfDay(eventEndLocal);\n\n // For each day the event spans (in local time), add to date index\n const dates = DateUtils.getDateRange(startDate, endDate);\n\n dates.forEach(date => {\n const dateStr = DateUtils.getLocalDateString(date);\n\n if (!this.indices.byDate.has(dateStr)) {\n this.indices.byDate.set(dateStr, new Set());\n }\n this.indices.byDate.get(dateStr).add(event.id);\n });\n\n // Index by month(s) using UTC\n const startMonth = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}`;\n const endMonth = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}`;\n\n // Add to all months the event spans\n const currentMonth = new Date(startDate.getFullYear(), startDate.getMonth(), 1);\n while (currentMonth <= endDate) {\n const monthKey = `${currentMonth.getFullYear()}-${String(currentMonth.getMonth() + 1).padStart(2, '0')}`;\n\n if (!this.indices.byMonth.has(monthKey)) {\n this.indices.byMonth.set(monthKey, new Set());\n }\n this.indices.byMonth.get(monthKey).add(event.id);\n\n currentMonth.setMonth(currentMonth.getMonth() + 1);\n }\n\n // Index by categories\n if (event.categories && event.categories.length > 0) {\n event.categories.forEach(category => {\n if (!this.indices.byCategory.has(category)) {\n this.indices.byCategory.set(category, new Set());\n }\n this.indices.byCategory.get(category).add(event.id);\n });\n }\n\n // Index by status\n if (event.status) {\n if (!this.indices.byStatus.has(event.status)) {\n this.indices.byStatus.set(event.status, new Set());\n }\n this.indices.byStatus.get(event.status).add(event.id);\n }\n\n // Index recurring events\n if (event.recurring) {\n this.indices.recurring.add(event.id);\n }\n }\n\n /**\n * Lazy index for events with large date ranges\n * @private\n */\n _indexEventLazy(event) {\n // Create lazy index markers\n const markers = this.optimizer.createLazyIndexMarkers(event);\n\n // Index only the boundaries initially (in event's local timezone)\n const eventStartLocal = event.getStartInTimezone(event.timeZone);\n const eventEndLocal = event.getEndInTimezone(event.endTimeZone || event.timeZone);\n\n const startDate = DateUtils.startOfDay(eventStartLocal);\n const endDate = DateUtils.endOfDay(eventEndLocal);\n\n // Index first week\n const firstWeekEnd = new Date(startDate);\n firstWeekEnd.setDate(firstWeekEnd.getDate() + 7);\n const firstWeekDates = DateUtils.getDateRange(\n startDate,\n firstWeekEnd < endDate ? firstWeekEnd : endDate\n );\n\n firstWeekDates.forEach(date => {\n const dateStr = DateUtils.getLocalDateString(date);\n if (!this.indices.byDate.has(dateStr)) {\n this.indices.byDate.set(dateStr, new Set());\n }\n this.indices.byDate.get(dateStr).add(event.id);\n });\n\n // Index last week if different from first\n if (endDate > firstWeekEnd) {\n const lastWeekStart = new Date(endDate);\n lastWeekStart.setDate(lastWeekStart.getDate() - 7);\n const lastWeekDates = DateUtils.getDateRange(\n lastWeekStart > startDate ? lastWeekStart : startDate,\n endDate\n );\n\n lastWeekDates.forEach(date => {\n const dateStr = DateUtils.getLocalDateString(date);\n if (!this.indices.byDate.has(dateStr)) {\n this.indices.byDate.set(dateStr, new Set());\n }\n this.indices.byDate.get(dateStr).add(event.id);\n });\n }\n\n // Index months as normal\n const currentMonth = new Date(startDate.getFullYear(), startDate.getMonth(), 1);\n while (currentMonth <= endDate) {\n const monthKey = `${currentMonth.getFullYear()}-${String(currentMonth.getMonth() + 1).padStart(2, '0')}`;\n if (!this.indices.byMonth.has(monthKey)) {\n this.indices.byMonth.set(monthKey, new Set());\n }\n this.indices.byMonth.get(monthKey).add(event.id);\n currentMonth.setMonth(currentMonth.getMonth() + 1);\n }\n\n // Index other properties normally\n if (event.categories && event.categories.length > 0) {\n event.categories.forEach(category => {\n if (!this.indices.byCategory.has(category)) {\n this.indices.byCategory.set(category, new Set());\n }\n this.indices.byCategory.get(category).add(event.id);\n });\n }\n\n if (event.status) {\n if (!this.indices.byStatus.has(event.status)) {\n this.indices.byStatus.set(event.status, new Set());\n }\n this.indices.byStatus.get(event.status).add(event.id);\n }\n\n if (event.recurring) {\n this.indices.recurring.add(event.id);\n }\n }\n\n /**\n * Remove event from indices\n * @private\n */\n _unindexEvent(event) {\n // Remove from date indices\n for (const [dateStr, eventIds] of this.indices.byDate) {\n eventIds.delete(event.id);\n if (eventIds.size === 0) {\n this.indices.byDate.delete(dateStr);\n }\n }\n\n // Remove from month indices\n for (const [monthKey, eventIds] of this.indices.byMonth) {\n eventIds.delete(event.id);\n if (eventIds.size === 0) {\n this.indices.byMonth.delete(monthKey);\n }\n }\n\n // Remove from recurring index\n this.indices.recurring.delete(event.id);\n }\n\n /**\n * Notify listeners of changes\n * @private\n */\n _notifyChange(change) {\n for (const listener of this.listeners) {\n try {\n listener(change);\n } catch (error) {\n console.error('Error in EventStore listener:', error);\n }\n }\n }\n\n /**\n * Get store statistics\n * @returns {Object}\n */\n getStats() {\n return {\n totalEvents: this.events.size,\n recurringEvents: this.indices.recurring.size,\n indexedDates: this.indices.byDate.size,\n indexedMonths: this.indices.byMonth.size,\n indexedCategories: this.indices.byCategory.size,\n indexedStatuses: this.indices.byStatus.size,\n version: this.version,\n performanceMetrics: this.optimizer.getMetrics()\n };\n }\n\n // ============ Batch Operations ============\n\n /**\n * Start batch mode for bulk operations\n * Delays notifications until batch is committed\n * @param {boolean} [enableRollback=false] - Enable rollback support (creates backup)\n */\n startBatch(enableRollback = false) {\n this.isBatchMode = true;\n this.batchNotifications = [];\n\n // Create backup for rollback if requested\n if (enableRollback) {\n this.batchBackup = {\n events: new Map(this.events),\n indices: {\n byDate: new Map(\n Array.from(this.indices.byDate.entries()).map(([k, v]) => [k, new Set(v)])\n ),\n byMonth: new Map(\n Array.from(this.indices.byMonth.entries()).map(([k, v]) => [k, new Set(v)])\n ),\n recurring: new Set(this.indices.recurring),\n byCategory: new Map(\n Array.from(this.indices.byCategory.entries()).map(([k, v]) => [k, new Set(v)])\n ),\n byStatus: new Map(\n Array.from(this.indices.byStatus.entries()).map(([k, v]) => [k, new Set(v)])\n )\n },\n version: this.version\n };\n }\n }\n\n /**\n * Commit batch operations\n * Sends all notifications at once\n */\n commitBatch() {\n if (!this.isBatchMode) return;\n\n this.isBatchMode = false;\n\n // Clear backup after successful commit\n this.batchBackup = null;\n\n // Send a single bulk notification\n if (this.batchNotifications.length > 0) {\n this._notifyChange({\n type: 'batch',\n changes: this.batchNotifications,\n count: this.batchNotifications.length,\n version: ++this.version\n });\n }\n\n this.batchNotifications = [];\n }\n\n /**\n * Rollback batch operations\n * Restores state to before batch started\n */\n rollbackBatch() {\n if (!this.isBatchMode) return;\n\n this.isBatchMode = false;\n\n // Restore backup if available\n if (this.batchBackup) {\n this.events = this.batchBackup.events;\n this.indices = this.batchBackup.indices;\n this.version = this.batchBackup.version;\n this.batchBackup = null;\n\n // Clear cache\n this.optimizer.clearCache();\n }\n\n this.batchNotifications = [];\n }\n\n /**\n * Execute batch operation with automatic rollback on error\n * @param {Function} operation - Operation to execute\n * @param {boolean} [enableRollback=true] - Enable automatic rollback on error\n * @returns {*} Result of operation\n * @throws {Error} If operation fails\n */\n async executeBatch(operation, enableRollback = true) {\n this.startBatch(enableRollback);\n\n try {\n const result = await operation();\n this.commitBatch();\n return result;\n } catch (error) {\n if (enableRollback) {\n this.rollbackBatch();\n }\n throw error;\n }\n }\n\n /**\n * Add multiple events in batch\n * @param {Array<Event|import('../../types.js').EventData>} events - Events to add\n * @returns {Event[]} Added events\n */\n addEvents(events) {\n return this.optimizer.measure('addEvents', () => {\n this.startBatch();\n const results = [];\n const errors = [];\n\n for (const eventData of events) {\n try {\n results.push(this.addEvent(eventData));\n } catch (error) {\n errors.push({ event: eventData, error: error.message });\n }\n }\n\n this.commitBatch();\n\n if (errors.length > 0) {\n console.warn(`Failed to add ${errors.length} events:`, errors);\n }\n\n return results;\n });\n }\n\n /**\n * Update multiple events in batch\n * @param {Array<{id: string, updates: Object}>} updates - Update operations\n * @returns {Event[]} Updated events\n */\n updateEvents(updates) {\n return this.optimizer.measure('updateEvents', () => {\n this.startBatch();\n const results = [];\n const errors = [];\n\n for (const { id, updates: eventUpdates } of updates) {\n try {\n results.push(this.updateEvent(id, eventUpdates));\n } catch (error) {\n errors.push({ id, error: error.message });\n }\n }\n\n this.commitBatch();\n\n if (errors.length > 0) {\n console.warn(`Failed to update ${errors.length} events:`, errors);\n }\n\n return results;\n });\n }\n\n /**\n * Remove multiple events in batch\n * @param {string[]} eventIds - Event IDs to remove\n * @returns {number} Number of events removed\n */\n removeEvents(eventIds) {\n return this.optimizer.measure('removeEvents', () => {\n this.startBatch();\n let removed = 0;\n\n for (const id of eventIds) {\n if (this.removeEvent(id)) {\n removed++;\n }\n }\n\n this.commitBatch();\n return removed;\n });\n }\n\n // ============ Performance Methods ============\n\n /**\n * Get performance metrics\n * @returns {Object} Performance metrics\n */\n getPerformanceMetrics() {\n return this.optimizer.getMetrics();\n }\n\n /**\n * Clear all caches\n */\n clearCaches() {\n this.optimizer.eventCache.clear();\n this.optimizer.queryCache.clear();\n this.optimizer.dateRangeCache.clear();\n }\n\n /**\n * Optimize indices by removing old or irrelevant entries\n * @param {Date} [cutoffDate] - Remove indices older than this date\n */\n optimizeIndices(cutoffDate) {\n if (!cutoffDate) {\n cutoffDate = new Date();\n cutoffDate.setMonth(cutoffDate.getMonth() - 6); // Default: 6 months ago\n }\n\n const cutoffStr = cutoffDate.toDateString();\n let removed = 0;\n\n // Clean up date indices\n for (const [dateStr, eventIds] of this.indices.byDate) {\n const date = new Date(dateStr);\n if (date < cutoffDate) {\n // Check if any events still need this index\n let stillNeeded = false;\n for (const eventId of eventIds) {\n const event = this.events.get(eventId);\n if (event && event.end >= cutoffDate) {\n stillNeeded = true;\n break;\n }\n }\n\n if (!stillNeeded) {\n this.indices.byDate.delete(dateStr);\n removed++;\n }\n }\n }\n\n console.log(`Optimized indices: removed ${removed} old date entries`);\n return removed;\n }\n\n /**\n * Destroy the store and clean up resources\n */\n destroy() {\n this.clear();\n this.optimizer.destroy();\n this.listeners.clear();\n }\n\n // ============ Conflict Detection Methods ============\n\n /**\n * Check for conflicts for an event\n * @param {Event|import('../../types.js').EventData} event - Event to check\n * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options\n * @returns {import('../../types.js').ConflictSummary} Conflict summary\n */\n checkConflicts(event, options = {}) {\n return this.conflictDetector.checkConflicts(event, options);\n }\n\n /**\n * Check conflicts between two events\n * @param {string} eventId1 - First event ID\n * @param {string} eventId2 - Second event ID\n * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options\n * @returns {import('../../types.js').ConflictDetails[]} Conflicts between events\n */\n checkEventPairConflicts(eventId1, eventId2, options = {}) {\n const event1 = this.getEvent(eventId1);\n const event2 = this.getEvent(eventId2);\n\n if (!event1 || !event2) {\n throw new Error('One or both events not found');\n }\n\n return this.conflictDetector.checkEventPairConflicts(event1, event2, options);\n }\n\n /**\n * Get all conflicts in a date range\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @param {import('../../types.js').ConflictCheckOptions} [options={}] - Check options\n * @returns {import('../../types.js').ConflictSummary} All conflicts in range\n */\n getAllConflicts(start, end, options = {}) {\n const events = this.getEventsInRange(start, end, false);\n const allConflicts = [];\n const checkedPairs = new Set();\n\n for (let i = 0; i < events.length; i++) {\n for (let j = i + 1; j < events.length; j++) {\n const pairKey = `${events[i].id}-${events[j].id}`;\n if (!checkedPairs.has(pairKey)) {\n checkedPairs.add(pairKey);\n const conflicts = this.conflictDetector.checkEventPairConflicts(\n events[i],\n events[j],\n options\n );\n allConflicts.push(...conflicts);\n }\n }\n }\n\n return this.conflictDetector._buildConflictSummary(\n allConflicts,\n new Set(events.map(e => e.id)),\n new Set()\n );\n }\n\n /**\n * Get busy periods for attendees\n * @param {string[]} attendeeEmails - Attendee emails\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @param {Object} [options={}] - Options\n * @returns {Array<{start: Date, end: Date, eventIds: string[]}>} Busy periods\n */\n getBusyPeriods(attendeeEmails, start, end, options = {}) {\n return this.conflictDetector.getBusyPeriods(attendeeEmails, start, end, options);\n }\n\n /**\n * Get free periods for scheduling\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @param {number} durationMinutes - Required duration in minutes\n * @param {Object} [options={}] - Options\n * @returns {Array<{start: Date, end: Date}>} Free periods\n */\n getFreePeriods(start, end, durationMinutes, options = {}) {\n return this.conflictDetector.getFreePeriods(start, end, durationMinutes, options);\n }\n\n /**\n * Add event with conflict checking\n * @param {Event|import('../../types.js').EventData} event - Event to add\n * @param {boolean} [allowConflicts=true] - Whether to allow adding with conflicts\n * @returns {{event: Event, conflicts: import('../../types.js').ConflictSummary}} Result\n */\n addEventWithConflictCheck(event, allowConflicts = true) {\n // Check conflicts before adding\n const conflicts = this.checkConflicts(event);\n\n if (!allowConflicts && conflicts.hasConflicts) {\n throw new Error(`Cannot add event: ${conflicts.totalConflicts} conflicts detected`);\n }\n\n // Add the event\n const addedEvent = this.addEvent(event);\n\n return {\n event: addedEvent,\n conflicts\n };\n }\n\n /**\n * Find events with conflicts\n * @param {Object} [options={}] - Options\n * @returns {Array<{event: Event, conflicts: import('../../types.js').ConflictDetails[]}>} Events with conflicts\n */\n findEventsWithConflicts(options = {}) {\n const eventsWithConflicts = [];\n const allEvents = this.getAllEvents();\n\n for (const event of allEvents) {\n const conflicts = this.checkConflicts(event, options);\n if (conflicts.hasConflicts) {\n eventsWithConflicts.push({\n event,\n conflicts: conflicts.conflicts\n });\n }\n }\n\n return eventsWithConflicts;\n }\n}\n","/**\n * StateManager - Central state management for the calendar\n * Implements an immutable state pattern with change notifications\n */\nexport class StateManager {\n /**\n * Create a new StateManager instance\n * @param {Partial<import('../../types.js').CalendarState>} [initialState={}] - Initial state values\n */\n constructor(initialState = {}) {\n this.state = {\n // Current view configuration\n view: 'month', // 'month', 'week', 'day', 'list'\n currentDate: new Date(),\n\n // UI state\n selectedEventId: null,\n selectedDate: null,\n hoveredEventId: null,\n hoveredDate: null,\n\n // Display options\n weekStartsOn: 0, // 0 = Sunday, 1 = Monday, etc.\n showWeekNumbers: false,\n showWeekends: true,\n fixedWeekCount: true, // Always show 6 weeks in month view\n\n // Time configuration\n timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n locale: 'en-US',\n hourFormat: '12h', // '12h' or '24h'\n\n // Business hours (for week/day views)\n businessHours: {\n start: '09:00',\n end: '17:00'\n },\n\n // Filters\n filters: {\n searchTerm: '',\n categories: [],\n showAllDay: true,\n showTimed: true\n },\n\n // Interaction flags\n isDragging: false,\n isResizing: false,\n isCreating: false,\n\n // Loading states\n isLoading: false,\n loadingMessage: '',\n\n // Error state\n error: null,\n\n // Custom metadata\n metadata: {},\n\n // Apply initial state overrides\n ...initialState\n };\n\n // Observers for state changes\n this.listeners = new Map();\n this.globalListeners = new Set();\n\n // History for undo/redo (optional)\n this.history = [];\n this.historyIndex = -1;\n this.maxHistorySize = 50;\n }\n\n /**\n * Get the current state\n * @returns {import('../../types.js').CalendarState} Current state (frozen)\n */\n getState() {\n return Object.freeze({ ...this.state });\n }\n\n /**\n * Get a specific state value\n * @param {keyof import('../../types.js').CalendarState} key - The state key\n * @returns {any} The state value\n */\n get(key) {\n return this.state[key];\n }\n\n /**\n * Update state with partial updates\n * @param {Object|Function} updates - Object with updates or updater function\n */\n setState(updates) {\n const oldState = this.state;\n\n // Support function updater pattern\n if (typeof updates === 'function') {\n updates = updates(oldState);\n }\n\n // Create new state with updates\n const newState = {\n ...oldState,\n ...updates,\n // Preserve nested objects\n filters: updates.filters ? { ...oldState.filters, ...updates.filters } : oldState.filters,\n businessHours: updates.businessHours\n ? { ...oldState.businessHours, ...updates.businessHours }\n : oldState.businessHours,\n metadata: updates.metadata ? { ...oldState.metadata, ...updates.metadata } : oldState.metadata\n };\n\n // Check if state actually changed\n if (this._hasChanged(oldState, newState)) {\n this.state = newState;\n\n // Add to history (store the new state)\n this._addToHistory(newState);\n\n // Notify listeners\n this._notifyListeners(oldState, newState);\n }\n }\n\n /**\n * Set the current view\n * @param {string} view - The view type\n */\n setView(view) {\n const validViews = ['month', 'week', 'day', 'list'];\n if (!validViews.includes(view)) {\n throw new Error(`Invalid view: ${view}. Must be one of: ${validViews.join(', ')}`);\n }\n this.setState({ view });\n }\n\n /**\n * Set the current date\n * @param {Date} date - The date to set\n */\n setCurrentDate(date) {\n if (!(date instanceof Date)) {\n date = new Date(date);\n }\n if (isNaN(date.getTime())) {\n throw new Error('Invalid date');\n }\n this.setState({ currentDate: date });\n }\n\n /**\n * Navigate to the next period (month/week/day based on view)\n */\n navigateNext() {\n const { view, currentDate } = this.state;\n const newDate = new Date(currentDate);\n\n switch (view) {\n case 'month':\n newDate.setMonth(newDate.getMonth() + 1);\n break;\n case 'week':\n newDate.setDate(newDate.getDate() + 7);\n break;\n case 'day':\n newDate.setDate(newDate.getDate() + 1);\n break;\n }\n\n this.setCurrentDate(newDate);\n }\n\n /**\n * Navigate to the previous period\n */\n navigatePrevious() {\n const { view, currentDate } = this.state;\n const newDate = new Date(currentDate);\n\n switch (view) {\n case 'month':\n newDate.setMonth(newDate.getMonth() - 1);\n break;\n case 'week':\n newDate.setDate(newDate.getDate() - 7);\n break;\n case 'day':\n newDate.setDate(newDate.getDate() - 1);\n break;\n }\n\n this.setCurrentDate(newDate);\n }\n\n /**\n * Navigate to today\n */\n navigateToday() {\n this.setCurrentDate(new Date());\n }\n\n /**\n * Select an event\n * @param {string} eventId - The event ID to select\n */\n selectEvent(eventId) {\n this.setState({ selectedEventId: eventId });\n }\n\n /**\n * Clear event selection\n */\n clearEventSelection() {\n this.setState({ selectedEventId: null });\n }\n\n /**\n * Select a date\n * @param {Date} date - The date to select\n */\n selectDate(date) {\n if (!(date instanceof Date)) {\n date = new Date(date);\n }\n this.setState({ selectedDate: date });\n }\n\n /**\n * Clear date selection\n */\n clearDateSelection() {\n this.setState({ selectedDate: null });\n }\n\n /**\n * Set loading state\n * @param {boolean} isLoading - Loading state\n * @param {string} message - Optional loading message\n */\n setLoading(isLoading, message = '') {\n this.setState({\n isLoading,\n loadingMessage: message\n });\n }\n\n /**\n * Set error state\n * @param {Error|string|null} error - The error\n */\n setError(error) {\n this.setState({\n error: error ? (error instanceof Error ? error.message : error) : null\n });\n }\n\n /**\n * Update filters\n * @param {Object} filters - Filter updates\n */\n updateFilters(filters) {\n this.setState({\n filters: {\n ...this.state.filters,\n ...filters\n }\n });\n }\n\n /**\n * Subscribe to all state changes\n * @param {Function} callback - Callback function\n * @returns {Function} Unsubscribe function\n */\n subscribe(callback) {\n this.globalListeners.add(callback);\n\n return () => {\n this.globalListeners.delete(callback);\n };\n }\n\n /**\n * Subscribe to specific state key changes\n * @param {string|string[]} keys - State key(s) to watch\n * @param {Function} callback - Callback function\n * @returns {Function} Unsubscribe function\n */\n watch(keys, callback) {\n const keyArray = Array.isArray(keys) ? keys : [keys];\n\n keyArray.forEach(key => {\n if (!this.listeners.has(key)) {\n this.listeners.set(key, new Set());\n }\n this.listeners.get(key).add(callback);\n });\n\n return () => {\n keyArray.forEach(key => {\n const callbacks = this.listeners.get(key);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) {\n this.listeners.delete(key);\n }\n }\n });\n };\n }\n\n /**\n * Check if undo is available\n * @returns {boolean} True if undo is available\n */\n canUndo() {\n return this.historyIndex > 0;\n }\n\n /**\n * Check if redo is available\n * @returns {boolean} True if redo is available\n */\n canRedo() {\n return this.historyIndex < this.history.length - 1;\n }\n\n /**\n * Get the number of undo operations available\n * @returns {number} Number of undo operations\n */\n getUndoCount() {\n return this.historyIndex;\n }\n\n /**\n * Get the number of redo operations available\n * @returns {number} Number of redo operations\n */\n getRedoCount() {\n return this.history.length - 1 - this.historyIndex;\n }\n\n /**\n * Undo the last state change\n * @returns {boolean} True if undo was performed\n */\n undo() {\n if (!this.canUndo()) {\n return false;\n }\n\n this.historyIndex--;\n const previousState = this.history[this.historyIndex];\n const currentState = this.state;\n\n // Update state without adding to history\n this.state = { ...previousState };\n\n // Notify listeners\n this._notifyListeners(currentState, this.state);\n\n return true;\n }\n\n /**\n * Redo the next state change\n * @returns {boolean} True if redo was performed\n */\n redo() {\n if (!this.canRedo()) {\n return false;\n }\n\n this.historyIndex++;\n const nextState = this.history[this.historyIndex];\n const currentState = this.state;\n\n // Update state without adding to history\n this.state = { ...nextState };\n\n // Notify listeners\n this._notifyListeners(currentState, this.state);\n\n return true;\n }\n\n /**\n * Reset state to initial values\n */\n reset() {\n const initialState = this.history[0] || {};\n this.setState(initialState);\n this.history = [initialState];\n this.historyIndex = 0;\n }\n\n /**\n * Check if state has changed\n * @private\n */\n _hasChanged(oldState, newState) {\n return !this._deepEqual(oldState, newState);\n }\n\n /**\n * Deep equality check optimized for state comparison\n * @private\n * @param {*} a - First value\n * @param {*} b - Second value\n * @param {Set} seen - Track circular references\n * @returns {boolean} True if values are deeply equal\n */\n _deepEqual(a, b, seen = new Set()) {\n // Same reference\n if (a === b) return true;\n\n // Different types or null/undefined\n if (a == null || b == null) return a === b;\n if (typeof a !== typeof b) return false;\n\n // Primitives\n if (typeof a !== 'object') return a === b;\n\n // Check for circular references\n if (seen.has(a) || seen.has(b)) return false;\n seen.add(a);\n seen.add(b);\n\n // Arrays\n if (Array.isArray(a)) {\n if (!Array.isArray(b) || a.length !== b.length) {\n seen.delete(a);\n seen.delete(b);\n return false;\n }\n\n for (let i = 0; i < a.length; i++) {\n if (!this._deepEqual(a[i], b[i], seen)) {\n seen.delete(a);\n seen.delete(b);\n return false;\n }\n }\n\n seen.delete(a);\n seen.delete(b);\n return true;\n }\n\n // Dates\n if (a instanceof Date && b instanceof Date) {\n const result = a.getTime() === b.getTime();\n seen.delete(a);\n seen.delete(b);\n return result;\n }\n\n // Objects\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n if (aKeys.length !== bKeys.length) {\n seen.delete(a);\n seen.delete(b);\n return false;\n }\n\n // Sort keys for consistent comparison\n aKeys.sort();\n bKeys.sort();\n\n // Compare keys\n for (let i = 0; i < aKeys.length; i++) {\n if (aKeys[i] !== bKeys[i]) {\n seen.delete(a);\n seen.delete(b);\n return false;\n }\n }\n\n // Compare values\n for (const key of aKeys) {\n if (!this._deepEqual(a[key], b[key], seen)) {\n seen.delete(a);\n seen.delete(b);\n return false;\n }\n }\n\n seen.delete(a);\n seen.delete(b);\n return true;\n }\n\n /**\n * Add state to history\n * @private\n */\n _addToHistory(state) {\n // Remove any future history if we're not at the end\n if (this.historyIndex < this.history.length - 1) {\n this.history = this.history.slice(0, this.historyIndex + 1);\n }\n\n // Deep clone state to prevent shared references in history\n // (shallow copy would share nested objects like filters, businessHours, metadata)\n const clonedState = this._deepClone(state);\n this.history.push(clonedState);\n this.historyIndex++;\n\n // Limit history size\n if (this.history.length > this.maxHistorySize) {\n this.history.shift();\n this.historyIndex--;\n }\n }\n\n /**\n * Deep clone a value for history storage\n * @private\n */\n _deepClone(value) {\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n if (value instanceof Date) {\n return new Date(value);\n }\n\n if (Array.isArray(value)) {\n return value.map(item => this._deepClone(item));\n }\n\n const cloned = {};\n for (const key in value) {\n if (Object.prototype.hasOwnProperty.call(value, key)) {\n cloned[key] = this._deepClone(value[key]);\n }\n }\n return cloned;\n }\n\n /**\n * Notify listeners of state changes\n * @private\n */\n _notifyListeners(oldState, newState) {\n // Notify global listeners\n for (const callback of this.globalListeners) {\n try {\n callback(newState, oldState);\n } catch (error) {\n console.error('Error in state listener:', error);\n }\n }\n\n // Notify specific key listeners\n for (const [key, callbacks] of this.listeners) {\n if (oldState[key] !== newState[key]) {\n for (const callback of callbacks) {\n try {\n callback(newState[key], oldState[key], newState, oldState);\n } catch (error) {\n console.error(`Error in state listener for key \"${key}\":`, error);\n }\n }\n }\n }\n }\n}\n","import { EventStore } from '../events/EventStore.js';\nimport { Event } from '../events/Event.js';\nimport { StateManager } from '../state/StateManager.js';\nimport { DateUtils } from './DateUtils.js';\nimport { TimezoneManager } from '../timezone/TimezoneManager.js';\n\n/**\n * Calendar - Main calendar class with full timezone support\n * Pure JavaScript, no DOM dependencies\n * Framework agnostic, Locker Service compatible\n */\nexport class Calendar {\n /**\n * Create a new Calendar instance\n * @param {import('../../types.js').CalendarConfig} [config={}] - Configuration options\n */\n constructor(config = {}) {\n // Initialize timezone manager first (use singleton to share cache)\n this.timezoneManager = TimezoneManager.getInstance();\n\n // Initialize configuration\n this.config = {\n view: 'month',\n date: new Date(),\n weekStartsOn: 0, // 0 = Sunday\n locale: 'en-US',\n timeZone: config.timeZone || this.timezoneManager.getSystemTimezone(),\n showWeekNumbers: false,\n showWeekends: true,\n fixedWeekCount: true,\n businessHours: {\n start: '09:00',\n end: '17:00'\n },\n ...config\n };\n\n // Initialize core components with timezone support\n this.eventStore = new EventStore({ timezone: this.config.timeZone });\n this.state = new StateManager({\n view: this.config.view,\n currentDate: this.config.date,\n weekStartsOn: this.config.weekStartsOn,\n locale: this.config.locale,\n timeZone: this.config.timeZone,\n showWeekNumbers: this.config.showWeekNumbers,\n showWeekends: this.config.showWeekends,\n fixedWeekCount: this.config.fixedWeekCount,\n businessHours: this.config.businessHours\n });\n\n // Event emitter for calendar events\n this.listeners = new Map();\n\n // Plugins\n this.plugins = new Set();\n\n // View instances (lazy loaded)\n this.views = new Map();\n\n // Set up internal listeners\n this._setupInternalListeners();\n\n // Load initial events if provided\n if (config.events) {\n this.setEvents(config.events);\n }\n }\n\n /**\n * Set the calendar view\n * @param {import('../../types.js').ViewType} viewType - The view type ('month', 'week', 'day', 'list')\n * @param {Date} [date=null] - Optional date to navigate to\n */\n setView(viewType, date = null) {\n this.state.setView(viewType);\n\n if (date) {\n this.state.setCurrentDate(date);\n }\n\n this._emit('viewChange', {\n view: viewType,\n date: date || this.state.get('currentDate')\n });\n }\n\n /**\n * Get the current view type\n * @returns {import('../../types.js').ViewType} The current view type\n */\n getView() {\n return this.state.get('view');\n }\n\n /**\n * Navigate to the next period\n */\n next() {\n this.state.navigateNext();\n this._emit('navigate', {\n direction: 'next',\n date: this.state.get('currentDate'),\n view: this.state.get('view')\n });\n }\n\n /**\n * Navigate to the previous period\n */\n previous() {\n this.state.navigatePrevious();\n this._emit('navigate', {\n direction: 'previous',\n date: this.state.get('currentDate'),\n view: this.state.get('view')\n });\n }\n\n /**\n * Navigate to today\n */\n today() {\n this.state.navigateToday();\n this._emit('navigate', {\n direction: 'today',\n date: this.state.get('currentDate'),\n view: this.state.get('view')\n });\n }\n\n /**\n * Navigate to a specific date\n * @param {Date} date - The date to navigate to\n */\n goToDate(date) {\n this.state.setCurrentDate(date);\n this._emit('navigate', {\n direction: 'goto',\n date: date,\n view: this.state.get('view')\n });\n }\n\n /**\n * Alias for goToDate (compat)\n * @param {Date} date - The date to navigate to\n */\n setDate(date) {\n this.goToDate(date);\n }\n\n /**\n * Get the current date\n * @returns {Date}\n */\n getCurrentDate() {\n return new Date(this.state.get('currentDate'));\n }\n\n /**\n * Add an event\n * @param {import('../events/Event.js').Event|import('../../types.js').EventData} eventData - Event data or Event instance\n * @returns {import('../events/Event.js').Event} The added event\n */\n addEvent(eventData) {\n // If eventData is not an Event instance and doesn't have a timezone, use calendar's timezone\n if (!(eventData instanceof Event) && !eventData.timeZone) {\n eventData = { ...eventData, timeZone: this.config.timeZone };\n }\n\n const event = this.eventStore.addEvent(eventData);\n\n this._emit('eventAdd', { event });\n\n return event;\n }\n\n /**\n * Update an event\n * @param {string} eventId - The event ID\n * @param {Object} updates - Properties to update\n * @returns {Event} The updated event\n */\n updateEvent(eventId, updates) {\n const oldEvent = this.eventStore.getEvent(eventId);\n const event = this.eventStore.updateEvent(eventId, updates);\n\n this._emit('eventUpdate', { event, oldEvent });\n\n return event;\n }\n\n /**\n * Remove an event\n * @param {string} eventId - The event ID\n * @returns {boolean} True if removed\n */\n removeEvent(eventId) {\n const event = this.eventStore.getEvent(eventId);\n const removed = this.eventStore.removeEvent(eventId);\n\n if (removed) {\n this._emit('eventRemove', { event });\n }\n\n return removed;\n }\n\n /**\n * Alias for removeEvent (compat)\n * @param {string} eventId - The event ID\n * @returns {boolean} True if removed\n */\n deleteEvent(eventId) {\n return this.removeEvent(eventId);\n }\n\n /**\n * Get an event by ID\n * @param {string} eventId - The event ID\n * @returns {Event|null}\n */\n getEvent(eventId) {\n return this.eventStore.getEvent(eventId);\n }\n\n /**\n * Get all events\n * @returns {Event[]}\n */\n getEvents() {\n return this.eventStore.getAllEvents();\n }\n\n /**\n * Set all events (replaces existing)\n * @param {Event[]} events - Array of events\n */\n setEvents(events) {\n this.eventStore.loadEvents(events);\n this._emit('eventsSet', { events: this.getEvents() });\n }\n\n /**\n * Query events with filters\n * @param {Object} filters - Query filters\n * @returns {Event[]}\n */\n queryEvents(filters) {\n return this.eventStore.queryEvents(filters);\n }\n\n /**\n * Get events for a specific date\n * @param {Date} date - The date\n * @param {string} [timezone] - Timezone for the query (defaults to calendar timezone)\n * @returns {Event[]}\n */\n getEventsForDate(date, timezone = null) {\n return this.eventStore.getEventsForDate(date, timezone || this.config.timeZone);\n }\n\n /**\n * Get events in a date range\n * @param {Date} start - Start date\n * @param {Date} end - End date\n * @param {string} [timezone] - Timezone for the query (defaults to calendar timezone)\n * @returns {Event[]}\n */\n getEventsInRange(start, end, timezone = null) {\n return this.eventStore.getEventsInRange(start, end, true, timezone || this.config.timeZone);\n }\n\n /**\n * Set the calendar's timezone\n * @param {string} timezone - IANA timezone identifier\n */\n setTimezone(timezone) {\n const parsedTimezone = this.timezoneManager.parseTimezone(timezone);\n const previousTimezone = this.config.timeZone;\n\n this.config.timeZone = parsedTimezone;\n this.eventStore.defaultTimezone = parsedTimezone;\n this.state.setState({ timeZone: parsedTimezone });\n\n this._emit('timezoneChange', {\n timezone: parsedTimezone,\n previousTimezone: previousTimezone\n });\n }\n\n /**\n * Get the current timezone\n * @returns {string} Current timezone\n */\n getTimezone() {\n return this.config.timeZone;\n }\n\n /**\n * Set the calendar locale\n * @param {string} locale - Locale identifier (e.g. 'en-US')\n */\n setLocale(locale) {\n this.config.locale = locale;\n this.state.setState({ locale });\n this._emit('localeChange', { locale });\n }\n\n /**\n * Set the week start day\n * @param {number} weekStartsOn - 0 = Sunday, 1 = Monday, etc.\n */\n setWeekStartsOn(weekStartsOn) {\n this.config.weekStartsOn = weekStartsOn;\n this.state.setState({ weekStartsOn });\n this._emit('weekStartsOnChange', { weekStartsOn });\n }\n\n /**\n * Convert a date from one timezone to another\n * @param {Date} date - Date to convert\n * @param {string} fromTimezone - Source timezone\n * @param {string} toTimezone - Target timezone\n * @returns {Date} Converted date\n */\n convertTimezone(date, fromTimezone, toTimezone) {\n return this.timezoneManager.convertTimezone(date, fromTimezone, toTimezone);\n }\n\n /**\n * Convert a date to the calendar's timezone\n * @param {Date} date - Date to convert\n * @param {string} fromTimezone - Source timezone\n * @returns {Date} Date in calendar timezone\n */\n toCalendarTimezone(date, fromTimezone) {\n return this.timezoneManager.convertTimezone(date, fromTimezone, this.config.timeZone);\n }\n\n /**\n * Convert a date from the calendar's timezone\n * @param {Date} date - Date in calendar timezone\n * @param {string} toTimezone - Target timezone\n * @returns {Date} Converted date\n */\n fromCalendarTimezone(date, toTimezone) {\n return this.timezoneManager.convertTimezone(date, this.config.timeZone, toTimezone);\n }\n\n /**\n * Format a date in a specific timezone\n * @param {Date} date - Date to format\n * @param {string} [timezone] - Timezone for formatting (defaults to calendar timezone)\n * @param {Object} [options] - Formatting options\n * @returns {string} Formatted date string\n */\n formatInTimezone(date, timezone = null, options = {}) {\n return this.timezoneManager.formatInTimezone(date, timezone || this.config.timeZone, options);\n }\n\n /**\n * Get list of common timezones with offsets\n * @returns {Array<{value: string, label: string, offset: string}>} Timezone list\n */\n getTimezones() {\n return this.timezoneManager.getCommonTimezones();\n }\n\n /**\n * Get overlapping event groups for a date\n * @param {Date} date - The date to check\n * @param {boolean} timedOnly - Only include timed events\n * @returns {Array<Event[]>} Array of event groups that overlap\n */\n getOverlapGroups(date, timedOnly = true) {\n return this.eventStore.getOverlapGroups(date, timedOnly);\n }\n\n /**\n * Calculate event positions for rendering\n * @param {Event[]} events - Array of overlapping events\n * @returns {Map<string, {column: number, totalColumns: number}>} Position data\n */\n calculateEventPositions(events) {\n return this.eventStore.calculateEventPositions(events);\n }\n\n /**\n * Get the current view's data\n * @returns {import('../../types.js').MonthViewData|import('../../types.js').WeekViewData|import('../../types.js').DayViewData|import('../../types.js').ListViewData|null} View-specific data\n */\n getViewData() {\n const view = this.state.get('view');\n const currentDate = this.state.get('currentDate');\n\n switch (view) {\n case 'month':\n return this._getMonthViewData(currentDate);\n case 'week':\n return this._getWeekViewData(currentDate);\n case 'day':\n return this._getDayViewData(currentDate);\n case 'list':\n return this._getListViewData(currentDate);\n default:\n return null;\n }\n }\n\n /**\n * Get month view data\n * @private\n */\n _getMonthViewData(date) {\n const year = date.getFullYear();\n const month = date.getMonth();\n const weekStartsOn = this.state.get('weekStartsOn');\n const fixedWeekCount = this.state.get('fixedWeekCount');\n\n // Get the first day of the month\n const firstDay = new Date(year, month, 1);\n\n // Get the last day of the month\n const lastDay = new Date(year, month + 1, 0);\n\n // Calculate the start date (beginning of the week containing the first day)\n const startDate = DateUtils.startOfWeek(firstDay, weekStartsOn);\n\n // Calculate weeks\n const weeks = [];\n let currentDate = new Date(startDate);\n\n // Generate weeks\n const maxWeeks = fixedWeekCount\n ? 6\n : Math.ceil((lastDay.getDate() + DateUtils.getDayOfWeek(firstDay, weekStartsOn)) / 7);\n\n for (let weekIndex = 0; weekIndex < maxWeeks; weekIndex++) {\n const week = {\n weekNumber: DateUtils.getWeekNumber(currentDate),\n days: []\n };\n\n for (let dayIndex = 0; dayIndex < 7; dayIndex++) {\n const dayDate = new Date(currentDate);\n const isCurrentMonth = dayDate.getMonth() === month;\n const isToday = DateUtils.isToday(dayDate);\n const isWeekend = dayDate.getDay() === 0 || dayDate.getDay() === 6;\n\n week.days.push({\n date: dayDate,\n dayOfMonth: dayDate.getDate(),\n isCurrentMonth,\n isToday,\n isWeekend,\n events: this.getEventsForDate(dayDate)\n });\n\n // Use DateUtils.addDays to handle month boundaries correctly\n currentDate = DateUtils.addDays(currentDate, 1);\n }\n\n weeks.push(week);\n }\n\n return {\n type: 'month',\n year,\n month,\n monthName: DateUtils.getMonthName(date, this.state.get('locale')),\n weeks,\n startDate,\n endDate: new Date(currentDate.getTime() - 1) // Last moment of the view\n };\n }\n\n /**\n * Get week view data\n * @private\n */\n _getWeekViewData(date) {\n const weekStartsOn = this.state.get('weekStartsOn');\n const startDate = DateUtils.startOfWeek(date, weekStartsOn);\n const endDate = DateUtils.endOfWeek(date, weekStartsOn);\n\n const days = [];\n const currentDate = new Date(startDate);\n\n for (let i = 0; i < 7; i++) {\n const dayDate = new Date(currentDate);\n days.push({\n date: dayDate,\n dayOfMonth: dayDate.getDate(),\n dayOfWeek: dayDate.getDay(),\n dayName: DateUtils.getDayName(dayDate, this.state.get('locale')),\n isToday: DateUtils.isToday(dayDate),\n isWeekend: dayDate.getDay() === 0 || dayDate.getDay() === 6,\n events: this.getEventsForDate(dayDate),\n // Add overlap groups for positioning overlapping events\n overlapGroups: this.eventStore.getOverlapGroups(dayDate, true),\n getEventPositions: events => this.eventStore.calculateEventPositions(events)\n });\n // Move to next day\n currentDate.setDate(currentDate.getDate() + 1);\n }\n\n return {\n type: 'week',\n weekNumber: DateUtils.getWeekNumber(startDate),\n startDate,\n endDate,\n days\n };\n }\n\n /**\n * Get day view data\n * @private\n */\n _getDayViewData(date) {\n const events = this.getEventsForDate(date);\n\n // Separate all-day and timed events\n const allDayEvents = events.filter(e => e.allDay);\n const timedEvents = events.filter(e => !e.allDay);\n\n // Create hourly slots for timed events\n const hours = [];\n for (let hour = 0; hour < 24; hour++) {\n const hourDate = new Date(date);\n hourDate.setHours(hour, 0, 0, 0);\n const hourEnd = new Date(date);\n hourEnd.setHours(hour + 1, 0, 0, 0);\n\n hours.push({\n hour,\n time: DateUtils.formatTime(hourDate, this.state.get('locale')),\n events: timedEvents.filter(event => {\n // Check if event occurs during this hour (not just starts)\n // Event occurs in this hour if it overlaps with the hour slot\n return event.start < hourEnd && event.end > hourDate;\n })\n });\n }\n\n return {\n type: 'day',\n date,\n dayName: DateUtils.getDayName(date, this.state.get('locale')),\n isToday: DateUtils.isToday(date),\n allDayEvents,\n hours\n };\n }\n\n /**\n * Get list view data\n * @private\n */\n _getListViewData(date) {\n // Get events for the next 30 days\n const startDate = new Date(date);\n startDate.setHours(0, 0, 0, 0);\n\n const endDate = new Date(startDate);\n endDate.setDate(endDate.getDate() + 30);\n\n const events = this.getEventsInRange(startDate, endDate);\n\n // Group events by day\n const groupedEvents = new Map();\n\n events.forEach(event => {\n const dateKey = event.start.toDateString();\n if (!groupedEvents.has(dateKey)) {\n groupedEvents.set(dateKey, {\n date: new Date(event.start),\n events: []\n });\n }\n groupedEvents.get(dateKey).events.push(event);\n });\n\n // Convert to sorted array\n const days = Array.from(groupedEvents.values())\n .sort((a, b) => a.date - b.date)\n .map(day => ({\n ...day,\n dayName: DateUtils.getDayName(day.date, this.state.get('locale')),\n isToday: DateUtils.isToday(day.date)\n }));\n\n return {\n type: 'list',\n startDate,\n endDate,\n days,\n totalEvents: events.length\n };\n }\n\n /**\n * Select an event\n * @param {string} eventId - Event ID to select\n */\n selectEvent(eventId) {\n const event = this.getEvent(eventId);\n if (event) {\n this.state.selectEvent(eventId);\n this._emit('eventSelect', { event });\n }\n }\n\n /**\n * Clear event selection\n */\n clearEventSelection() {\n const eventId = this.state.get('selectedEventId');\n this.state.clearEventSelection();\n\n if (eventId) {\n this._emit('eventDeselect', { eventId });\n }\n }\n\n /**\n * Select a date\n * @param {Date} date - Date to select\n */\n selectDate(date) {\n this.state.selectDate(date);\n this._emit('dateSelect', { date });\n }\n\n /**\n * Clear date selection\n */\n clearDateSelection() {\n const date = this.state.get('selectedDate');\n this.state.clearDateSelection();\n\n if (date) {\n this._emit('dateDeselect', { date });\n }\n }\n\n /**\n * Subscribe to calendar events\n * @param {string} eventName - Event name\n * @param {Function} callback - Callback function\n * @returns {Function} Unsubscribe function\n */\n on(eventName, callback) {\n if (!this.listeners.has(eventName)) {\n this.listeners.set(eventName, new Set());\n }\n this.listeners.get(eventName).add(callback);\n\n return () => this.off(eventName, callback);\n }\n\n /**\n * Unsubscribe from calendar events\n * @param {string} eventName - Event name\n * @param {Function} callback - Callback function\n */\n off(eventName, callback) {\n const callbacks = this.listeners.get(eventName);\n if (callbacks) {\n callbacks.delete(callback);\n if (callbacks.size === 0) {\n this.listeners.delete(eventName);\n }\n }\n }\n\n /**\n * Emit an event\n * @private\n */\n _emit(eventName, data) {\n const callbacks = this.listeners.get(eventName);\n if (callbacks) {\n callbacks.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error(`Error in event listener for \"${eventName}\":`, error);\n }\n });\n }\n }\n\n /**\n * Set up internal listeners\n * @private\n */\n _setupInternalListeners() {\n // Listen to state changes\n this.state.subscribe((newState, oldState) => {\n this._emit('stateChange', { newState, oldState });\n });\n\n // Listen to event store changes\n this.eventStore.subscribe(change => {\n this._emit('eventStoreChange', change);\n });\n }\n\n /**\n * Install a plugin\n * @param {Object} plugin - Plugin object with install method\n */\n use(plugin) {\n if (this.plugins.has(plugin)) {\n console.warn('Plugin already installed');\n return;\n }\n\n if (typeof plugin.install === 'function') {\n plugin.install(this);\n this.plugins.add(plugin);\n } else {\n throw new Error('Plugin must have an install method');\n }\n }\n\n /**\n * Destroy the calendar and clean up\n */\n destroy() {\n // Clear all listeners\n this.listeners.clear();\n\n // Properly destroy EventStore (clears events, caches, and cleanup timers)\n this.eventStore.destroy();\n\n // Clear plugins\n this.plugins.forEach(plugin => {\n if (typeof plugin.uninstall === 'function') {\n plugin.uninstall(this);\n }\n });\n this.plugins.clear();\n\n // Clear view instances\n this.views.clear();\n\n this._emit('destroy');\n }\n} // Test workflow\n","/**\n * EventBus - Central event communication system\n *\n * Enables decoupled communication between components\n * Supports event namespacing and wildcard subscriptions\n */\n\nclass EventBus {\n constructor() {\n this.events = new Map();\n this.wildcardHandlers = new Set();\n }\n\n /**\n * Subscribe to an event\n * @param {string} eventName - Event name or pattern (supports wildcards)\n * @param {Function} handler - Event handler function\n * @param {Object} options - Subscription options\n * @returns {Function} Unsubscribe function\n */\n on(eventName, handler, options = {}) {\n const { once = false, priority = 0 } = options;\n\n // Handle wildcard subscriptions\n if (eventName.includes('*')) {\n const subscription = { pattern: eventName, handler, once, priority };\n this.wildcardHandlers.add(subscription);\n return () => this.wildcardHandlers.delete(subscription);\n }\n\n // Regular event subscription\n if (!this.events.has(eventName)) {\n this.events.set(eventName, []);\n }\n\n const subscription = { handler, once, priority };\n const handlers = this.events.get(eventName);\n handlers.push(subscription);\n handlers.sort((a, b) => b.priority - a.priority);\n\n // Return unsubscribe function\n return () => {\n const index = handlers.indexOf(subscription);\n if (index > -1) {\n handlers.splice(index, 1);\n }\n };\n }\n\n /**\n * Subscribe to an event that fires only once\n */\n once(eventName, handler, options = {}) {\n return this.on(eventName, handler, { ...options, once: true });\n }\n\n /**\n * Unsubscribe from an event\n */\n off(eventName, handler) {\n if (!this.events.has(eventName)) return;\n\n const handlers = this.events.get(eventName);\n const index = handlers.findIndex(sub => sub.handler === handler);\n if (index > -1) {\n handlers.splice(index, 1);\n }\n\n if (handlers.length === 0) {\n this.events.delete(eventName);\n }\n }\n\n /**\n * Emit an event\n * @param {string} eventName - Event name\n * @param {*} data - Event data\n * @returns {Promise} Resolves when all handlers complete\n */\n async emit(eventName, data) {\n const promises = [];\n\n // Handle direct subscriptions\n if (this.events.has(eventName)) {\n const handlers = [...this.events.get(eventName)];\n\n for (const subscription of handlers) {\n const { handler, once } = subscription;\n\n if (once) {\n this.off(eventName, handler);\n }\n\n try {\n const result = handler(data, eventName);\n if (result instanceof Promise) {\n promises.push(result);\n }\n } catch (error) {\n console.error(`Error in event handler for ${eventName}:`, error);\n }\n }\n }\n\n // Handle wildcard subscriptions (copy Set to avoid mutation during iteration)\n const toRemove = [];\n for (const subscription of [...this.wildcardHandlers]) {\n if (this.matchesPattern(eventName, subscription.pattern)) {\n const { handler, once } = subscription;\n\n if (once) {\n toRemove.push(subscription);\n }\n\n try {\n const result = handler(data, eventName);\n if (result instanceof Promise) {\n promises.push(result);\n }\n } catch (error) {\n console.error(`Error in wildcard handler for ${eventName}:`, error);\n }\n }\n }\n // Remove one-time handlers after iteration\n toRemove.forEach(sub => this.wildcardHandlers.delete(sub));\n\n return Promise.all(promises);\n }\n\n /**\n * Check if event name matches a pattern\n */\n matchesPattern(eventName, pattern) {\n const regex = new RegExp('^' + pattern.replace(/\\*/g, '.*') + '$');\n return regex.test(eventName);\n }\n\n /**\n * Clear all event subscriptions\n */\n clear() {\n this.events.clear();\n this.wildcardHandlers.clear();\n }\n\n /**\n * Get all registered event names\n */\n getEventNames() {\n return Array.from(this.events.keys());\n }\n\n /**\n * Get handler count for an event\n */\n getHandlerCount(eventName) {\n return this.events.has(eventName) ? this.events.get(eventName).length : 0;\n }\n}\n\n// Create singleton instance\nconst eventBus = new EventBus();\n\n// Export both the class and singleton\nexport { EventBus, eventBus as default };","/**\n * StateManager - Centralized state management for Force Calendar\n *\n * Wraps the @forcecalendar/core Calendar instance\n * Provides reactive state updates and component synchronization\n */\n\nimport { Calendar } from '@forcecalendar/core';\nimport eventBus from './EventBus.js';\n\nclass StateManager {\n constructor(config = {}) {\n // Initialize Core Calendar instance\n this.calendar = new Calendar({\n view: config.view || 'month',\n date: config.date || new Date(),\n weekStartsOn: config.weekStartsOn ?? 0,\n locale: config.locale || 'en-US',\n timeZone: config.timeZone || Intl.DateTimeFormat().resolvedOptions().timeZone,\n ...config\n });\n\n // Internal state\n this.state = {\n view: this.calendar.getView(),\n currentDate: this.calendar.getCurrentDate(),\n events: [],\n selectedEvent: null,\n selectedDate: null,\n loading: false,\n error: null,\n config: { ...config }\n };\n\n // State change subscribers\n this.subscribers = new Set();\n\n // Bind methods\n this.subscribe = this.subscribe.bind(this);\n this.unsubscribe = this.unsubscribe.bind(this);\n this.setState = this.setState.bind(this);\n }\n\n // State management\n getState() {\n return { ...this.state };\n }\n\n setState(updates, options = {}) {\n const { silent = false } = options;\n const oldState = { ...this.state };\n this.state = { ...this.state, ...updates };\n\n if (!silent) {\n this.notifySubscribers(oldState, this.state);\n this.emitStateChange(oldState, this.state);\n }\n\n return this.state;\n }\n\n subscribe(callback) {\n this.subscribers.add(callback);\n return () => this.unsubscribe(callback);\n }\n\n unsubscribe(callback) {\n this.subscribers.delete(callback);\n }\n\n notifySubscribers(oldState, newState) {\n this.subscribers.forEach(callback => {\n try {\n callback(newState, oldState);\n } catch (error) {\n console.error('Error in state subscriber:', error);\n }\n });\n }\n\n emitStateChange(oldState, newState) {\n const changedKeys = Object.keys(newState).filter(\n key => oldState[key] !== newState[key]\n );\n\n changedKeys.forEach(key => {\n eventBus.emit(`state:${key}:changed`, {\n oldValue: oldState[key],\n newValue: newState[key],\n state: newState\n });\n });\n\n if (changedKeys.length > 0) {\n eventBus.emit('state:changed', { oldState, newState, changedKeys });\n }\n }\n\n // Calendar operations\n setView(view) {\n this.calendar.setView(view);\n this.setState({ view });\n eventBus.emit('view:changed', { view });\n }\n\n getView() {\n return this.state.view;\n }\n\n setDate(date) {\n this.calendar.goToDate(date);\n this.setState({ currentDate: this.calendar.getCurrentDate() });\n eventBus.emit('date:changed', { date: this.state.currentDate });\n }\n\n getCurrentDate() {\n return this.state.currentDate;\n }\n\n // Navigation\n next() {\n this.calendar.next();\n this.setState({ currentDate: this.calendar.getCurrentDate() });\n eventBus.emit('navigation:next', { date: this.state.currentDate });\n }\n\n previous() {\n this.calendar.previous();\n this.setState({ currentDate: this.calendar.getCurrentDate() });\n eventBus.emit('navigation:previous', { date: this.state.currentDate });\n }\n\n today() {\n this.calendar.today();\n this.setState({ currentDate: this.calendar.getCurrentDate() });\n eventBus.emit('navigation:today', { date: this.state.currentDate });\n }\n\n goToDate(date) {\n this.calendar.goToDate(date);\n this.setState({ currentDate: this.calendar.getCurrentDate() });\n eventBus.emit('navigation:goto', { date: this.state.currentDate });\n }\n\n // Event management\n addEvent(event) {\n const addedEvent = this.calendar.addEvent(event);\n if (!addedEvent) {\n console.error('Failed to add event to calendar');\n eventBus.emit('event:error', { action: 'add', event, error: 'Failed to add event' });\n return null;\n }\n // Create new array to avoid mutation before setState\n const newEvents = [...this.state.events, addedEvent];\n this.setState({ events: newEvents });\n eventBus.emit('event:added', { event: addedEvent });\n return addedEvent;\n }\n\n updateEvent(eventId, updates) {\n const event = this.calendar.updateEvent(eventId, updates);\n if (!event) {\n console.error(`Failed to update event: ${eventId}`);\n eventBus.emit('event:error', { action: 'update', eventId, updates, error: 'Event not found in calendar' });\n return null;\n }\n\n const index = this.state.events.findIndex(e => e.id === eventId);\n if (index === -1) {\n console.error(`Event ${eventId} not found in state`);\n eventBus.emit('event:error', { action: 'update', eventId, error: 'Event not found in state' });\n return null;\n }\n\n // Create new array to avoid mutation before setState\n const newEvents = [...this.state.events];\n newEvents[index] = event;\n this.setState({ events: newEvents });\n eventBus.emit('event:updated', { event });\n return event;\n }\n\n deleteEvent(eventId) {\n const deleted = this.calendar.removeEvent(eventId);\n if (!deleted) {\n console.error(`Failed to delete event: ${eventId}`);\n eventBus.emit('event:error', { action: 'delete', eventId, error: 'Event not found' });\n return false;\n }\n // Create new array to avoid mutation before setState\n const newEvents = this.state.events.filter(e => e.id !== eventId);\n this.setState({ events: newEvents });\n eventBus.emit('event:deleted', { eventId });\n return true;\n }\n\n getEvents() {\n return this.calendar.getEvents();\n }\n\n getEventsForDate(date) {\n return this.calendar.getEventsForDate(date);\n }\n\n getEventsInRange(start, end) {\n return this.calendar.getEventsInRange(start, end);\n }\n\n // View data\n getViewData() {\n const viewData = this.calendar.getViewData();\n return this.enrichViewData(viewData);\n }\n\n enrichViewData(viewData) {\n const selectedDateString = this.state.selectedDate?.toDateString();\n\n // Strategy 1: Multi-week structure (Month view)\n if (viewData.weeks) {\n viewData.weeks = viewData.weeks.map(week => ({\n ...week,\n days: week.days.map(day => {\n const dayDate = new Date(day.date);\n return {\n ...day,\n isSelected: dayDate.toDateString() === selectedDateString,\n events: day.events || this.getEventsForDate(dayDate)\n };\n })\n }));\n }\n\n // Strategy 2: Flat days structure (Week view or list view)\n if (viewData.days) {\n viewData.days = viewData.days.map(day => {\n const dayDate = new Date(day.date);\n return {\n ...day,\n isSelected: dayDate.toDateString() === selectedDateString,\n events: day.events || this.getEventsForDate(dayDate)\n };\n });\n }\n\n // Strategy 3: Single day structure (Day view)\n if (viewData.date && !viewData.days && !viewData.weeks) {\n const dayDate = new Date(viewData.date);\n viewData.isSelected = dayDate.toDateString() === selectedDateString;\n viewData.events = viewData.events || this.getEventsForDate(dayDate);\n }\n\n return viewData;\n }\n\n // Selection management\n selectEvent(event) {\n this.setState({ selectedEvent: event });\n eventBus.emit('event:selected', { event });\n }\n\n selectEventById(eventId) {\n const event = this.state.events.find(e => e.id === eventId);\n if (event) {\n this.selectEvent(event);\n }\n }\n\n deselectEvent() {\n this.setState({ selectedEvent: null });\n eventBus.emit('event:deselected', {});\n }\n\n selectDate(date) {\n this.setState({ selectedDate: date });\n eventBus.emit('date:selected', { date });\n }\n\n deselectDate() {\n this.setState({ selectedDate: null });\n eventBus.emit('date:deselected', {});\n }\n\n // Utility methods\n isToday(date) {\n const today = new Date();\n return date.toDateString() === today.toDateString();\n }\n\n isSelectedDate(date) {\n return this.state.selectedDate &&\n date.toDateString() === this.state.selectedDate.toDateString();\n }\n\n isWeekend(date) {\n const day = date.getDay();\n return day === 0 || day === 6;\n }\n\n // Loading state\n setLoading(loading) {\n this.setState({ loading });\n }\n\n // Error handling\n setError(error) {\n this.setState({ error });\n if (error) {\n eventBus.emit('error', { error });\n }\n }\n\n clearError() {\n this.setState({ error: null });\n }\n\n // Configuration\n updateConfig(config) {\n this.setState({ config: { ...this.state.config, ...config } });\n\n // Update calendar configuration if needed\n if (config.weekStartsOn !== undefined) {\n this.calendar.setWeekStartsOn(config.weekStartsOn);\n }\n if (config.locale !== undefined) {\n this.calendar.setLocale(config.locale);\n }\n if (config.timeZone !== undefined) {\n this.calendar.setTimezone(config.timeZone);\n }\n }\n\n // Destroy\n destroy() {\n this.subscribers.clear();\n this.state = null;\n this.calendar = null;\n }\n}\n\n// Export StateManager\nexport default StateManager;","/**\n * DateUtils - Date formatting and manipulation utilities\n *\n * Extends Core DateUtils with UI-specific formatting\n */\n\nimport { DateUtils as CoreDateUtils } from '@forcecalendar/core';\n\nexport class DateUtils extends CoreDateUtils {\n /**\n * Format date for display\n */\n static formatDate(date, format = 'default', locale = 'en-US') {\n if (!date) return '';\n\n const formats = {\n default: { year: 'numeric', month: 'long', day: 'numeric' },\n short: { year: 'numeric', month: 'short', day: 'numeric' },\n long: { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' },\n month: { year: 'numeric', month: 'long' },\n monthShort: { year: 'numeric', month: 'short' },\n day: { weekday: 'long', day: 'numeric' },\n dayShort: { weekday: 'short', day: 'numeric' },\n time: { hour: 'numeric', minute: '2-digit' },\n timeShort: { hour: 'numeric' },\n datetime: {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit'\n }\n };\n\n const options = formats[format] || formats.default;\n return new Intl.DateTimeFormat(locale, options).format(date);\n }\n\n /**\n * Format time for display\n */\n static formatTime(date, showMinutes = true, use24Hour = false, locale = 'en-US') {\n if (!date) return '';\n\n const options = {\n hour: 'numeric',\n minute: showMinutes ? '2-digit' : undefined,\n hour12: !use24Hour\n };\n\n return new Intl.DateTimeFormat(locale, options).format(date);\n }\n\n /**\n * Format date range for display\n */\n static formatDateRange(start, end, locale = 'en-US') {\n if (!start) return '';\n if (!end || this.isSameDay(start, end)) {\n return this.formatDate(start, 'default', locale);\n }\n\n const startFormat = this.isSameYear(start, end) ? 'short' : 'default';\n return `${this.formatDate(start, startFormat, locale)} - ${this.formatDate(end, 'default', locale)}`;\n }\n\n /**\n * Format time range for display\n */\n static formatTimeRange(start, end, locale = 'en-US') {\n if (!start) return '';\n\n const startTime = this.formatTime(start, true, false, locale);\n if (!end) return startTime;\n\n const endTime = this.formatTime(end, true, false, locale);\n return `${startTime} - ${endTime}`;\n }\n\n /**\n * Get relative time string (e.g., \"2 hours ago\", \"in 3 days\")\n */\n static getRelativeTime(date, baseDate = new Date(), locale = 'en-US') {\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n const diff = date - baseDate;\n const diffInSeconds = Math.floor(diff / 1000);\n const diffInMinutes = Math.floor(diffInSeconds / 60);\n const diffInHours = Math.floor(diffInMinutes / 60);\n const diffInDays = Math.floor(diffInHours / 24);\n const diffInWeeks = Math.floor(diffInDays / 7);\n const diffInMonths = Math.floor(diffInDays / 30);\n const diffInYears = Math.floor(diffInDays / 365);\n\n if (Math.abs(diffInSeconds) < 60) {\n return rtf.format(diffInSeconds, 'second');\n } else if (Math.abs(diffInMinutes) < 60) {\n return rtf.format(diffInMinutes, 'minute');\n } else if (Math.abs(diffInHours) < 24) {\n return rtf.format(diffInHours, 'hour');\n } else if (Math.abs(diffInDays) < 7) {\n return rtf.format(diffInDays, 'day');\n } else if (Math.abs(diffInWeeks) < 4) {\n return rtf.format(diffInWeeks, 'week');\n } else if (Math.abs(diffInMonths) < 12) {\n return rtf.format(diffInMonths, 'month');\n } else {\n return rtf.format(diffInYears, 'year');\n }\n }\n\n /**\n * Check if date is today\n */\n static isToday(date) {\n const today = new Date();\n return this.isSameDay(date, today);\n }\n\n /**\n * Check if date is in the past\n */\n static isPast(date) {\n return date < new Date();\n }\n\n /**\n * Check if date is in the future\n */\n static isFuture(date) {\n return date > new Date();\n }\n\n /**\n * Get calendar week number\n */\n static getWeekNumber(date) {\n const firstDayOfYear = new Date(date.getFullYear(), 0, 1);\n const pastDaysOfYear = (date - firstDayOfYear) / 86400000;\n return Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);\n }\n\n /**\n * Get day abbreviation\n */\n static getDayAbbreviation(dayIndex, locale = 'en-US') {\n const date = new Date(2024, 0, 7 + dayIndex); // Jan 7, 2024 is a Sunday\n return new Intl.DateTimeFormat(locale, { weekday: 'short' }).format(date);\n }\n\n /**\n * Get month name\n */\n static getMonthName(monthIndex, format = 'long', locale = 'en-US') {\n const date = new Date(2024, monthIndex, 1);\n return new Intl.DateTimeFormat(locale, { month: format }).format(date);\n }\n\n /**\n * Parse time string (e.g., \"14:30\" or \"2:30 PM\")\n */\n static parseTimeString(timeStr, baseDate = new Date()) {\n const date = new Date(baseDate);\n const [time, period] = timeStr.split(/\\s+/);\n const [hours, minutes] = time.split(':').map(Number);\n\n let adjustedHours = hours;\n if (period) {\n if (period.toLowerCase() === 'pm' && hours < 12) {\n adjustedHours = hours + 12;\n } else if (period.toLowerCase() === 'am' && hours === 12) {\n adjustedHours = 0;\n }\n }\n\n date.setHours(adjustedHours, minutes || 0, 0, 0);\n return date;\n }\n}\n\nexport default DateUtils;","/**\n * DOMUtils - DOM manipulation and event utilities\n */\n\nexport class DOMUtils {\n /**\n * Create element with attributes and children\n */\n static createElement(tag, attributes = {}, children = []) {\n const element = document.createElement(tag);\n\n // Set attributes\n Object.entries(attributes).forEach(([key, value]) => {\n if (key === 'className') {\n element.className = value;\n } else if (key === 'style' && typeof value === 'object') {\n Object.assign(element.style, value);\n } else if (key.startsWith('data-')) {\n element.setAttribute(key, value);\n } else if (key.startsWith('on') && typeof value === 'function') {\n const eventName = key.slice(2).toLowerCase();\n element.addEventListener(eventName, value);\n } else {\n element[key] = value;\n }\n });\n\n // Add children\n children.forEach(child => {\n if (typeof child === 'string') {\n element.appendChild(document.createTextNode(child));\n } else if (child instanceof Node) {\n element.appendChild(child);\n }\n });\n\n return element;\n }\n\n /**\n * Add multiple event listeners\n */\n static addEventListeners(element, events) {\n Object.entries(events).forEach(([event, handler]) => {\n element.addEventListener(event, handler);\n });\n\n // Return cleanup function\n return () => {\n Object.entries(events).forEach(([event, handler]) => {\n element.removeEventListener(event, handler);\n });\n };\n }\n\n /**\n * Delegate event handling\n */\n static delegate(element, selector, event, handler) {\n const delegatedHandler = (e) => {\n const target = e.target.closest(selector);\n if (target && element.contains(target)) {\n handler.call(target, e);\n }\n };\n\n element.addEventListener(event, delegatedHandler);\n return () => element.removeEventListener(event, delegatedHandler);\n }\n\n /**\n * Get element position relative to viewport\n */\n static getPosition(element) {\n const rect = element.getBoundingClientRect();\n return {\n top: rect.top + window.scrollY,\n left: rect.left + window.scrollX,\n bottom: rect.bottom + window.scrollY,\n right: rect.right + window.scrollX,\n width: rect.width,\n height: rect.height\n };\n }\n\n /**\n * Check if element is in viewport\n */\n static isInViewport(element, threshold = 0) {\n const rect = element.getBoundingClientRect();\n return (\n rect.top >= -threshold &&\n rect.left >= -threshold &&\n rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) + threshold &&\n rect.right <= (window.innerWidth || document.documentElement.clientWidth) + threshold\n );\n }\n\n /**\n * Smooth scroll to element\n */\n static scrollToElement(element, options = {}) {\n const { behavior = 'smooth', block = 'start', inline = 'nearest' } = options;\n element.scrollIntoView({ behavior, block, inline });\n }\n\n /**\n * Get computed style value\n */\n static getStyle(element, property) {\n return window.getComputedStyle(element).getPropertyValue(property);\n }\n\n /**\n * Set multiple styles\n */\n static setStyles(element, styles) {\n Object.assign(element.style, styles);\n }\n\n /**\n * Add/remove classes with animation support\n */\n static async animateClass(element, className, duration = 300) {\n element.classList.add(className);\n await this.wait(duration);\n element.classList.remove(className);\n }\n\n /**\n * Wait for animation/transition to complete\n */\n static waitForAnimation(element, eventType = 'animationend') {\n return new Promise(resolve => {\n const handler = () => {\n element.removeEventListener(eventType, handler);\n resolve();\n };\n element.addEventListener(eventType, handler);\n });\n }\n\n /**\n * Utility wait function\n */\n static wait(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n /**\n * Parse HTML string safely\n */\n static parseHTML(htmlString) {\n const template = document.createElement('template');\n template.innerHTML = htmlString.trim();\n return template.content.firstChild;\n }\n\n /**\n * Escape HTML to prevent XSS\n */\n static escapeHTML(str) {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n /**\n * Debounce function calls\n */\n static debounce(func, wait = 250) {\n let timeout;\n return function executedFunction(...args) {\n const later = () => {\n clearTimeout(timeout);\n func(...args);\n };\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n };\n }\n\n /**\n * Throttle function calls\n */\n static throttle(func, limit = 250) {\n let inThrottle;\n return function(...args) {\n if (!inThrottle) {\n func.apply(this, args);\n inThrottle = true;\n setTimeout(() => inThrottle = false, limit);\n }\n };\n }\n\n /**\n * Get closest parent matching selector\n */\n static closest(element, selector) {\n return element.closest(selector);\n }\n\n /**\n * Get all parents matching selector\n */\n static parents(element, selector) {\n const parents = [];\n let parent = element.parentElement;\n\n while (parent) {\n if (parent.matches(selector)) {\n parents.push(parent);\n }\n parent = parent.parentElement;\n }\n\n return parents;\n }\n\n /**\n * Measure element dimensions including margins\n */\n static getOuterDimensions(element) {\n const styles = window.getComputedStyle(element);\n const margin = {\n top: parseInt(styles.marginTop),\n right: parseInt(styles.marginRight),\n bottom: parseInt(styles.marginBottom),\n left: parseInt(styles.marginLeft)\n };\n\n return {\n width: element.offsetWidth + margin.left + margin.right,\n height: element.offsetHeight + margin.top + margin.bottom,\n margin\n };\n }\n\n /**\n * Clone element with event listeners\n */\n static cloneWithEvents(element, deep = true) {\n const clone = element.cloneNode(deep);\n\n // Copy event listeners (Note: This is a simplified version)\n // In production, you'd need a more robust event copying mechanism\n return clone;\n }\n\n /**\n * Focus trap for modals/dialogs\n */\n static trapFocus(container) {\n const focusableElements = container.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n\n // Handle case where there are no focusable elements\n if (focusableElements.length === 0) {\n // Make container focusable as fallback\n container.setAttribute('tabindex', '-1');\n container.focus();\n return () => container.removeAttribute('tabindex');\n }\n\n const firstFocusable = focusableElements[0];\n const lastFocusable = focusableElements[focusableElements.length - 1];\n\n const handleKeyDown = (e) => {\n if (e.key !== 'Tab') return;\n\n if (e.shiftKey) {\n if (document.activeElement === firstFocusable) {\n lastFocusable?.focus();\n e.preventDefault();\n }\n } else {\n if (document.activeElement === lastFocusable) {\n firstFocusable?.focus();\n e.preventDefault();\n }\n }\n };\n\n container.addEventListener('keydown', handleKeyDown);\n firstFocusable?.focus();\n\n return () => container.removeEventListener('keydown', handleKeyDown);\n }\n}\n\nexport default DOMUtils;","/**\n * StyleUtils - Styling utilities and theme management\n */\n\nexport class StyleUtils {\n /**\n * Default theme colors\n */\n static colors = {\n primary: '#3B82F6', // Modern Blue\n secondary: '#64748B', // Slate\n accent: '#F59E0B', // Amber\n danger: '#EF4444', // Red\n warning: '#F97316', // Orange\n info: '#06B6D4', // Cyan\n success: '#22C55E', // Green\n light: '#F8FAFC',\n dark: '#0F172A',\n white: '#FFFFFF',\n gray: {\n 50: '#F8FAFC',\n 100: '#F1F5F9',\n 200: '#E2E8F0',\n 300: '#CBD5E1',\n 400: '#94A3B8',\n 500: '#64748B',\n 600: '#475569',\n 700: '#334155',\n 800: '#1E293B',\n 900: '#0F172A'\n }\n };\n\n /**\n * Common CSS variables\n */\n static cssVariables = {\n // \"Pro\" Palette - Functional & Sharp\n '--fc-primary-color': '#2563EB', // International Blue (Focus)\n '--fc-primary-hover': '#1D4ED8',\n '--fc-primary-light': '#EFF6FF',\n \n // Neutral Scale (Slate/Gray for structure)\n '--fc-text-color': '#111827', // Almost Black\n '--fc-text-secondary': '#6B7280', // Cool Gray\n '--fc-text-light': '#9CA3AF',\n \n '--fc-border-color': '#E5E7EB', // Crisp Light Gray\n '--fc-border-color-hover': '#D1D5DB',\n \n '--fc-background': '#FFFFFF',\n '--fc-background-alt': '#FAFAFA', // Very subtle off-white\n '--fc-background-hover': '#F3F4F6',\n '--fc-background-active': '#E5E7EB',\n\n // Semantic Colors\n '--fc-accent-color': '#F59E0B',\n '--fc-danger-color': '#EF4444',\n '--fc-success-color': '#10B981',\n\n // Typography - optimized for UI density\n '--fc-font-family': 'Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n '--fc-font-size-xs': '11px',\n '--fc-font-size-sm': '12px',\n '--fc-font-size-base': '13px', // Slightly smaller for density\n '--fc-font-size-lg': '15px',\n '--fc-font-size-xl': '18px',\n '--fc-font-size-2xl': '24px',\n '--fc-line-height': '1.4',\n '--fc-font-weight-normal': '400',\n '--fc-font-weight-medium': '500',\n '--fc-font-weight-semibold': '600',\n '--fc-font-weight-bold': '700',\n\n // Spacing - Tighter\n '--fc-spacing-xs': '2px',\n '--fc-spacing-sm': '6px',\n '--fc-spacing-md': '10px',\n '--fc-spacing-lg': '14px',\n '--fc-spacing-xl': '20px',\n '--fc-spacing-2xl': '28px',\n\n // Border\n '--fc-border-width': '1px',\n '--fc-border-radius-sm': '3px', // Micro rounding\n '--fc-border-radius': '5px',\n '--fc-border-radius-lg': '8px',\n '--fc-border-radius-full': '9999px',\n\n // Shadows - Minimal/Functional\n '--fc-shadow-sm': '0 1px 1px rgba(0,0,0,0.05)',\n '--fc-shadow': '0 1px 3px rgba(0,0,0,0.1), 0 1px 2px rgba(0,0,0,0.06)',\n '--fc-shadow-md': '0 4px 6px -1px rgba(0, 0, 0, 0.1)',\n '--fc-shadow-lg': '0 10px 15px -3px rgba(0, 0, 0, 0.1)',\n\n // Transitions - Snappy\n '--fc-transition-fast': '100ms ease-out',\n '--fc-transition': '150ms ease-out',\n '--fc-transition-slow': '250ms ease-out',\n\n // Z-index\n '--fc-z-dropdown': '1000',\n '--fc-z-modal': '2000',\n '--fc-z-tooltip': '3000'\n };\n\n /**\n * Get CSS variable value\n */\n static getCSSVariable(name, element = document.documentElement) {\n return getComputedStyle(element).getPropertyValue(name).trim();\n }\n\n /**\n * Set CSS variables\n */\n static setCSSVariables(variables, element = document.documentElement) {\n Object.entries(variables).forEach(([key, value]) => {\n element.style.setProperty(key, value);\n });\n }\n\n /**\n * Generate base styles\n */\n static getBaseStyles() {\n return `\n :host {\n /* Apply CSS variables */\n ${Object.entries(this.cssVariables)\n .map(([key, value]) => `${key}: ${value};`)\n .join('\\n ')}\n\n /* Base styles */\n display: block;\n box-sizing: border-box;\n font-family: var(--fc-font-family);\n font-size: var(--fc-font-size-base);\n line-height: var(--fc-line-height);\n color: var(--fc-text-color);\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n\n *, *::before, *::after {\n box-sizing: inherit;\n }\n\n /* Reset styles */\n h1, h2, h3, h4, h5, h6, p {\n margin: 0;\n font-weight: normal;\n }\n\n button {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n margin: 0;\n }\n\n /* Accessibility */\n .visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n /* Focus styles */\n :focus-visible {\n outline: 2px solid var(--fc-primary-color);\n outline-offset: 2px;\n }\n `;\n }\n\n /**\n * Generate button styles\n */\n static getButtonStyles() {\n return `\n .fc-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 8px 16px;\n font-size: var(--fc-font-size-sm);\n font-weight: var(--fc-font-weight-medium);\n line-height: 1.25rem;\n border-radius: var(--fc-border-radius);\n border: 1px solid transparent;\n cursor: pointer;\n transition: all var(--fc-transition-fast);\n outline: none;\n user-select: none;\n gap: var(--fc-spacing-sm);\n white-space: nowrap;\n }\n\n .fc-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .fc-btn-primary {\n background: var(--fc-primary-color);\n color: white;\n box-shadow: var(--fc-shadow-sm);\n }\n\n .fc-btn-primary:hover:not(:disabled) {\n background: var(--fc-primary-hover);\n box-shadow: var(--fc-shadow);\n }\n\n .fc-btn-secondary {\n background: white;\n border-color: var(--fc-border-color);\n color: var(--fc-text-color);\n box-shadow: var(--fc-shadow-sm);\n }\n\n .fc-btn-secondary:hover:not(:disabled) {\n background: var(--fc-background-hover);\n border-color: var(--fc-border-color-hover);\n }\n\n .fc-btn-outline {\n background: transparent;\n border-color: var(--fc-border-color);\n color: var(--fc-text-secondary);\n }\n\n .fc-btn-outline:hover:not(:disabled) {\n background: var(--fc-background-hover);\n color: var(--fc-text-color);\n border-color: var(--fc-border-color-hover);\n }\n\n .fc-btn-ghost {\n background: transparent;\n color: var(--fc-text-secondary);\n }\n\n .fc-btn-ghost:hover:not(:disabled) {\n background: var(--fc-background-hover);\n color: var(--fc-text-color);\n }\n\n .fc-btn-sm {\n padding: 6px 12px;\n font-size: var(--fc-font-size-xs);\n }\n\n .fc-btn-lg {\n padding: 10px 20px;\n font-size: var(--fc-font-size-base);\n }\n\n .fc-btn-icon {\n width: 32px;\n height: 32px;\n padding: 0;\n border-radius: var(--fc-border-radius-full);\n }\n `;\n }\n\n /**\n * Darken color by percentage\n */\n static darken(color, percent) {\n const num = parseInt(color.replace('#', ''), 16);\n const amt = Math.round(2.55 * percent);\n const R = (num >> 16) - amt;\n const G = (num >> 8 & 0x00FF) - amt;\n const B = (num & 0x0000FF) - amt;\n return '#' + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +\n (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +\n (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);\n }\n\n /**\n * Lighten color by percentage\n */\n static lighten(color, percent) {\n const num = parseInt(color.replace('#', ''), 16);\n const amt = Math.round(2.55 * percent);\n const R = (num >> 16) + amt;\n const G = (num >> 8 & 0x00FF) + amt;\n const B = (num & 0x0000FF) + amt;\n return '#' + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +\n (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +\n (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);\n }\n\n /**\n * Get contrast color (black or white) for background\n */\n static getContrastColor(bgColor) {\n const color = bgColor.replace('#', '');\n const r = parseInt(color.substr(0, 2), 16);\n const g = parseInt(color.substr(2, 2), 16);\n const b = parseInt(color.substr(4, 2), 16);\n const yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;\n return yiq >= 128 ? '#000000' : '#FFFFFF';\n }\n\n /**\n * Sanitize color value to prevent CSS injection\n * Returns the color if valid, or a fallback color if invalid\n */\n static sanitizeColor(color, fallback = 'var(--fc-primary-color)') {\n if (!color || typeof color !== 'string') {\n return fallback;\n }\n\n // Trim and check for dangerous characters that could break out of CSS\n const trimmed = color.trim();\n if (/[;{}()<>\\\"\\'\\\\]/.test(trimmed)) {\n return fallback;\n }\n\n // Allow hex colors (#RGB, #RRGGBB, #RRGGBBAA)\n if (/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/.test(trimmed)) {\n return trimmed;\n }\n\n // Allow CSS variables\n if (/^var\\(--[a-zA-Z0-9-]+\\)$/.test(trimmed)) {\n return trimmed;\n }\n\n // Allow rgb/rgba with numbers only\n if (/^rgba?\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*(,\\s*(0|1|0?\\.\\d+))?\\s*\\)$/.test(trimmed)) {\n return trimmed;\n }\n\n // Allow safe CSS color keywords\n const safeKeywords = [\n 'transparent', 'currentColor', 'inherit',\n 'black', 'white', 'red', 'green', 'blue', 'yellow', 'orange', 'purple',\n 'pink', 'brown', 'gray', 'grey', 'cyan', 'magenta', 'lime', 'navy',\n 'teal', 'aqua', 'maroon', 'olive', 'silver', 'fuchsia'\n ];\n if (safeKeywords.includes(trimmed.toLowerCase())) {\n return trimmed;\n }\n\n return fallback;\n }\n\n /**\n * Convert hex to rgba\n */\n static hexToRgba(hex, alpha = 1) {\n const color = hex.replace('#', '');\n const r = parseInt(color.substr(0, 2), 16);\n const g = parseInt(color.substr(2, 2), 16);\n const b = parseInt(color.substr(4, 2), 16);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n }\n\n /**\n * Generate grid styles\n */\n static getGridStyles() {\n return `\n .fc-grid {\n display: grid;\n gap: 1px;\n background: var(--fc-border-color);\n border: 1px solid var(--fc-border-color);\n border-radius: var(--fc-border-radius);\n overflow: hidden;\n }\n\n .fc-grid-cell {\n background: var(--fc-background);\n padding: var(--fc-spacing-sm);\n min-height: 100px;\n position: relative;\n }\n\n .fc-grid-cell:hover {\n background: var(--fc-background-hover);\n }\n\n .fc-grid-header {\n background: var(--fc-background-alt);\n padding: var(--fc-spacing-sm);\n font-weight: var(--fc-font-weight-semibold);\n text-align: center;\n color: var(--fc-text-secondary);\n font-size: var(--fc-font-size-xs);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n `;\n }\n\n /**\n * Get responsive breakpoints\n */\n static breakpoints = {\n xs: '320px',\n sm: '576px',\n md: '768px',\n lg: '992px',\n xl: '1200px',\n '2xl': '1400px'\n };\n\n /**\n * Generate media query\n */\n static mediaQuery(breakpoint, styles) {\n const size = this.breakpoints[breakpoint];\n if (!size) return '';\n return `@media (min-width: ${size}) { ${styles} }`;\n }\n\n /**\n * Animation keyframes\n */\n static getAnimations() {\n return `\n @keyframes fc-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n @keyframes fc-slide-in-up {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n @keyframes fc-slide-in-down {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n @keyframes fc-scale-in {\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n @keyframes fc-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n .fc-fade-in {\n animation: fc-fade-in var(--fc-transition);\n }\n\n .fc-slide-in-up {\n animation: fc-slide-in-up var(--fc-transition);\n }\n\n .fc-scale-in {\n animation: fc-scale-in var(--fc-transition);\n }\n `;\n }\n}\n\nexport default StyleUtils;","/**\n * MonthView - Month grid view component\n *\n * Displays a traditional month calendar grid with events\n */\n\nimport { BaseComponent } from '../../core/BaseComponent.js';\nimport { DOMUtils } from '../../utils/DOMUtils.js';\nimport { DateUtils } from '../../utils/DateUtils.js';\nimport { StyleUtils } from '../../utils/StyleUtils.js';\n\nexport class MonthView extends BaseComponent {\n constructor() {\n super();\n this._stateManager = null;\n this.viewData = null;\n this.config = {\n maxEventsToShow: 3,\n };\n this._registryCheckInterval = null;\n }\n\n connectedCallback() {\n super.connectedCallback();\n console.log('[MonthView] connectedCallback - starting registry polling');\n // Poll for registry since attributeChangedCallback doesn't work in Locker Service\n this._startRegistryPolling();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this._stopRegistryPolling();\n }\n\n _startRegistryPolling() {\n // Check immediately\n this._checkRegistry();\n\n // Then poll every 100ms until we find it (max 5 seconds)\n let attempts = 0;\n this._registryCheckInterval = setInterval(() => {\n attempts++;\n if (this._stateManager || attempts > 50) {\n this._stopRegistryPolling();\n return;\n }\n this._checkRegistry();\n }, 100);\n }\n\n _stopRegistryPolling() {\n if (this._registryCheckInterval) {\n clearInterval(this._registryCheckInterval);\n this._registryCheckInterval = null;\n }\n }\n\n _checkRegistry() {\n const registryId = this.getAttribute('data-state-registry');\n console.log('[MonthView] Checking registry for ID:', registryId);\n if (registryId && window.__forceCalendarRegistry && window.__forceCalendarRegistry[registryId]) {\n const manager = window.__forceCalendarRegistry[registryId];\n console.log('[MonthView] Found stateManager in registry');\n this._stopRegistryPolling();\n this.setStateManager(manager);\n }\n }\n\n set stateManager(manager) {\n console.log('[MonthView] stateManager setter called with:', !!manager);\n this.setStateManager(manager);\n }\n\n // Method alternative for Salesforce Locker Service compatibility\n setStateManager(manager) {\n console.log('[MonthView] setStateManager method called with:', !!manager);\n // Prevent re-initialization if same manager\n if (this._stateManager === manager) {\n console.log('[MonthView] stateManager already set, skipping');\n return;\n }\n this._stateManager = manager;\n if (manager) {\n console.log('[MonthView] Subscribing to state changes and loading view data');\n // Subscribe to state changes\n this.unsubscribe = manager.subscribe(this.handleStateUpdate.bind(this));\n this.loadViewData();\n }\n }\n\n get stateManager() {\n return this._stateManager;\n }\n\n handleStateUpdate(newState, oldState) {\n if (newState.currentDate !== oldState.currentDate) {\n this.loadViewData(); // Full reload if the month/year changes\n return;\n }\n\n if (newState.events !== oldState.events) {\n this.updateEvents();\n }\n\n if (newState.selectedDate !== oldState.selectedDate) {\n this.updateSelection(newState.selectedDate, oldState.selectedDate);\n }\n }\n\n updateEvents() {\n this.loadViewData(); // For now, we still do a full reload. A more granular update would be more complex.\n }\n\n updateSelection(newDate, oldDate) {\n if (oldDate) {\n const oldDateEl = this.shadowRoot.querySelector(`[data-date^=\"${oldDate.toISOString().split('T')[0]}\"]`);\n if (oldDateEl) {\n oldDateEl.classList.remove('selected');\n }\n }\n if (newDate) {\n const newDateEl = this.shadowRoot.querySelector(`[data-date^=\"${newDate.toISOString().split('T')[0]}\"]`);\n if (newDateEl) {\n newDateEl.classList.add('selected');\n }\n }\n }\n\n loadViewData() {\n console.log('[MonthView] loadViewData called, stateManager:', !!this.stateManager);\n if (!this.stateManager) return;\n\n const viewData = this.stateManager.getViewData();\n console.log('[MonthView] viewData from stateManager:', viewData);\n this.viewData = this.processViewData(viewData);\n console.log('[MonthView] processed viewData:', this.viewData);\n this.render();\n console.log('[MonthView] render completed');\n }\n\n processViewData(viewData) {\n if (!viewData || !viewData.weeks) return null;\n\n const selectedDate = this.stateManager?.getState()?.selectedDate;\n\n const weeks = viewData.weeks.map(week => {\n return week.days.map(day => {\n const dayDate = new Date(day.date);\n const isSelected = selectedDate && dayDate.toDateString() === selectedDate.toDateString();\n \n const processedEvents = day.events.map(event => ({\n ...event,\n textColor: this.getContrastingTextColor(event.backgroundColor)\n }));\n\n return {\n ...day,\n date: dayDate,\n isOtherMonth: !day.isCurrentMonth,\n isSelected,\n events: processedEvents,\n };\n });\n });\n\n return {\n ...viewData,\n weeks,\n month: viewData.month,\n year: viewData.year\n };\n }\n\n getContrastingTextColor(bgColor) {\n if (!bgColor || typeof bgColor !== 'string') return 'white';\n\n // Extract hex color, removing # if present\n const color = (bgColor.charAt(0) === '#') ? bgColor.substring(1) : bgColor;\n\n // Validate hex format (3 or 6 characters)\n if (!/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(color)) {\n return 'white'; // Fallback for invalid format\n }\n\n // Expand 3-char hex to 6-char\n const fullColor = color.length === 3\n ? color[0] + color[0] + color[1] + color[1] + color[2] + color[2]\n : color;\n\n const r = parseInt(fullColor.substring(0, 2), 16);\n const g = parseInt(fullColor.substring(2, 4), 16);\n const b = parseInt(fullColor.substring(4, 6), 16);\n\n // Check for NaN (shouldn't happen with validation, but just in case)\n if (isNaN(r) || isNaN(g) || isNaN(b)) {\n return 'white';\n }\n\n const uicolors = [r / 255, g / 255, b / 255];\n const c = uicolors.map((col) => {\n if (col <= 0.03928) {\n return col / 12.92;\n }\n return Math.pow((col + 0.055) / 1.055, 2.4);\n });\n const L = (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]);\n return (L > 0.179) ? 'black' : 'white';\n }\n\n isSelectedDate(date) {\n const selectedDate = this.stateManager?.getState()?.selectedDate;\n return selectedDate && date.toDateString() === selectedDate.toDateString();\n }\n\n getStyles() {\n return `\n :host {\n display: block;\n height: 100%;\n }\n\n .month-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n }\n\n .month-header {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n background: var(--fc-background);\n border-bottom: 1px solid var(--fc-border-color);\n z-index: 5;\n }\n\n .month-header-cell {\n padding: var(--fc-spacing-sm);\n text-align: left; /* Align with dates */\n font-weight: var(--fc-font-weight-bold);\n font-size: 10px;\n color: var(--fc-text-light);\n text-transform: uppercase;\n letter-spacing: 0.1em;\n border-left: 1px solid transparent; /* Alignment hack */\n padding-left: 8px;\n }\n\n .month-body {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n .month-week {\n flex: 1;\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n border-bottom: 1px solid var(--fc-border-color);\n }\n \n .month-week:last-child {\n border-bottom: none;\n }\n\n .month-day {\n background: var(--fc-background);\n padding: 4px;\n position: relative;\n cursor: default;\n overflow: hidden;\n min-height: 80px;\n border-right: 1px solid var(--fc-border-color);\n display: flex;\n flex-direction: column;\n min-width: 0; /* Critical for Grid Item shrinking */\n }\n\n .month-day:last-child {\n border-right: none;\n }\n\n .month-day:hover {\n background: var(--fc-background-alt);\n }\n\n .month-day.other-month {\n background: var(--fc-background-alt);\n background-image: linear-gradient(45deg, #f9fafb 25%, transparent 25%, transparent 50%, #f9fafb 50%, #f9fafb 75%, transparent 75%, transparent);\n background-size: 10px 10px;\n }\n\n .month-day.other-month .day-number {\n color: var(--fc-text-light);\n opacity: 0.5;\n }\n\n .month-day.selected {\n background: var(--fc-background-hover);\n }\n\n .day-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px;\n margin-bottom: 2px;\n }\n \n .day-number {\n font-size: 12px;\n font-family: var(--fc-font-family); /* Ensure monospaced feel if available */\n font-weight: var(--fc-font-weight-medium);\n color: var(--fc-text-color);\n line-height: 1;\n }\n \n .month-day.today .day-number {\n color: white;\n background: var(--fc-danger-color); /* Red for Today (Calendar standard) */\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n margin-left: -4px; /* Optical adjustment */\n }\n\n .day-events {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n overflow: hidden;\n }\n\n /* Precision Event Style */\n .event-item {\n font-size: 11px;\n padding: 2px 6px;\n border-radius: 2px; /* Micro rounding */\n \n /* High Contrast */\n background: var(--fc-primary-color);\n color: white;\n \n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n line-height: 1.3;\n font-weight: var(--fc-font-weight-medium);\n margin: 0 1px;\n border: 1px solid rgba(0,0,0,0.05); /* Subtle border for definition */\n }\n\n .event-item:hover {\n opacity: 0.9;\n }\n\n .event-time {\n font-weight: var(--fc-font-weight-bold);\n margin-right: 4px;\n opacity: 0.9;\n font-size: 10px;\n }\n\n .more-events {\n font-size: 10px;\n color: var(--fc-text-secondary);\n cursor: pointer;\n padding: 1px 4px;\n font-weight: var(--fc-font-weight-medium);\n text-align: right;\n }\n\n .more-events:hover {\n color: var(--fc-text-color);\n text-decoration: underline;\n }\n\n /* Responsive adjustments */\n @media (max-width: 768px) {\n .month-day {\n min-height: 60px;\n padding: 2px;\n }\n\n .day-number {\n font-size: 11px;\n }\n\n .event-item {\n font-size: 10px;\n padding: 1px 3px;\n }\n\n .month-header-cell {\n font-size: 9px;\n padding: 4px;\n }\n }\n\n /* Loading state */\n .month-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--fc-text-secondary);\n font-weight: var(--fc-font-weight-medium);\n }\n\n /* Empty state */\n .month-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--fc-text-secondary);\n gap: var(--fc-spacing-md);\n }\n\n .empty-icon {\n width: 48px;\n height: 48px;\n opacity: 0.3;\n }\n `;\n }\n\n template() {\n if (!this.viewData) {\n return `\n <div class=\"month-view\">\n <div class=\"month-loading\">Loading calendar...</div>\n </div>\n `;\n }\n\n return `\n <div class=\"month-view\">\n ${this.renderHeader()}\n ${this.renderBody()}\n </div>\n `;\n }\n\n renderHeader() {\n const { config } = this.stateManager.getState();\n const days = [];\n const weekStartsOn = config.weekStartsOn || 0;\n\n for (let i = 0; i < 7; i++) {\n const dayIndex = (weekStartsOn + i) % 7;\n const dayName = DateUtils.getDayAbbreviation(dayIndex, config.locale);\n days.push(`<div class=\"month-header-cell\">${dayName}</div>`);\n }\n\n return `\n <div class=\"month-header\">\n ${days.join('')}\n </div>\n `;\n }\n\n renderBody() {\n if (!this.viewData.weeks || this.viewData.weeks.length === 0) {\n return `\n <div class=\"month-body\">\n <div class=\"month-empty\">\n <svg class=\"empty-icon\" viewBox=\"0 0 24 24\">\n <path fill=\"currentColor\" d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11z\"/>\n </svg>\n <p>No calendar data available</p>\n </div>\n </div>\n `;\n }\n\n const weeks = this.viewData.weeks.map(week => this.renderWeek(week));\n\n return `\n <div class=\"month-body\">\n ${weeks.join('')}\n </div>\n `;\n }\n\n renderWeek(weekDays) {\n const days = weekDays.map(day => this.renderDay(day));\n\n return `\n <div class=\"month-week\">\n ${days.join('')}\n </div>\n `;\n }\n\n renderDay(dayData) {\n const { date, dayOfMonth, isOtherMonth, isToday, isSelected, isWeekend, events = [] } = dayData;\n const dayNumber = dayOfMonth;\n\n // Build classes\n const classes = ['month-day'];\n if (isOtherMonth) classes.push('other-month');\n if (isToday) classes.push('today');\n if (isSelected) classes.push('selected');\n if (isWeekend) classes.push('weekend');\n\n // Render events\n const visibleEvents = events.slice(0, this.config.maxEventsToShow);\n const remainingCount = events.length - this.config.maxEventsToShow;\n\n const eventsHtml = visibleEvents.map(event => this.renderEvent(event)).join('');\n const moreHtml = remainingCount > 0 ?\n `<div class=\"more-events\">+${remainingCount} more</div>` : '';\n\n return `\n <div class=\"${classes.join(' ')}\"\n data-date=\"${date.toISOString()}\"\n data-day=\"${dayNumber}\">\n <div class=\"day-header\">\n <span class=\"day-number\">${dayNumber}</span>\n </div>\n <div class=\"day-events\">\n ${eventsHtml}\n ${moreHtml}\n </div>\n </div>\n `;\n }\n\n renderEvent(event) {\n const { title, start, allDay, backgroundColor, textColor } = event;\n\n let style = '';\n if (backgroundColor) {\n const safeColor = StyleUtils.sanitizeColor(backgroundColor);\n const safeTextColor = StyleUtils.sanitizeColor(textColor, 'white');\n style += `background-color: ${safeColor}; color: ${safeTextColor};`;\n }\n\n let timeStr = '';\n if (!allDay && start) {\n timeStr = DateUtils.formatTime(new Date(start), false, false);\n }\n\n const classes = ['event-item'];\n if (allDay) classes.push('all-day');\n\n return `\n <div class=\"${classes.join(' ')}\"\n style=\"${style}\"\n data-event-id=\"${event.id}\"\n title=\"${DOMUtils.escapeHTML(title)}\">\n ${timeStr ? `<span class=\"event-time\">${timeStr}</span>` : ''}\n <span class=\"event-title\">${DOMUtils.escapeHTML(title)}</span>\n </div>\n `;\n }\n\n afterRender() {\n // Add click handlers for days\n this.$$('.month-day').forEach(dayEl => {\n this.addListener(dayEl, 'click', this.handleDayClick);\n });\n\n // Add click handlers for events\n this.$$('.event-item').forEach(eventEl => {\n this.addListener(eventEl, 'click', this.handleEventClick);\n });\n\n // Add click handlers for \"more events\"\n this.$$('.more-events').forEach(moreEl => {\n this.addListener(moreEl, 'click', this.handleMoreClick);\n });\n }\n\n handleDayClick(event) {\n event.stopPropagation();\n const dayEl = event.currentTarget;\n const date = new Date(dayEl.dataset.date);\n\n this.stateManager.selectDate(date);\n this.emit('day-click', { date });\n }\n\n handleEventClick(event) {\n event.stopPropagation();\n const eventEl = event.currentTarget;\n const eventId = eventEl.dataset.eventId;\n const calendarEvent = this.stateManager.getEvents().find(e => e.id === eventId);\n\n if (calendarEvent) {\n this.stateManager.selectEvent(calendarEvent);\n this.emit('event-click', { event: calendarEvent });\n }\n }\n\n handleMoreClick(event) {\n event.stopPropagation();\n const dayEl = event.currentTarget.closest('.month-day');\n const date = new Date(dayEl.dataset.date);\n const events = this.stateManager.getEventsForDate(date);\n\n this.emit('more-events-click', { date, events });\n }\n\n unmount() {\n if (this.unsubscribe) {\n this.unsubscribe();\n }\n }\n}\n\n// Export both the class and as default\nexport default MonthView;","/**\n * WeekView - Professional Time-Grid Week View\n * \n * Displays a 7-day schedule with a time axis and event positioning.\n */\n\nimport { BaseComponent } from '../../core/BaseComponent.js';\nimport { DateUtils } from '../../utils/DateUtils.js';\nimport { StyleUtils } from '../../utils/StyleUtils.js';\nimport { DOMUtils } from '../../utils/DOMUtils.js';\n\nexport class WeekView extends BaseComponent {\n constructor() {\n super();\n this._stateManager = null;\n this.viewData = null;\n this.hours = Array.from({ length: 24 }, (_, i) => i); // 0-23\n this._registryCheckInterval = null;\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._startRegistryPolling();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n if (this._registryCheckInterval) {\n clearInterval(this._registryCheckInterval);\n }\n }\n\n _startRegistryPolling() {\n this._checkRegistry();\n let attempts = 0;\n this._registryCheckInterval = setInterval(() => {\n attempts++;\n if (this._stateManager || attempts > 50) {\n clearInterval(this._registryCheckInterval);\n return;\n }\n this._checkRegistry();\n }, 100);\n }\n\n _checkRegistry() {\n const registryId = this.getAttribute('data-state-registry');\n if (registryId && window.__forceCalendarRegistry && window.__forceCalendarRegistry[registryId]) {\n clearInterval(this._registryCheckInterval);\n this.setStateManager(window.__forceCalendarRegistry[registryId]);\n }\n }\n\n set stateManager(manager) {\n this.setStateManager(manager);\n }\n\n setStateManager(manager) {\n if (this._stateManager === manager) return;\n this._stateManager = manager;\n if (manager) {\n this.unsubscribe = manager.subscribe(this.handleStateUpdate.bind(this));\n this.loadViewData();\n }\n }\n\n get stateManager() {\n return this._stateManager;\n }\n\n handleStateUpdate(newState, oldState) {\n // Granular updates\n if (newState.currentDate !== oldState?.currentDate || newState.view !== oldState?.view) {\n this.loadViewData();\n return;\n }\n\n if (newState.events !== oldState?.events) {\n this.loadViewData(); // Simple reload for now\n }\n\n if (newState.selectedDate !== oldState?.selectedDate) {\n this.updateSelection(newState.selectedDate, oldState?.selectedDate);\n }\n }\n\n updateSelection(newDate, oldDate) {\n // Selection in WeekView is often visual on the column\n if (oldDate) {\n const oldDayEl = this.shadowRoot.querySelector(`[data-date^=\"${oldDate.toISOString().split('T')[0]}\"]`);\n if (oldDayEl) oldDayEl.classList.remove('selected');\n }\n if (newDate) {\n const newDayEl = this.shadowRoot.querySelector(`[data-date^=\"${newDate.toISOString().split('T')[0]}\"]`);\n if (newDayEl) newDayEl.classList.add('selected');\n }\n }\n\n loadViewData() {\n if (!this.stateManager) return;\n const viewData = this.stateManager.getViewData();\n this.viewData = this.processViewData(viewData);\n this.render();\n }\n\n processViewData(viewData) {\n if (!viewData) return null;\n\n let days = [];\n if (viewData.weeks && viewData.weeks.length > 0) {\n days = viewData.weeks[0].days;\n } else if (viewData.days) {\n days = viewData.days;\n }\n\n if (!days || days.length === 0) return null;\n\n return {\n ...viewData,\n days: days.map(day => {\n const dayDate = new Date(day.date);\n return {\n ...day,\n date: dayDate,\n isToday: DateUtils.isToday(dayDate),\n timedEvents: (day.events || []).filter(e => !e.allDay),\n allDayEvents: (day.events || []).filter(e => e.allDay)\n };\n })\n };\n }\n\n getStyles() {\n return `\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n }\n\n .week-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n min-height: 0;\n overflow: hidden;\n }\n\n /* Header Section */\n .week-header {\n display: grid;\n grid-template-columns: 60px repeat(7, 1fr);\n border-bottom: 1px solid var(--fc-border-color);\n background: var(--fc-background);\n z-index: 20;\n flex-shrink: 0;\n }\n\n .day-column-header {\n padding: 12px 8px;\n text-align: center;\n border-right: 1px solid var(--fc-border-color);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n }\n\n .day-name {\n font-size: 10px;\n font-weight: 700;\n color: var(--fc-text-light);\n text-transform: uppercase;\n letter-spacing: 0.1em;\n }\n\n .day-number {\n font-size: 16px;\n font-weight: 500;\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n color: var(--fc-text-color);\n }\n\n .is-today .day-number {\n background: var(--fc-danger-color);\n color: white;\n font-weight: 700;\n }\n\n /* All Day Events Row */\n .all-day-row {\n display: grid;\n grid-template-columns: 60px repeat(7, 1fr);\n border-bottom: 1px solid var(--fc-border-color);\n background: var(--fc-background-alt);\n min-height: 32px;\n flex-shrink: 0;\n }\n\n .all-day-label {\n font-size: 9px;\n color: var(--fc-text-light);\n display: flex;\n align-items: center;\n justify-content: center;\n border-right: 1px solid var(--fc-border-color);\n text-transform: uppercase;\n font-weight: 700;\n }\n\n .all-day-cell {\n border-right: 1px solid var(--fc-border-color);\n padding: 4px;\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n /* Body Section */\n .week-body {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n position: relative;\n display: grid;\n grid-template-columns: 60px repeat(7, 1fr);\n background: var(--fc-background);\n }\n\n .time-gutter {\n border-right: 1px solid var(--fc-border-color);\n background: var(--fc-background-alt);\n height: 1440px;\n }\n\n .time-slot-label {\n height: 60px;\n font-size: 10px;\n color: var(--fc-text-light);\n text-align: right;\n padding-right: 8px;\n font-weight: 500;\n }\n\n .day-column {\n border-right: 1px solid var(--fc-border-color);\n position: relative;\n height: 1440px;\n }\n\n .day-column.selected {\n background: var(--fc-background-hover);\n }\n\n /* Grid Lines Layer */\n .grid-lines {\n position: absolute;\n top: 0;\n left: 60px;\n right: 0;\n bottom: 0;\n pointer-events: none;\n }\n\n .grid-line {\n height: 60px;\n border-bottom: 1px solid var(--fc-border-color);\n width: 100%;\n }\n \n .grid-line:last-child {\n border-bottom: none;\n }\n\n .event-container {\n position: absolute;\n left: 2px;\n right: 2px;\n border-radius: 4px;\n padding: 4px 8px;\n font-size: 11px;\n font-weight: 500;\n color: white;\n background: var(--fc-primary-color);\n border: 1px solid rgba(0,0,0,0.1);\n overflow: hidden;\n box-shadow: var(--fc-shadow-sm);\n cursor: pointer;\n transition: transform 0.1s;\n z-index: 5;\n }\n\n .event-container:hover {\n z-index: 10;\n transform: scale(1.02);\n }\n\n .now-indicator {\n position: absolute;\n left: 0;\n right: 0;\n height: 2px;\n background: var(--fc-danger-color);\n z-index: 15;\n pointer-events: none;\n }\n `;\n }\n\n template() {\n if (!this.viewData) return '<div class=\"week-view\">Loading...</div>';\n\n return `\n <div class=\"week-view\">\n <div class=\"week-header\">\n <div class=\"time-gutter-header\"></div>\n ${this.viewData.days.map(day => `\n <div class=\"day-column-header ${day.isToday ? 'is-today' : ''}\">\n <span class=\"day-name\">${DateUtils.getDayAbbreviation(day.date.getDay())}</span>\n <span class=\"day-number\">${day.date.getDate()}</span>\n </div>\n `).join('')}\n </div>\n\n <div class=\"all-day-row\">\n <div class=\"all-day-label\">All day</div>\n ${this.viewData.days.map(day => `\n <div class=\"all-day-cell\">\n ${day.allDayEvents.map(e => this.renderAllDayEvent(e)).join('')}\n </div>\n `).join('')}\n </div>\n\n <div class=\"week-body\" id=\"scroll-container\">\n <div class=\"grid-lines\">\n ${this.hours.map(() => `<div class=\"grid-line\"></div>`).join('')}\n </div>\n\n <div class=\"time-gutter\">\n ${this.hours.map(h => `\n <div class=\"time-slot-label\">\n ${h === 0 ? '' : DateUtils.formatTime(new Date().setHours(h, 0), false)}\n </div>\n `).join('')}\n </div>\n\n ${this.viewData.days.map(day => `\n <div class=\"day-column\" data-date=\"${day.date.toISOString()}\">\n ${day.isToday ? this.renderNowIndicator() : ''}\n ${day.timedEvents.map(e => this.renderTimedEvent(e)).join('')}\n </div>\n `).join('')}\n </div>\n </div>\n `;\n }\n\n renderTimedEvent(event) {\n const start = new Date(event.start);\n const end = new Date(event.end);\n\n const startMinutes = start.getHours() * 60 + start.getMinutes();\n const durationMinutes = (end - start) / (1000 * 60);\n\n const top = startMinutes;\n const height = Math.max(durationMinutes, 20);\n\n const color = StyleUtils.sanitizeColor(event.backgroundColor);\n const textColor = StyleUtils.sanitizeColor(StyleUtils.getContrastColor(color), 'white');\n\n return `\n <div class=\"event-container\"\n style=\"top: ${top}px; height: ${height}px; background-color: ${color}; color: ${textColor};\"\n data-event-id=\"${event.id}\">\n <span class=\"event-title\">${DOMUtils.escapeHTML(event.title)}</span>\n <span class=\"event-time\">${DateUtils.formatTime(start)}</span>\n </div>\n `;\n }\n\n renderAllDayEvent(event) {\n const color = StyleUtils.sanitizeColor(event.backgroundColor);\n const textColor = StyleUtils.sanitizeColor(StyleUtils.getContrastColor(color), 'white');\n\n return `\n <div class=\"event-item\"\n style=\"background-color: ${color}; color: ${textColor}; font-size: 10px; padding: 2px 4px; border-radius: 2px; cursor: pointer; margin-bottom: 2px;\"\n data-event-id=\"${event.id}\">\n ${DOMUtils.escapeHTML(event.title)}\n </div>\n `;\n }\n\n renderNowIndicator() {\n const now = new Date();\n const minutes = now.getHours() * 60 + now.getMinutes();\n return `<div class=\"now-indicator\" style=\"top: ${minutes}px\"></div>`;\n }\n\n afterRender() {\n const container = this.$('#scroll-container');\n if (container && !this._scrolled) {\n container.scrollTop = 8 * 60 - 50;\n this._scrolled = true;\n }\n\n this.$$('[data-event-id]').forEach(el => {\n this.addListener(el, 'click', (e) => {\n e.stopPropagation();\n const eventId = e.currentTarget.dataset.eventId;\n const event = this.stateManager.getEvents().find(ev => ev.id === eventId);\n if (event) this.emit('event-click', { event });\n });\n });\n\n this.$$('.day-column').forEach(el => {\n this.addListener(el, 'click', (e) => {\n const col = e.currentTarget;\n const container = this.$('#scroll-container');\n const rect = col.getBoundingClientRect();\n const y = e.clientY - rect.top + (container ? container.scrollTop : 0);\n \n const date = new Date(col.dataset.date);\n date.setHours(Math.floor(y / 60), Math.floor(y % 60), 0, 0);\n \n this.stateManager.selectDate(date);\n this.emit('day-click', { date });\n });\n });\n }\n\n unmount() {\n if (this.unsubscribe) this.unsubscribe();\n }\n}\n\nexport default WeekView;\n","/**\n * DayView - Professional Time-Grid Day View\n * \n * Displays a single day schedule with a time axis and event positioning.\n */\n\nimport { BaseComponent } from '../../core/BaseComponent.js';\nimport { DateUtils } from '../../utils/DateUtils.js';\nimport { StyleUtils } from '../../utils/StyleUtils.js';\nimport { DOMUtils } from '../../utils/DOMUtils.js';\n\nexport class DayView extends BaseComponent {\n constructor() {\n super();\n this._stateManager = null;\n this.viewData = null;\n this.hours = Array.from({ length: 24 }, (_, i) => i);\n this._registryCheckInterval = null;\n }\n\n connectedCallback() {\n super.connectedCallback();\n this._startRegistryPolling();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n if (this._registryCheckInterval) {\n clearInterval(this._registryCheckInterval);\n }\n }\n\n _startRegistryPolling() {\n this._checkRegistry();\n let attempts = 0;\n this._registryCheckInterval = setInterval(() => {\n attempts++;\n if (this._stateManager || attempts > 50) {\n clearInterval(this._registryCheckInterval);\n return;\n }\n this._checkRegistry();\n }, 100);\n }\n\n _checkRegistry() {\n const registryId = this.getAttribute('data-state-registry');\n if (registryId && window.__forceCalendarRegistry && window.__forceCalendarRegistry[registryId]) {\n clearInterval(this._registryCheckInterval);\n this.setStateManager(window.__forceCalendarRegistry[registryId]);\n }\n }\n\n set stateManager(manager) {\n this.setStateManager(manager);\n }\n\n setStateManager(manager) {\n if (this._stateManager === manager) return;\n this._stateManager = manager;\n if (manager) {\n this.unsubscribe = manager.subscribe(this.handleStateUpdate.bind(this));\n this.loadViewData();\n }\n }\n\n get stateManager() {\n return this._stateManager;\n }\n\n handleStateUpdate(newState, oldState) {\n // Granular updates\n if (newState.currentDate !== oldState?.currentDate || newState.view !== oldState?.view) {\n this.loadViewData();\n return;\n }\n\n if (newState.events !== oldState?.events) {\n this.loadViewData(); // Simple reload for now\n }\n\n if (newState.selectedDate !== oldState?.selectedDate) {\n this.updateSelection(newState.selectedDate, oldState?.selectedDate);\n }\n }\n\n updateSelection(newDate, oldDate) {\n const dayCol = this.shadowRoot.querySelector('.day-column');\n if (!dayCol) return;\n\n const isMatch = (date) => date && DateUtils.isSameDay(date, new Date(dayCol.dataset.date));\n \n if (isMatch(newDate)) {\n dayCol.classList.add('selected');\n } else {\n dayCol.classList.remove('selected');\n }\n }\n\n loadViewData() {\n if (!this.stateManager) return;\n const viewData = this.stateManager.getViewData();\n this.viewData = this.processViewData(viewData);\n this.render();\n }\n\n processViewData(viewData) {\n if (!viewData) return null;\n\n let dayData = null;\n const currentState = this.stateManager?.getState();\n const currentDate = currentState?.currentDate || new Date();\n\n if (viewData.days && Array.isArray(viewData.days) && viewData.days.length > 0) {\n dayData = viewData.days.find(d => DateUtils.isSameDay(new Date(d.date), currentDate)) || viewData.days[0];\n } \n else if (viewData.weeks && Array.isArray(viewData.weeks) && viewData.weeks.length > 0) {\n const allDays = viewData.weeks.flatMap(w => w.days || []);\n dayData = allDays.find(d => DateUtils.isSameDay(new Date(d.date), currentDate)) || allDays[0];\n }\n else if (viewData.date) {\n dayData = viewData;\n }\n\n if (!dayData) return null;\n\n const dayDate = new Date(dayData.date);\n return {\n ...viewData,\n day: {\n ...dayData,\n date: dayDate,\n isToday: DateUtils.isToday(dayDate),\n timedEvents: (dayData.events || []).filter(e => !e.allDay),\n allDayEvents: (dayData.events || []).filter(e => e.allDay)\n }\n };\n }\n\n getStyles() {\n return `\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n }\n\n .day-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n min-height: 0;\n overflow: hidden;\n }\n\n /* Header */\n .day-header {\n display: grid;\n grid-template-columns: 60px 1fr;\n border-bottom: 1px solid var(--fc-border-color);\n background: var(--fc-background);\n z-index: 20;\n flex-shrink: 0;\n }\n\n .day-column-header {\n padding: 16px 24px;\n text-align: left;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .day-name {\n font-size: 12px;\n font-weight: 700;\n color: var(--fc-text-light);\n text-transform: uppercase;\n letter-spacing: 0.1em;\n }\n\n .day-number {\n font-size: 24px;\n font-weight: 600;\n color: var(--fc-text-color);\n }\n\n .is-today .day-number {\n color: var(--fc-danger-color);\n }\n\n /* All Day Events */\n .all-day-row {\n display: grid;\n grid-template-columns: 60px 1fr;\n border-bottom: 1px solid var(--fc-border-color);\n background: var(--fc-background-alt);\n min-height: 36px;\n flex-shrink: 0;\n }\n\n .all-day-label {\n font-size: 9px;\n color: var(--fc-text-light);\n display: flex;\n align-items: center;\n justify-content: center;\n border-right: 1px solid var(--fc-border-color);\n text-transform: uppercase;\n font-weight: 700;\n }\n\n .all-day-cell {\n padding: 6px 12px;\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n }\n\n /* Body */\n .day-body {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n position: relative;\n display: grid;\n grid-template-columns: 60px 1fr;\n background: var(--fc-background);\n }\n\n .time-gutter {\n border-right: 1px solid var(--fc-border-color);\n background: var(--fc-background-alt);\n height: 1440px;\n }\n\n .time-slot-label {\n height: 60px;\n font-size: 11px;\n color: var(--fc-text-light);\n text-align: right;\n padding-right: 12px;\n font-weight: 500;\n }\n\n .day-column {\n position: relative;\n height: 1440px;\n }\n\n .day-column.selected {\n background: var(--fc-background-hover);\n }\n\n /* Grid Lines */\n .grid-lines {\n position: absolute;\n top: 0;\n left: 60px;\n right: 0;\n bottom: 0;\n pointer-events: none;\n }\n\n .grid-line {\n height: 60px;\n border-bottom: 1px solid var(--fc-border-color);\n width: 100%;\n }\n\n /* Event Style */\n .event-container {\n position: absolute;\n left: 12px;\n right: 24px;\n border-radius: 6px;\n padding: 8px 12px;\n font-size: 13px;\n font-weight: 500;\n color: white;\n background: var(--fc-primary-color);\n border: 1px solid rgba(0,0,0,0.1);\n overflow: hidden;\n box-shadow: var(--fc-shadow);\n cursor: pointer;\n transition: all 0.15s ease;\n z-index: 5;\n }\n\n .event-container:hover {\n z-index: 10;\n transform: translateX(4px);\n }\n\n .now-indicator {\n position: absolute;\n left: 0;\n right: 0;\n height: 2px;\n background: var(--fc-danger-color);\n z-index: 15;\n pointer-events: none;\n }\n `;\n }\n\n template() {\n if (!this.viewData || !this.viewData.day) {\n return '<div class=\"day-view\" style=\"padding: 20px; color: var(--fc-text-light);\">No data available.</div>';\n }\n\n const { day } = this.viewData;\n const locale = this.stateManager?.state?.config?.locale || 'en-US';\n const dayName = DateUtils.formatDate(day.date, 'day', locale).split(' ')[0];\n\n return `\n <div class=\"day-view\">\n <div class=\"day-header\">\n <div class=\"time-gutter-header\"></div>\n <div class=\"day-column-header ${day.isToday ? 'is-today' : ''}\">\n <span class=\"day-name\">${dayName}</span>\n <span class=\"day-number\">${day.date.getDate()}</span>\n </div>\n </div>\n\n <div class=\"all-day-row\">\n <div class=\"all-day-label\">All day</div>\n <div class=\"all-day-cell\">\n ${day.allDayEvents.map(e => this.renderAllDayEvent(e)).join('')}\n </div>\n </div>\n\n <div class=\"day-body\" id=\"scroll-container\">\n <div class=\"grid-lines\">\n ${this.hours.map(() => `<div class=\"grid-line\"></div>`).join('')}\n </div>\n\n <div class=\"time-gutter\">\n ${this.hours.map(h => `\n <div class=\"time-slot-label\">\n ${h === 0 ? '' : DateUtils.formatTime(new Date().setHours(h, 0), false)}\n </div>\n `).join('')}\n </div>\n\n <div class=\"day-column\" data-date=\"${day.date.toISOString()}\">\n ${day.isToday ? this.renderNowIndicator() : ''}\n ${day.timedEvents.map(e => this.renderTimedEvent(e)).join('')}\n </div>\n </div>\n </div>\n `;\n }\n\n renderTimedEvent(event) {\n const start = new Date(event.start);\n const end = new Date(event.end);\n\n const startMinutes = start.getHours() * 60 + start.getMinutes();\n const durationMinutes = (end - start) / (1000 * 60);\n\n const top = startMinutes;\n const height = Math.max(durationMinutes, 30);\n\n const color = StyleUtils.sanitizeColor(event.backgroundColor);\n const textColor = StyleUtils.sanitizeColor(StyleUtils.getContrastColor(color), 'white');\n\n return `\n <div class=\"event-container\"\n style=\"top: ${top}px; height: ${height}px; background-color: ${color}; color: ${textColor};\"\n data-event-id=\"${event.id}\">\n <span class=\"event-title\">${DOMUtils.escapeHTML(event.title)}</span>\n <span class=\"event-time\">${DateUtils.formatTime(start)} - ${DateUtils.formatTime(end)}</span>\n </div>\n `;\n }\n\n renderAllDayEvent(event) {\n const color = StyleUtils.sanitizeColor(event.backgroundColor);\n const textColor = StyleUtils.sanitizeColor(StyleUtils.getContrastColor(color), 'white');\n\n return `\n <div class=\"event-item\"\n style=\"background-color: ${color}; color: ${textColor}; font-size: 12px; padding: 4px 8px; border-radius: 4px; cursor: pointer; font-weight: 500; margin-bottom: 2px;\"\n data-event-id=\"${event.id}\">\n ${DOMUtils.escapeHTML(event.title)}\n </div>\n `;\n }\n\n renderNowIndicator() {\n const now = new Date();\n const minutes = now.getHours() * 60 + now.getMinutes();\n return `<div class=\"now-indicator\" style=\"top: ${minutes}px\"></div>`;\n }\n\n afterRender() {\n const container = this.$('#scroll-container');\n if (container && !this._scrolled) {\n container.scrollTop = 8 * 60 - 50;\n this._scrolled = true;\n }\n\n this.$$('[data-event-id]').forEach(el => {\n this.addListener(el, 'click', (e) => {\n e.stopPropagation();\n const eventId = e.currentTarget.dataset.eventId;\n const event = this.stateManager.getEvents().find(ev => ev.id === eventId);\n if (event) this.emit('event-click', { event });\n });\n });\n\n const dayCol = this.$('.day-column');\n if (dayCol) {\n this.addListener(dayCol, 'click', (e) => {\n const col = e.currentTarget;\n const container = this.$('#scroll-container');\n const rect = col.getBoundingClientRect();\n const y = e.clientY - rect.top + (container ? container.scrollTop : 0);\n \n const date = new Date(col.dataset.date);\n date.setHours(Math.floor(y / 60), Math.floor(y % 60), 0, 0);\n \n this.stateManager.selectDate(date);\n this.emit('day-click', { date });\n });\n }\n }\n\n unmount() {\n if (this.unsubscribe) this.unsubscribe();\n }\n}\n\nexport default DayView;\n","import { BaseComponent } from '../core/BaseComponent.js';\nimport { StyleUtils } from '../utils/StyleUtils.js';\nimport { DOMUtils } from '../utils/DOMUtils.js';\n\nexport class EventForm extends BaseComponent {\n constructor() {\n super();\n this._isVisible = false;\n this._cleanupFocusTrap = null;\n this.config = {\n title: 'New Event',\n defaultDuration: 60, // minutes\n colors: [\n { color: '#2563EB', label: 'Blue' },\n { color: '#10B981', label: 'Green' },\n { color: '#F59E0B', label: 'Amber' },\n { color: '#EF4444', label: 'Red' },\n { color: '#8B5CF6', label: 'Purple' },\n { color: '#6B7280', label: 'Gray' }\n ]\n };\n this._formData = {\n title: '',\n start: new Date(),\n end: new Date(),\n allDay: false,\n color: this.config.colors[0].color\n };\n }\n\n static get observedAttributes() {\n return ['open'];\n }\n\n attributeChangedCallback(name, oldValue, newValue) {\n if (name === 'open') {\n if (newValue !== null) {\n this.open();\n } else {\n this.close();\n }\n }\n }\n\n getStyles() {\n return `\n ${StyleUtils.getBaseStyles()}\n ${StyleUtils.getButtonStyles()}\n\n :host {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: var(--fc-z-modal);\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(2px);\n }\n\n :host([open]) {\n display: flex;\n }\n\n .modal-content {\n background: var(--fc-background);\n width: 400px;\n max-width: 90vw;\n border-radius: var(--fc-border-radius-lg);\n box-shadow: var(--fc-shadow-lg);\n border: 1px solid var(--fc-border-color);\n display: flex;\n flex-direction: column;\n animation: fc-scale-in var(--fc-transition);\n }\n\n .modal-header {\n padding: var(--fc-spacing-lg);\n border-bottom: 1px solid var(--fc-border-color);\n display: flex;\n align-items: center;\n justify-content: space-between;\n }\n\n .modal-title {\n font-size: var(--fc-font-size-lg);\n font-weight: var(--fc-font-weight-semibold);\n color: var(--fc-text-color);\n }\n\n .close-btn {\n background: transparent;\n border: none;\n color: var(--fc-text-secondary);\n cursor: pointer;\n padding: 4px;\n border-radius: var(--fc-border-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .close-btn:hover {\n background: var(--fc-background-hover);\n color: var(--fc-text-color);\n }\n\n .modal-body {\n padding: var(--fc-spacing-lg);\n display: flex;\n flex-direction: column;\n gap: var(--fc-spacing-md);\n }\n\n .form-group {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n label {\n font-size: var(--fc-font-size-sm);\n font-weight: var(--fc-font-weight-medium);\n color: var(--fc-text-secondary);\n }\n\n input[type=\"text\"],\n input[type=\"datetime-local\"],\n select {\n padding: 8px 12px;\n border: 1px solid var(--fc-border-color);\n border-radius: var(--fc-border-radius);\n font-family: var(--fc-font-family);\n font-size: var(--fc-font-size-base);\n color: var(--fc-text-color);\n background: var(--fc-background);\n transition: border-color var(--fc-transition-fast);\n }\n\n input:focus,\n select:focus {\n outline: none;\n border-color: var(--fc-primary-color);\n box-shadow: 0 0 0 2px var(--fc-primary-light);\n }\n\n .row {\n display: flex;\n gap: var(--fc-spacing-md);\n }\n \n .row .form-group {\n flex: 1;\n }\n\n .modal-footer {\n padding: var(--fc-spacing-lg);\n border-top: 1px solid var(--fc-border-color);\n display: flex;\n justify-content: flex-end;\n gap: var(--fc-spacing-md);\n background: var(--fc-background-alt);\n border-bottom-left-radius: var(--fc-border-radius-lg);\n border-bottom-right-radius: var(--fc-border-radius-lg);\n }\n\n /* Color picker style */\n .color-options {\n display: flex;\n gap: 8px;\n margin-top: 4px;\n }\n\n .color-btn {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n cursor: pointer;\n border: 2px solid transparent;\n transition: transform var(--fc-transition-fast), border-color var(--fc-transition-fast);\n padding: 0;\n position: relative;\n }\n\n .color-btn:hover {\n transform: scale(1.1);\n }\n\n .color-btn.selected {\n border-color: var(--fc-text-color);\n box-shadow: 0 0 0 2px var(--fc-background), 0 0 0 4px var(--fc-primary-color);\n }\n\n .color-btn:focus {\n outline: none;\n box-shadow: 0 0 0 2px var(--fc-background), 0 0 0 4px var(--fc-primary-color);\n }\n\n .error-message {\n color: var(--fc-danger-color);\n font-size: 11px;\n margin-top: 2px;\n display: none;\n }\n\n .form-group.has-error .error-message {\n display: block;\n }\n\n .form-group.has-error input {\n border-color: var(--fc-danger-color);\n }\n `;\n }\n\n template() {\n return `\n <div class=\"modal-content\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"modal-title\">\n <header class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"modal-title\">${this.config.title}</h3>\n <button class=\"close-btn\" id=\"close-x\" aria-label=\"Close modal\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6l12 12\"></path>\n </svg>\n </button>\n </header>\n \n <div class=\"modal-body\">\n <div class=\"form-group\" id=\"title-group\">\n <label for=\"event-title\">Title</label>\n <input type=\"text\" id=\"event-title\" placeholder=\"Event name\" autofocus required>\n <span class=\"error-message\">Title is required</span>\n </div>\n\n <div class=\"row\">\n <div class=\"form-group\" id=\"start-group\">\n <label for=\"event-start\">Start</label>\n <input type=\"datetime-local\" id=\"event-start\" required>\n </div>\n <div class=\"form-group\" id=\"end-group\">\n <label for=\"event-end\">End</label>\n <input type=\"datetime-local\" id=\"event-end\" required>\n <span class=\"error-message\">End time must be after start time</span>\n </div>\n </div>\n\n <div class=\"form-group\">\n <label id=\"color-label\">Color</label>\n <div class=\"color-options\" id=\"color-picker\" role=\"radiogroup\" aria-labelledby=\"color-label\">\n ${this.config.colors.map(c => `\n <button type=\"button\" \n class=\"color-btn ${c.color === this._formData.color ? 'selected' : ''}\" \n style=\"background-color: ${c.color}\" \n data-color=\"${c.color}\"\n title=\"${c.label}\"\n aria-label=\"${c.label}\"\n aria-checked=\"${c.color === this._formData.color ? 'true' : 'false'}\"\n role=\"radio\"></button>\n `).join('')}\n </div>\n </div>\n </div>\n\n <footer class=\"modal-footer\">\n <button class=\"fc-btn fc-btn-secondary\" id=\"cancel-btn\">Cancel</button>\n <button class=\"fc-btn fc-btn-primary\" id=\"save-btn\">Save Event</button>\n </footer>\n </div>\n `;\n }\n\n afterRender() {\n // Bind elements\n this.modalContent = this.$('.modal-content');\n this.titleInput = this.$('#event-title');\n this.startInput = this.$('#event-start');\n this.endInput = this.$('#event-end');\n this.colorContainer = this.$('#color-picker');\n \n this.titleGroup = this.$('#title-group');\n this.endGroup = this.$('#end-group');\n\n // Event Listeners using addListener for automatic cleanup\n this.addListener(this.$('#close-x'), 'click', () => this.close());\n this.addListener(this.$('#cancel-btn'), 'click', () => this.close());\n this.addListener(this.$('#save-btn'), 'click', () => this.save());\n\n this.colorContainer.querySelectorAll('.color-btn').forEach(btn => {\n this.addListener(btn, 'click', (e) => {\n this._formData.color = e.currentTarget.dataset.color;\n this.updateColorSelection();\n });\n });\n\n // Close on backdrop click\n this.addListener(this, 'click', (e) => {\n if (e.target === this) this.close();\n });\n\n // Close on Escape key - remove old listener before adding new one\n if (this._handleKeyDown) {\n window.removeEventListener('keydown', this._handleKeyDown);\n }\n this._handleKeyDown = (e) => {\n if (e.key === 'Escape' && this.hasAttribute('open')) {\n this.close();\n }\n };\n window.addEventListener('keydown', this._handleKeyDown);\n }\n\n updateColorSelection() {\n const buttons = this.colorContainer.querySelectorAll('.color-btn');\n buttons.forEach(btn => {\n const isSelected = btn.dataset.color === this._formData.color;\n btn.classList.toggle('selected', isSelected);\n btn.setAttribute('aria-checked', isSelected ? 'true' : 'false');\n });\n }\n\n open(initialDate = new Date()) {\n if (!this.hasAttribute('open')) {\n this.setAttribute('open', '');\n }\n \n // Reset errors\n this.titleGroup.classList.remove('has-error');\n this.endGroup.classList.remove('has-error');\n\n // Initialize form data\n this._formData.start = initialDate;\n this._formData.end = new Date(initialDate.getTime() + this.config.defaultDuration * 60 * 1000);\n this._formData.title = '';\n this._formData.color = this.config.colors[0].color;\n \n // Update inputs\n if (this.startInput) {\n this.titleInput.value = '';\n this.startInput.value = this.formatDateForInput(this._formData.start);\n this.endInput.value = this.formatDateForInput(this._formData.end);\n this.updateColorSelection();\n \n // Focus trapping\n this._cleanupFocusTrap = DOMUtils.trapFocus(this.modalContent);\n }\n }\n\n close() {\n this.removeAttribute('open');\n if (this._cleanupFocusTrap) {\n this._cleanupFocusTrap();\n this._cleanupFocusTrap = null;\n }\n }\n\n validate() {\n let isValid = true;\n \n // Reset errors\n this.titleGroup.classList.remove('has-error');\n this.endGroup.classList.remove('has-error');\n\n // Check title\n if (!this.titleInput.value.trim()) {\n this.titleGroup.classList.add('has-error');\n isValid = false;\n }\n\n // Check date range\n const start = new Date(this.startInput.value);\n const end = new Date(this.endInput.value);\n if (end <= start) {\n this.endGroup.classList.add('has-error');\n isValid = false;\n }\n\n return isValid;\n }\n\n save() {\n if (!this.validate()) return;\n\n const event = {\n title: this.titleInput.value.trim(),\n start: new Date(this.startInput.value),\n end: new Date(this.endInput.value),\n backgroundColor: this._formData.color\n };\n\n this.emit('save', event);\n this.close();\n }\n\n formatDateForInput(date) {\n // Handle local date string for datetime-local input\n const pad = (num) => String(num).padStart(2, '0');\n const year = date.getFullYear();\n const month = pad(date.getMonth() + 1);\n const day = pad(date.getDate());\n const hours = pad(date.getHours());\n const minutes = pad(date.getMinutes());\n \n return `${year}-${month}-${day}T${hours}:${minutes}`;\n }\n\n unmount() {\n if (this._cleanupFocusTrap) {\n this._cleanupFocusTrap();\n }\n window.removeEventListener('keydown', this._handleKeyDown);\n }\n}\n\nif (!customElements.get('forcecal-event-form')) {\n customElements.define('forcecal-event-form', EventForm);\n}\n","/**\n * ForceCalendar - Main calendar component\n *\n * The primary interface component that integrates all views and features\n */\n\nimport { BaseComponent } from '../core/BaseComponent.js';\nimport StateManager from '../core/StateManager.js';\nimport eventBus from '../core/EventBus.js';\nimport { StyleUtils } from '../utils/StyleUtils.js';\nimport { DateUtils } from '../utils/DateUtils.js';\nimport { DOMUtils } from '../utils/DOMUtils.js';\n\n// Import view components\nimport { MonthView } from './views/MonthView.js';\nimport { WeekView } from './views/WeekView.js';\nimport { DayView } from './views/DayView.js';\nimport { EventForm } from './EventForm.js'; // Import EventForm\n\n// Register view components\nif (!customElements.get('forcecal-month')) {\n customElements.define('forcecal-month', MonthView);\n}\nif (!customElements.get('forcecal-week')) {\n customElements.define('forcecal-week', WeekView);\n}\nif (!customElements.get('forcecal-day')) {\n customElements.define('forcecal-day', DayView);\n}\n// EventForm is self-registering in its file\n\n\nexport class ForceCalendar extends BaseComponent {\n static get observedAttributes() {\n return ['view', 'date', 'locale', 'timezone', 'week-starts-on', 'height'];\n }\n\n constructor() {\n super();\n this.stateManager = null;\n this.currentView = null;\n this._hasRendered = false; // Track if initial render is complete\n this._cachedStyles = null; // Cache styles to avoid recreation\n }\n\n initialize() {\n // Initialize state manager with config from attributes\n const config = {\n view: this.getAttribute('view') || 'month',\n date: this.getAttribute('date') ? new Date(this.getAttribute('date')) : new Date(),\n locale: this.getAttribute('locale') || 'en-US',\n timeZone: this.getAttribute('timezone') || Intl.DateTimeFormat().resolvedOptions().timeZone,\n weekStartsOn: parseInt(this.getAttribute('week-starts-on') || '0')\n };\n\n this.stateManager = new StateManager(config);\n\n // Subscribe to state changes\n this.stateManager.subscribe(this.handleStateChange.bind(this));\n\n // Listen for events\n this.setupEventListeners();\n }\n\n setupEventListeners() {\n // Navigation events\n eventBus.on('navigation:*', (data, event) => {\n this.emit('calendar-navigate', { action: event.split(':')[1], ...data });\n });\n\n // View change events\n eventBus.on('view:changed', (data) => {\n this.emit('calendar-view-change', data);\n });\n\n // Event management events\n eventBus.on('event:*', (data, event) => {\n this.emit(`calendar-event-${event.split(':')[1]}`, data);\n });\n\n // Date selection events\n eventBus.on('date:selected', (data) => {\n this.emit('calendar-date-select', data);\n });\n }\n\n handleStateChange(newState, oldState) {\n // If not yet rendered, do nothing (mount will handle initial render)\n if (!this._hasRendered) {\n return;\n }\n\n // Check what changed\n const viewChanged = newState.view !== oldState?.view;\n const dateChanged = newState.currentDate?.getTime() !== oldState?.currentDate?.getTime();\n const eventsChanged = newState.events !== oldState?.events;\n const loadingChanged = newState.loading !== oldState?.loading;\n const errorChanged = newState.error !== oldState?.error;\n\n // For loading/error state changes, do full re-render (rare)\n if (loadingChanged || errorChanged) {\n this.render();\n return;\n }\n\n // Update local view reference if needed\n if (viewChanged) {\n this.currentView = newState.view;\n }\n\n // Targeted updates based on what changed\n if (viewChanged) {\n // View changed: update title, buttons, and switch view\n this._updateTitle();\n this._updateViewButtons();\n this._switchView();\n } else if (dateChanged) {\n // Date changed: update title and re-render view\n this._updateTitle();\n this._updateViewContent();\n } else if (eventsChanged) {\n // Events changed: only re-render view content\n this._updateViewContent();\n }\n // Selection changes are handled by the view internally, no action needed here\n }\n\n /**\n * Update only the title text (no DOM recreation)\n */\n _updateTitle() {\n const titleEl = this.$('.fc-title');\n if (titleEl) {\n const state = this.stateManager.getState();\n titleEl.textContent = this.getTitle(state.currentDate, state.view);\n }\n }\n\n /**\n * Update view button active states (no DOM recreation)\n */\n _updateViewButtons() {\n const state = this.stateManager.getState();\n this.$$('[data-view]').forEach(button => {\n const isActive = button.dataset.view === state.view;\n button.classList.toggle('active', isActive);\n });\n }\n\n /**\n * Switch to a different view type\n */\n _switchView() {\n const container = this.$('#calendar-view-container');\n if (!container) return;\n\n // Clean up previous view\n if (this._currentViewInstance) {\n if (this._currentViewInstance.cleanup) {\n this._currentViewInstance.cleanup();\n }\n }\n\n // Create new view\n try {\n const viewRenderer = this._createViewRenderer(this.currentView);\n if (viewRenderer) {\n viewRenderer._viewType = this.currentView;\n this._currentViewInstance = viewRenderer;\n viewRenderer.stateManager = this.stateManager;\n viewRenderer.container = container;\n viewRenderer.render();\n // Note: No subscription - handleStateChange manages all view updates\n }\n } catch (err) {\n console.error('[ForceCalendar] Error switching view:', err);\n }\n }\n\n /**\n * Re-render only the view content (not header)\n */\n _updateViewContent() {\n if (this._currentViewInstance && this._currentViewInstance.render) {\n this._currentViewInstance.render();\n }\n }\n\n mount() {\n super.mount();\n this.loadView(this.stateManager.getView());\n }\n\n loadView(viewType) {\n // Views are already registered at the top of the file\n this.currentView = viewType;\n this.render();\n }\n\n getStyles() {\n const height = this.getAttribute('height') || '800px';\n\n return `\n ${StyleUtils.getBaseStyles()}\n ${StyleUtils.getButtonStyles()}\n ${StyleUtils.getGridStyles()}\n ${StyleUtils.getAnimations()}\n\n :host {\n --calendar-height: ${height};\n display: block;\n font-family: var(--fc-font-family);\n }\n\n .force-calendar {\n display: flex;\n flex-direction: column;\n height: var(--calendar-height);\n background: var(--fc-background);\n border: 1px solid var(--fc-border-color);\n border-radius: var(--fc-border-radius-lg);\n overflow: hidden;\n box-shadow: var(--fc-shadow);\n }\n\n .fc-header {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n align-items: center;\n padding: var(--fc-spacing-md) var(--fc-spacing-lg);\n background: rgba(255, 255, 255, 0.95);\n -webkit-backdrop-filter: blur(8px); /* Safari support */\n backdrop-filter: blur(8px);\n border-bottom: 1px solid var(--fc-border-color);\n z-index: 10;\n position: sticky;\n top: 0;\n }\n\n .fc-header-left {\n display: flex;\n align-items: center;\n gap: var(--fc-spacing-md);\n justify-self: start;\n flex-basis: 0; /* Force Safari to distribute space */\n }\n\n .fc-header-center {\n display: flex;\n align-items: center;\n gap: var(--fc-spacing-lg);\n justify-self: center;\n }\n\n .fc-header-right {\n display: flex;\n align-items: center;\n gap: var(--fc-spacing-md);\n justify-self: end;\n flex-basis: 0; /* Force Safari to distribute space */\n }\n\n .fc-title {\n font-size: 14px;\n font-weight: var(--fc-font-weight-semibold);\n color: var(--fc-text-color);\n white-space: nowrap;\n letter-spacing: -0.01em;\n min-width: 140px;\n text-align: center;\n }\n\n .fc-btn-today {\n border-radius: var(--fc-border-radius-sm);\n padding: 0 12px;\n font-size: 12px;\n font-weight: var(--fc-font-weight-medium);\n border: 1px solid var(--fc-border-color);\n background: var(--fc-background);\n color: var(--fc-text-color);\n height: 28px;\n transition: all var(--fc-transition-fast);\n cursor: pointer;\n display: flex;\n align-items: center;\n }\n\n .fc-btn-today:hover {\n background: var(--fc-background-hover);\n border-color: var(--fc-border-color-hover);\n }\n\n .fc-nav-arrow {\n border: 1px solid var(--fc-border-color);\n background: var(--fc-background);\n height: 28px;\n width: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--fc-border-radius-sm);\n color: var(--fc-text-secondary);\n cursor: pointer;\n transition: all var(--fc-transition-fast);\n padding: 0;\n }\n\n .fc-nav-arrow:hover {\n background: var(--fc-background-hover);\n color: var(--fc-text-color);\n border-color: var(--fc-border-color-hover);\n }\n\n /* View Switcher - Fused Button Group */\n .fc-view-buttons {\n display: flex;\n border: 1px solid var(--fc-border-color);\n border-radius: var(--fc-border-radius-sm);\n overflow: hidden;\n }\n\n .fc-view-button {\n background: var(--fc-background);\n border: none;\n border-right: 1px solid var(--fc-border-color);\n color: var(--fc-text-secondary);\n padding: 0 12px;\n font-size: var(--fc-font-size-sm);\n font-weight: var(--fc-font-weight-medium);\n transition: background-color var(--fc-transition-fast);\n cursor: pointer;\n height: 28px;\n display: flex;\n align-items: center;\n }\n \n .fc-view-button:last-child {\n border-right: none;\n }\n\n .fc-view-button:hover:not(.active) {\n background: var(--fc-background-hover);\n color: var(--fc-text-color);\n }\n\n .fc-view-button.active {\n background: var(--fc-background-alt);\n color: var(--fc-text-color);\n font-weight: var(--fc-font-weight-semibold);\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.02);\n }\n\n .fc-body {\n flex: 1;\n position: relative;\n background: var(--fc-background);\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n .fc-view-container {\n flex: 1;\n position: relative;\n min-height: 0;\n display: flex;\n flex-direction: column;\n }\n\n /* Ensure view container has proper dimensions */\n #calendar-view-container {\n display: block;\n width: 100%;\n height: 100%;\n flex: 1;\n }\n\n #calendar-view-container > * {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n /* Loading state */\n .fc-loading {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--fc-spacing-md);\n color: var(--fc-text-secondary);\n }\n\n .fc-spinner {\n width: 24px;\n height: 24px;\n border: 3px solid var(--fc-border-color);\n border-top-color: var(--fc-primary-color);\n border-radius: 50%;\n animation: fc-spin 1s linear infinite;\n }\n\n /* Error state */\n .fc-error {\n padding: var(--fc-spacing-xl);\n text-align: center;\n color: var(--fc-danger-color);\n background: #FEF2F2;\n border-radius: var(--fc-border-radius);\n margin: var(--fc-spacing-xl);\n }\n\n /* Icons */\n .fc-icon {\n width: 18px;\n height: 18px;\n fill: currentColor;\n }\n\n /* Responsive Adjustments */\n @media (max-width: 850px) {\n .fc-header {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: var(--fc-spacing-md);\n height: auto;\n position: static;\n padding: var(--fc-spacing-md);\n }\n\n .fc-header-center {\n order: -1;\n text-align: center;\n width: 100%;\n padding: var(--fc-spacing-xs) 0;\n }\n\n .fc-header-left,\n .fc-header-right {\n justify-content: space-between;\n width: 100%;\n }\n\n #create-event-btn {\n flex: 1;\n }\n }\n\n /* Month View Styles (inline rendering for Locker Service compatibility) */\n .fc-month-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n }\n\n .fc-month-header {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n border-bottom: 1px solid var(--fc-border-color);\n background: var(--fc-background-alt);\n }\n\n .fc-month-header-cell {\n padding: 12px 8px;\n text-align: center;\n font-size: 11px;\n font-weight: 600;\n color: var(--fc-text-light);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n\n .fc-month-body {\n display: flex;\n flex-direction: column;\n flex: 1;\n }\n\n .fc-month-week {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n flex: 1;\n min-height: 100px;\n }\n\n .fc-month-day {\n background: var(--fc-background);\n border-right: 1px solid var(--fc-border-color);\n border-bottom: 1px solid var(--fc-border-color);\n padding: 4px;\n min-height: 80px;\n cursor: pointer;\n transition: background-color 0.15s ease;\n display: flex;\n flex-direction: column;\n }\n\n .fc-month-day:hover {\n background: var(--fc-background-hover);\n }\n\n .fc-month-day:last-child {\n border-right: none;\n }\n\n .fc-month-day.other-month {\n background: var(--fc-background-alt);\n }\n\n .fc-month-day.other-month .fc-day-number {\n color: var(--fc-text-light);\n }\n\n .fc-month-day.today {\n background: rgba(37, 99, 235, 0.05);\n }\n\n .fc-month-day.today .fc-day-number {\n background: var(--fc-primary-color);\n color: white;\n border-radius: 50%;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .fc-day-number {\n font-size: 13px;\n font-weight: 500;\n color: var(--fc-text-color);\n padding: 2px 4px;\n margin-bottom: 4px;\n }\n\n .fc-day-events {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n overflow: hidden;\n }\n\n .fc-event {\n font-size: 11px;\n padding: 2px 6px;\n border-radius: 3px;\n color: white;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n cursor: pointer;\n transition: transform 0.1s ease;\n }\n\n .fc-event:hover {\n transform: scale(1.02);\n }\n\n .fc-more-events {\n font-size: 10px;\n color: var(--fc-text-light);\n padding: 2px 4px;\n font-weight: 500;\n }\n\n /* Week View Styles (inline rendering for Locker Service compatibility) */\n .fc-week-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n }\n\n /* Day View Styles (inline rendering for Locker Service compatibility) */\n .fc-day-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--fc-background);\n }\n `;\n }\n\n template() {\n const state = this.stateManager.getState();\n const { currentDate, view, loading, error } = state;\n\n if (error) {\n return `\n <div class=\"force-calendar\">\n <div class=\"fc-error\">\n <p><strong>Error:</strong> ${DOMUtils.escapeHTML(error.message || 'An error occurred')}</p>\n </div>\n </div>\n `;\n }\n\n const title = this.getTitle(currentDate, view);\n\n return `\n <div class=\"force-calendar\">\n <header class=\"fc-header\">\n <div class=\"fc-header-left\">\n <button class=\"fc-btn-today\" data-action=\"today\">\n Today\n </button>\n </div>\n\n <div class=\"fc-header-center\">\n <button class=\"fc-nav-arrow\" data-action=\"previous\" title=\"Previous\">\n ${this.getIcon('chevron-left')}\n </button>\n <h2 class=\"fc-title\">${title}</h2>\n <button class=\"fc-nav-arrow\" data-action=\"next\" title=\"Next\">\n ${this.getIcon('chevron-right')}\n </button>\n </div>\n\n <div class=\"fc-header-right\">\n <button class=\"fc-btn fc-btn-primary\" id=\"create-event-btn\" style=\"height: 28px; padding: 0 12px; font-size: 12px;\">\n + New Event\n </button>\n <div class=\"fc-view-buttons\" role=\"group\">\n <button class=\"fc-view-button ${view === 'month' ? 'active' : ''}\"\n data-view=\"month\">Month</button>\n <button class=\"fc-view-button ${view === 'week' ? 'active' : ''}\"\n data-view=\"week\">Week</button>\n <button class=\"fc-view-button ${view === 'day' ? 'active' : ''}\"\n data-view=\"day\">Day</button>\n </div>\n </div>\n </header>\n\n <div class=\"fc-body\">\n ${loading ? `\n <div class=\"fc-loading\">\n <div class=\"fc-spinner\"></div>\n <span>Loading...</span>\n </div>\n ` : `\n <div class=\"fc-view-container\">\n ${this.renderView()}\n </div>\n `}\n </div>\n \n <forcecal-event-form id=\"event-modal\"></forcecal-event-form>\n </div>\n `;\n }\n\n renderView() {\n // Use a plain div container - we'll manually instantiate view classes\n // This bypasses Locker Service's custom element restrictions\n return '<div id=\"calendar-view-container\"></div>';\n }\n\n afterRender() {\n // Manually instantiate and mount view component (bypasses Locker Service)\n const container = this.$('#calendar-view-container');\n\n // Only create view once per view type change\n if (container && this.stateManager && this.currentView) {\n // Check if container actually has content (render() clears shadow DOM)\n if (this._currentViewInstance && this._currentViewInstance._viewType === this.currentView && container.children.length > 0) {\n return;\n }\n\n // Clean up previous view if exists\n if (this._currentViewInstance) {\n if (this._currentViewInstance.cleanup) {\n this._currentViewInstance.cleanup();\n }\n if (this._viewUnsubscribe) {\n this._viewUnsubscribe();\n this._viewUnsubscribe = null;\n }\n }\n\n // Create a simple view renderer that doesn't use custom elements\n try {\n const viewRenderer = this._createViewRenderer(this.currentView);\n if (viewRenderer) {\n viewRenderer._viewType = this.currentView;\n this._currentViewInstance = viewRenderer;\n viewRenderer.stateManager = this.stateManager;\n viewRenderer.container = container;\n viewRenderer.render();\n // Note: No subscription here - handleStateChange manages all view updates\n // via _updateViewContent(), _switchView(), or full re-render\n }\n } catch (err) {\n console.error('[ForceCalendar] Error creating/rendering view:', err);\n }\n }\n\n // Add event listeners for buttons using tracked addListener\n this.$$('[data-action]').forEach(button => {\n this.addListener(button, 'click', this.handleNavigation);\n });\n\n this.$$('[data-view]').forEach(button => {\n this.addListener(button, 'click', this.handleViewChange);\n });\n\n // Event Modal Handling\n const modal = this.$('#event-modal');\n const createBtn = this.$('#create-event-btn');\n\n if (createBtn && modal) {\n this.addListener(createBtn, 'click', () => {\n modal.open(new Date());\n });\n }\n\n // Listen for day clicks from the view\n this.addListener(this.shadowRoot, 'day-click', (e) => {\n if (modal) {\n modal.open(e.detail.date);\n }\n });\n\n // Handle event saving\n if (modal) {\n this.addListener(modal, 'save', (e) => {\n const eventData = e.detail;\n // Robust Safari support check for randomUUID\n const id = (window.crypto && typeof window.crypto.randomUUID === 'function')\n ? window.crypto.randomUUID()\n : Math.random().toString(36).substring(2, 15);\n\n this.stateManager.addEvent({\n id,\n ...eventData\n });\n });\n }\n\n // Mark initial render as complete for targeted updates\n this._hasRendered = true;\n }\n\n _createViewRenderer(viewName) {\n // Create a simple view renderer that bypasses custom elements\n // This is necessary for Salesforce Locker Service compatibility\n const self = this;\n const currentViewName = viewName;\n\n return {\n stateManager: null,\n container: null,\n _listeners: [],\n _scrolled: false,\n\n _escapeHTML(str) {\n if (str == null) return '';\n return DOMUtils.escapeHTML(String(str));\n },\n\n cleanup() {\n this._listeners.forEach(({ element, event, handler }) => {\n element.removeEventListener(event, handler);\n });\n this._listeners = [];\n },\n\n addListener(element, event, handler) {\n element.addEventListener(event, handler);\n this._listeners.push({ element, event, handler });\n },\n\n render() {\n if (!this.container || !this.stateManager) return;\n\n const viewData = this.stateManager.getViewData();\n if (!viewData) {\n this.container.innerHTML = '<div style=\"padding: 20px; text-align: center; color: #666;\">Loading...</div>';\n return;\n }\n\n this.cleanup();\n const config = this.stateManager.getState().config;\n let html = '';\n\n switch (currentViewName) {\n case 'week':\n html = this._renderWeekView(viewData, config);\n break;\n case 'day':\n html = this._renderDayView(viewData, config);\n break;\n case 'month':\n default:\n if (!viewData.weeks) {\n this.container.innerHTML = '<div style=\"padding: 20px; text-align: center; color: #666;\">No data available for month view.</div>';\n return;\n }\n html = this._renderMonthView(viewData, config);\n break;\n }\n\n this.container.innerHTML = html;\n this._attachEventHandlers(currentViewName);\n },\n\n _renderMonthView(viewData, config) {\n const weekStartsOn = config.weekStartsOn || 0;\n const dayNames = [];\n for (let i = 0; i < 7; i++) {\n const dayIndex = (weekStartsOn + i) % 7;\n dayNames.push(['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][dayIndex]);\n }\n\n let html = `\n <div class=\"fc-month-view\" style=\"display: flex; flex-direction: column; height: 100%; min-height: 400px; background: #fff; border: 1px solid #e5e7eb;\">\n <div class=\"fc-month-header\" style=\"display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb;\">\n ${dayNames.map(d => `<div class=\"fc-month-header-cell\" style=\"padding: 12px 8px; text-align: center; font-size: 11px; font-weight: 600; color: #6b7280; text-transform: uppercase;\">${d}</div>`).join('')}\n </div>\n <div class=\"fc-month-body\" style=\"display: flex; flex-direction: column; flex: 1;\">\n `;\n\n viewData.weeks.forEach(week => {\n html += '<div class=\"fc-month-week\" style=\"display: grid; grid-template-columns: repeat(7, 1fr); flex: 1; min-height: 80px;\">';\n week.days.forEach(day => {\n const isOtherMonth = !day.isCurrentMonth;\n const isToday = day.isToday;\n\n const dayBg = isOtherMonth ? '#f3f4f6' : '#fff';\n const dayNumColor = isOtherMonth ? '#9ca3af' : '#111827';\n const todayStyle = isToday ? 'background: #2563eb; color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;' : '';\n\n const events = day.events || [];\n const visibleEvents = events.slice(0, 3);\n const moreCount = events.length - 3;\n\n html += `\n <div class=\"fc-month-day\" data-date=\"${day.date}\" style=\"background: ${dayBg}; border-right: 1px solid #e5e7eb; border-bottom: 1px solid #e5e7eb; padding: 4px; min-height: 80px; cursor: pointer;\">\n <div class=\"fc-day-number\" style=\"font-size: 13px; font-weight: 500; color: ${dayNumColor}; padding: 2px 4px; margin-bottom: 4px; ${todayStyle}\">${day.dayOfMonth}</div>\n <div class=\"fc-day-events\" style=\"display: flex; flex-direction: column; gap: 2px;\">\n ${visibleEvents.map(evt => `\n <div class=\"fc-event\" data-event-id=\"${this._escapeHTML(evt.id)}\" style=\"background-color: ${evt.backgroundColor || '#2563eb'}; font-size: 11px; padding: 2px 6px; border-radius: 3px; color: white; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;\">\n ${this._escapeHTML(evt.title)}\n </div>\n `).join('')}\n ${moreCount > 0 ? `<div class=\"fc-more-events\" style=\"font-size: 10px; color: #6b7280; padding: 2px 4px; font-weight: 500;\">+${moreCount} more</div>` : ''}\n </div>\n </div>\n `;\n });\n html += '</div>';\n });\n\n html += '</div></div>';\n return html;\n },\n\n _renderWeekView(viewData, config) {\n const days = viewData.days || [];\n if (days.length === 0) {\n return '<div style=\"padding: 20px; text-align: center; color: #666;\">No data available for week view.</div>';\n }\n\n const weekStartsOn = config.weekStartsOn || 0;\n const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n const hours = Array.from({ length: 24 }, (_, i) => i);\n\n // Process days to add events\n const processedDays = days.map(day => {\n const dayDate = new Date(day.date);\n const events = day.events || [];\n return {\n ...day,\n date: dayDate,\n dayName: dayNames[dayDate.getDay()],\n dayOfMonth: dayDate.getDate(),\n isToday: this._isToday(dayDate),\n timedEvents: events.filter(e => !e.allDay),\n allDayEvents: events.filter(e => e.allDay)\n };\n });\n\n let html = `\n <div class=\"fc-week-view\" style=\"display: flex; flex-direction: column; height: 100%; background: #fff; overflow: hidden;\">\n <!-- Header -->\n <div style=\"display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb; flex-shrink: 0;\">\n <div style=\"border-right: 1px solid #e5e7eb;\"></div>\n ${processedDays.map(day => `\n <div style=\"padding: 12px 8px; text-align: center; border-right: 1px solid #e5e7eb;\">\n <div style=\"font-size: 10px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;\">${day.dayName}</div>\n <div style=\"font-size: 16px; font-weight: 500; margin-top: 4px; ${day.isToday ? 'background: #dc2626; color: white; border-radius: 50%; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;' : 'color: #111827;'}\">${day.dayOfMonth}</div>\n </div>\n `).join('')}\n </div>\n\n <!-- All Day Row -->\n <div style=\"display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #fafafa; min-height: 32px; flex-shrink: 0;\">\n <div style=\"font-size: 9px; color: #6b7280; display: flex; align-items: center; justify-content: center; border-right: 1px solid #e5e7eb; text-transform: uppercase; font-weight: 700;\">All day</div>\n ${processedDays.map(day => `\n <div style=\"border-right: 1px solid #e5e7eb; padding: 4px; display: flex; flex-direction: column; gap: 2px;\">\n ${day.allDayEvents.map(evt => `\n <div class=\"fc-event\" data-event-id=\"${this._escapeHTML(evt.id)}\" style=\"background-color: ${evt.backgroundColor || '#2563eb'}; font-size: 10px; padding: 2px 4px; border-radius: 2px; color: white; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">\n ${this._escapeHTML(evt.title)}\n </div>\n `).join('')}\n </div>\n `).join('')}\n </div>\n\n <!-- Time Grid Body -->\n <div id=\"week-scroll-container\" style=\"flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;\">\n <div style=\"display: grid; grid-template-columns: 60px repeat(7, 1fr); position: relative; height: 1440px;\">\n <!-- Time Gutter -->\n <div style=\"border-right: 1px solid #e5e7eb; background: #fafafa;\">\n ${hours.map(h => `\n <div style=\"height: 60px; font-size: 10px; color: #6b7280; text-align: right; padding-right: 8px; font-weight: 500;\">\n ${h === 0 ? '' : this._formatHour(h)}\n </div>\n `).join('')}\n </div>\n\n <!-- Day Columns -->\n ${processedDays.map(day => `\n <div class=\"fc-week-day-column\" data-date=\"${day.date.toISOString()}\" style=\"border-right: 1px solid #e5e7eb; position: relative; cursor: pointer;\">\n <!-- Hour grid lines -->\n ${hours.map(() => `<div style=\"height: 60px; border-bottom: 1px solid #f3f4f6;\"></div>`).join('')}\n\n <!-- Now indicator for today -->\n ${day.isToday ? this._renderNowIndicator() : ''}\n\n <!-- Timed events -->\n ${day.timedEvents.map(evt => this._renderTimedEvent(evt)).join('')}\n </div>\n `).join('')}\n </div>\n </div>\n </div>\n `;\n\n return html;\n },\n\n _renderDayView(viewData, config) {\n // Day view from core has: type, date, dayName, isToday, allDayEvents, hours\n // We need to handle both the core structure and enriched structure\n const currentDate = this.stateManager?.getState()?.currentDate || new Date();\n\n let dayDate, dayName, isToday, allDayEvents, timedEvents;\n\n if (viewData.type === 'day' && viewData.date) {\n // Core day view structure\n dayDate = new Date(viewData.date);\n dayName = viewData.dayName || ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dayDate.getDay()];\n isToday = viewData.isToday !== undefined ? viewData.isToday : this._isToday(dayDate);\n allDayEvents = viewData.allDayEvents || [];\n\n // Extract timed events from hours array or get from stateManager\n if (viewData.hours && Array.isArray(viewData.hours)) {\n // Collect unique events from hours (events can span multiple hours)\n const eventMap = new Map();\n viewData.hours.forEach(hour => {\n (hour.events || []).forEach(evt => {\n if (!eventMap.has(evt.id)) {\n eventMap.set(evt.id, evt);\n }\n });\n });\n timedEvents = Array.from(eventMap.values());\n } else {\n timedEvents = [];\n }\n } else if (viewData.days && viewData.days.length > 0) {\n // Enriched structure with days array\n const dayData = viewData.days.find(d => this._isSameDay(new Date(d.date), currentDate)) || viewData.days[0];\n dayDate = new Date(dayData.date);\n dayName = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dayDate.getDay()];\n isToday = this._isToday(dayDate);\n const events = dayData.events || [];\n allDayEvents = events.filter(e => e.allDay);\n timedEvents = events.filter(e => !e.allDay);\n } else {\n return '<div style=\"padding: 20px; text-align: center; color: #666;\">No data available for day view.</div>';\n }\n\n const hours = Array.from({ length: 24 }, (_, i) => i);\n\n let html = `\n <div class=\"fc-day-view\" style=\"display: flex; flex-direction: column; height: 100%; background: #fff; overflow: hidden;\">\n <!-- Header -->\n <div style=\"display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid #e5e7eb; background: #f9fafb; flex-shrink: 0;\">\n <div style=\"border-right: 1px solid #e5e7eb;\"></div>\n <div style=\"padding: 16px 24px;\">\n <div style=\"font-size: 12px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;\">${dayName}</div>\n <div style=\"font-size: 24px; font-weight: 600; margin-top: 4px; ${isToday ? 'color: #dc2626;' : 'color: #111827;'}\">${dayDate.getDate()}</div>\n </div>\n </div>\n\n <!-- All Day Row -->\n <div style=\"display: grid; grid-template-columns: 60px 1fr; border-bottom: 1px solid #e5e7eb; background: #fafafa; min-height: 36px; flex-shrink: 0;\">\n <div style=\"font-size: 9px; color: #6b7280; display: flex; align-items: center; justify-content: center; border-right: 1px solid #e5e7eb; text-transform: uppercase; font-weight: 700;\">All day</div>\n <div style=\"padding: 6px 12px; display: flex; flex-wrap: wrap; gap: 4px;\">\n ${allDayEvents.map(evt => `\n <div class=\"fc-event\" data-event-id=\"${this._escapeHTML(evt.id)}\" style=\"background-color: ${evt.backgroundColor || '#2563eb'}; font-size: 12px; padding: 4px 8px; border-radius: 4px; color: white; cursor: pointer; font-weight: 500;\">\n ${this._escapeHTML(evt.title)}\n </div>\n `).join('')}\n </div>\n </div>\n\n <!-- Time Grid Body -->\n <div id=\"day-scroll-container\" style=\"flex: 1; overflow-y: auto; overflow-x: hidden; position: relative;\">\n <div style=\"display: grid; grid-template-columns: 60px 1fr; position: relative; height: 1440px;\">\n <!-- Time Gutter -->\n <div style=\"border-right: 1px solid #e5e7eb; background: #fafafa;\">\n ${hours.map(h => `\n <div style=\"height: 60px; font-size: 11px; color: #6b7280; text-align: right; padding-right: 12px; font-weight: 500;\">\n ${h === 0 ? '' : this._formatHour(h)}\n </div>\n `).join('')}\n </div>\n\n <!-- Day Column -->\n <div class=\"fc-day-column\" data-date=\"${dayDate.toISOString()}\" style=\"position: relative; cursor: pointer;\">\n <!-- Hour grid lines -->\n ${hours.map(() => `<div style=\"height: 60px; border-bottom: 1px solid #f3f4f6;\"></div>`).join('')}\n\n <!-- Now indicator for today -->\n ${isToday ? this._renderNowIndicator() : ''}\n\n <!-- Timed events -->\n ${timedEvents.map(evt => this._renderTimedEventDay(evt)).join('')}\n </div>\n </div>\n </div>\n </div>\n `;\n\n return html;\n },\n\n _renderTimedEvent(event) {\n const start = new Date(event.start);\n const end = new Date(event.end);\n const startMinutes = start.getHours() * 60 + start.getMinutes();\n const durationMinutes = Math.max((end - start) / (1000 * 60), 20);\n const color = event.backgroundColor || '#2563eb';\n\n return `\n <div class=\"fc-event\" data-event-id=\"${this._escapeHTML(event.id)}\"\n style=\"position: absolute; top: ${startMinutes}px; height: ${durationMinutes}px; left: 2px; right: 2px;\n background-color: ${color}; border-radius: 4px; padding: 4px 8px; font-size: 11px;\n font-weight: 500; color: white; overflow: hidden; box-shadow: 0 1px 2px rgba(0,0,0,0.1);\n cursor: pointer; z-index: 5;\">\n <div style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">${this._escapeHTML(event.title)}</div>\n <div style=\"font-size: 10px; opacity: 0.9;\">${this._formatTime(start)}</div>\n </div>\n `;\n },\n\n _renderTimedEventDay(event) {\n const start = new Date(event.start);\n const end = new Date(event.end);\n const startMinutes = start.getHours() * 60 + start.getMinutes();\n const durationMinutes = Math.max((end - start) / (1000 * 60), 30);\n const color = event.backgroundColor || '#2563eb';\n\n return `\n <div class=\"fc-event\" data-event-id=\"${this._escapeHTML(event.id)}\"\n style=\"position: absolute; top: ${startMinutes}px; height: ${durationMinutes}px; left: 12px; right: 24px;\n background-color: ${color}; border-radius: 6px; padding: 8px 12px; font-size: 13px;\n font-weight: 500; color: white; overflow: hidden; box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n cursor: pointer; z-index: 5;\">\n <div style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">${this._escapeHTML(event.title)}</div>\n <div style=\"font-size: 11px; opacity: 0.9;\">${this._formatTime(start)} - ${this._formatTime(end)}</div>\n </div>\n `;\n },\n\n _renderNowIndicator() {\n const now = new Date();\n const minutes = now.getHours() * 60 + now.getMinutes();\n return `<div style=\"position: absolute; left: 0; right: 0; top: ${minutes}px; height: 2px; background: #dc2626; z-index: 15; pointer-events: none;\"></div>`;\n },\n\n _formatHour(hour) {\n const period = hour >= 12 ? 'PM' : 'AM';\n const displayHour = hour % 12 || 12;\n return `${displayHour} ${period}`;\n },\n\n _formatTime(date) {\n const hours = date.getHours();\n const minutes = date.getMinutes();\n const period = hours >= 12 ? 'PM' : 'AM';\n const displayHour = hours % 12 || 12;\n return minutes === 0 ? `${displayHour} ${period}` : `${displayHour}:${minutes.toString().padStart(2, '0')} ${period}`;\n },\n\n _isToday(date) {\n const today = new Date();\n return date.getDate() === today.getDate() &&\n date.getMonth() === today.getMonth() &&\n date.getFullYear() === today.getFullYear();\n },\n\n _isSameDay(date1, date2) {\n return date1.getDate() === date2.getDate() &&\n date1.getMonth() === date2.getMonth() &&\n date1.getFullYear() === date2.getFullYear();\n },\n\n _attachEventHandlers(viewType) {\n const stateManager = this.stateManager;\n const self = this;\n\n // Day click handlers (for month view)\n this.container.querySelectorAll('.fc-month-day').forEach(dayEl => {\n this.addListener(dayEl, 'click', (e) => {\n const date = new Date(dayEl.dataset.date);\n stateManager.selectDate(date);\n });\n });\n\n // Week view day column click handlers\n this.container.querySelectorAll('.fc-week-day-column').forEach(dayEl => {\n this.addListener(dayEl, 'click', (e) => {\n if (e.target.closest('.fc-event')) return;\n const date = new Date(dayEl.dataset.date);\n const rect = dayEl.getBoundingClientRect();\n const scrollContainer = this.container.querySelector('#week-scroll-container');\n const y = e.clientY - rect.top + (scrollContainer ? scrollContainer.scrollTop : 0);\n date.setHours(Math.floor(y / 60), Math.floor(y % 60), 0, 0);\n stateManager.selectDate(date);\n });\n });\n\n // Day view column click handlers\n this.container.querySelectorAll('.fc-day-column').forEach(dayEl => {\n this.addListener(dayEl, 'click', (e) => {\n if (e.target.closest('.fc-event')) return;\n const date = new Date(dayEl.dataset.date);\n const rect = dayEl.getBoundingClientRect();\n const scrollContainer = this.container.querySelector('#day-scroll-container');\n const y = e.clientY - rect.top + (scrollContainer ? scrollContainer.scrollTop : 0);\n date.setHours(Math.floor(y / 60), Math.floor(y % 60), 0, 0);\n stateManager.selectDate(date);\n });\n });\n\n // Event click handlers\n this.container.querySelectorAll('.fc-event').forEach(eventEl => {\n this.addListener(eventEl, 'click', (e) => {\n e.stopPropagation();\n const eventId = eventEl.dataset.eventId;\n const event = stateManager.getEvents().find(ev => ev.id === eventId);\n if (event) {\n stateManager.selectEvent(event);\n }\n });\n });\n\n // Scroll to 8 AM for week and day views\n if (viewType === 'week' || viewType === 'day') {\n const scrollContainerId = viewType === 'week' ? '#week-scroll-container' : '#day-scroll-container';\n const scrollContainer = this.container.querySelector(scrollContainerId);\n if (scrollContainer && !this._scrolled) {\n scrollContainer.scrollTop = 8 * 60 - 50;\n this._scrolled = true;\n }\n }\n }\n };\n }\n\n handleNavigation(event) {\n const action = event.currentTarget.dataset.action;\n switch (action) {\n case 'today':\n this.stateManager.today();\n break;\n case 'previous':\n this.stateManager.previous();\n break;\n case 'next':\n this.stateManager.next();\n break;\n }\n }\n\n handleViewChange(event) {\n const view = event.currentTarget.dataset.view;\n this.stateManager.setView(view);\n }\n\n getTitle(date, view) {\n const locale = this.stateManager.state.config.locale;\n\n switch (view) {\n case 'month':\n return DateUtils.formatDate(date, 'month', locale);\n case 'week':\n const weekStart = DateUtils.startOfWeek(date);\n const weekEnd = DateUtils.endOfWeek(date);\n return DateUtils.formatDateRange(weekStart, weekEnd, locale);\n case 'day':\n return DateUtils.formatDate(date, 'long', locale);\n default:\n return DateUtils.formatDate(date, 'month', locale);\n }\n }\n\n getIcon(name) {\n const icons = {\n 'chevron-left': `\n <svg class=\"fc-icon\" viewBox=\"0 0 24 24\">\n <path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/>\n </svg>\n `,\n 'chevron-right': `\n <svg class=\"fc-icon\" viewBox=\"0 0 24 24\">\n <path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/>\n </svg>\n `,\n 'calendar': `\n <svg class=\"fc-icon\" viewBox=\"0 0 24 24\">\n <path d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z\"/>\n </svg>\n `\n };\n\n return icons[name] || '';\n }\n\n // Public API methods\n addEvent(event) {\n return this.stateManager.addEvent(event);\n }\n\n updateEvent(eventId, updates) {\n return this.stateManager.updateEvent(eventId, updates);\n }\n\n deleteEvent(eventId) {\n return this.stateManager.deleteEvent(eventId);\n }\n\n getEvents() {\n return this.stateManager.getEvents();\n }\n\n setView(view) {\n this.stateManager.setView(view);\n }\n\n setDate(date) {\n this.stateManager.setDate(date);\n }\n\n next() {\n this.stateManager.next();\n }\n\n previous() {\n this.stateManager.previous();\n }\n\n today() {\n this.stateManager.today();\n }\n\n destroy() {\n if (this.stateManager) {\n this.stateManager.destroy();\n }\n eventBus.clear();\n super.cleanup();\n }\n}\n\n// Register component\nif (!customElements.get('forcecal-main')) {\n customElements.define('forcecal-main', ForceCalendar);\n}","/**\n * Force Calendar Interface\n * Main entry point for the component library\n *\n * A solid foundation for calendar interfaces built on @forcecalendar/core\n */\n\n// Core modules\nexport { BaseComponent } from './core/BaseComponent.js';\nexport { default as StateManager } from './core/StateManager.js';\nexport { default as eventBus, EventBus } from './core/EventBus.js';\n\n// Utilities\nexport { DateUtils } from './utils/DateUtils.js';\nexport { DOMUtils } from './utils/DOMUtils.js';\nexport { StyleUtils } from './utils/StyleUtils.js';\n\n// Components\nimport './components/ForceCalendar.js';\nexport { ForceCalendar } from './components/ForceCalendar.js';\n\n// Views\nexport { MonthView } from './components/views/MonthView.js';\nexport { WeekView } from './components/views/WeekView.js';\nexport { DayView } from './components/views/DayView.js';\n\n// Auto-register main component if in browser environment\nif (typeof window !== 'undefined' && typeof customElements !== 'undefined') {\n // The ForceCalendar component self-registers\n console.log('Force Calendar Interface loading...');\n}"],"names":["BaseComponent","element","event","handler","newState","oldState","key","value","oldValue","newValue","boundHandler","eventName","detail","styles","template","selector","name","TimezoneDatabase","timezone","offsetMinutes","_","data","id","sharedInstance","TimezoneManager","date","fromTimezone","toTimezone","fromOffset","offsetDiff","offset","utcDate","cacheKey","parts","p","tzData","dstRule","year","dstStart","dstEnd","month","week","dayOfWeek","firstDay","dayOffset","lastDay","now","tz","offsetHours","hours","minutes","offsetStr","a","b","options","formatOptions","tzString","upperTz","offsetMatch","sign","totalOffset","timezone1","timezone2","offset1","hitRate","entriesToRemove","keys","i","Event","normalized","attendee","index","reminder","title","start","end","allDay","description","location","color","backgroundColor","borderColor","textColor","recurring","recurrenceRule","timeZone","endTimeZone","status","visibility","organizer","attendees","reminders","category","categories","attachments","conferenceData","metadata","rest","startDay","endDay","dateString","startString","endString","dayStart","dayEnd","otherEvent","datetime","updates","r","obj","other","emailOrId","email","responseStatus","counts","reminderId","triggerTime","normalizedCategory","c","DateUtils$1","DateUtils","result","weekStartsOn","day","diff","days","weeks","months","dayOfMonth","years","today","date1","date2","week1Start","week2Start","yearDiff","monthDiff","firstDayOfYear","pastDaysOfYear","locale","format","use24Hour","timeString","dates","current","endTime","dateObj","part","tzDate","jan","jul","janOffset","julOffset","currentOffset","originalOffset","newOffset","dstAdjustment","hour","minute","second","dateStr","timeStr","localDate","utcTime","RRuleParser","rrule","rule","freq","weekDays","match","nth","weekday","v","validateArray","arr","min","max","dayStr","d","freqMap","weekdayMap","nthMap","parseDay","dayDescs","parsed","monthNames","m","RecurrenceEngine","rangeStart","rangeEnd","maxOccurrences","occurrences","duration","eventTimezone","tzManager","currentDate","count","lastOffset","stuckCount","maxStuckIterations","occurrenceStart","occurrenceEnd","previousTimestamp","ruleString","next","iterations","originalDate","currentMonth","byDay","dayMap","weekdayCode","position","targetDay","nextMonth","eventId","dateTime","exDate","exceptionDate","exceptions","interval","dayCode","dayNames","code","LRUCache","capacity","firstKey","AdaptiveMemoryManager","config","cache","memoryUsage","memInfo","g","procKey","memKey","memFn","usage","totalItems","maxItems","cacheInfo","pressureLevel","sortedCaches","reduction","newCapacity","increase","oldCapacity","targetSize","itemsToRemove","cacheStats","thresholds","PerformanceOptimizer","operation","fn","error","isError","metric","summary","op","time","markers","startMonth","endMonth","promise","resolve","indexed","cacheType","cacheManagerName","reject","operations","callbacks","results","errors","callback","maxAge","queryKey","queryFn","cached","ConflictDetector","eventStore","opts","conflicts","affectedEventIds","affectedAttendees","searchStart","searchEnd","potentialConflicts","e","conflictingEvent","eventConflicts","event1","event2","attendeeEmails","busyPeriods","freePeriods","currentTime","busy","timeConflict","attendeeConflicts","resourceConflicts","locationConflict","bufferMinutes","buffer","start1","end1","start2","end2","overlapStart","overlapEnd","overlapMinutes","severity","conflictingAttendees","attendee1","attendee2","a1","a2","_a","_b","resources1","resources2","resource1","resource2","loc1","loc2","conflictsByType","conflictsBySeverity","conflict","periods","merged","last","startHour","endHour","businessStart","businessEnd","EventStore","existingEvent","updatedEvent","filters","monthKey","eventIds","candidateIds","checkDate","tempDate","tempDateStr","monthEventIds","allEvents","startOfDay","endOfDay","eventStartLocal","eventEndLocal","aStart","bStart","timeCompare","excludeId","overlapping","startDate","endDate","checkedIds","timedOnly","events","groups","processed","group","currentEvent","positions","startDiff","columns","column","totalColumns","pos","expandRecurring","startUTC","endUTC","baseEvents","expandedEvents","occurrence","oldEvents","eventData","firstWeekEnd","lastWeekStart","change","listener","enableRollback","k","eventUpdates","removed","cutoffDate","stillNeeded","eventId1","eventId2","allConflicts","checkedPairs","j","pairKey","durationMinutes","allowConflicts","eventsWithConflicts","StateManager$1","initialState","view","validViews","newDate","isLoading","message","keyArray","previousState","currentState","nextState","seen","aKeys","bKeys","state","clonedState","item","cloned","Calendar","StateManager","viewType","oldEvent","parsedTimezone","previousTimezone","fixedWeekCount","maxWeeks","weekIndex","dayIndex","dayDate","isCurrentMonth","isToday","isWeekend","allDayEvents","timedEvents","hourDate","hourEnd","groupedEvents","dateKey","plugin","EventBus","once","priority","subscription","handlers","sub","promises","toRemove","pattern","eventBus","silent","changedKeys","addedEvent","newEvents","viewData","selectedDateString","loading","CoreDateUtils","formats","showMinutes","startFormat","startTime","baseDate","rtf","diffInSeconds","diffInMinutes","diffInHours","diffInDays","diffInWeeks","diffInMonths","diffInYears","monthIndex","period","adjustedHours","DOMUtils","tag","attributes","children","child","delegatedHandler","target","rect","threshold","behavior","block","inline","property","className","eventType","ms","htmlString","str","div","func","wait","timeout","args","later","limit","inThrottle","parents","parent","margin","deep","container","focusableElements","firstFocusable","lastFocusable","handleKeyDown","StyleUtils","variables","percent","num","amt","R","G","B","bgColor","fallback","trimmed","hex","alpha","breakpoint","size","__publicField","MonthView","attempts","registryId","manager","oldDate","oldDateEl","newDateEl","selectedDate","isSelected","processedEvents","fullColor","col","dayName","dayData","isOtherMonth","dayNumber","classes","visibleEvents","remainingCount","eventsHtml","moreHtml","style","safeColor","safeTextColor","dayEl","eventEl","moreEl","calendarEvent","WeekView","oldDayEl","newDayEl","h","startMinutes","top","height","el","ev","y","DayView","dayCol","allDays","w","_c","EventForm","btn","initialDate","isValid","pad","ForceCalendar","viewChanged","dateChanged","eventsChanged","loadingChanged","errorChanged","titleEl","button","isActive","viewRenderer","err","modal","createBtn","viewName","currentViewName","html","dayBg","dayNumColor","todayStyle","moreCount","evt","processedDays","eventMap","displayHour","stateManager","scrollContainer","scrollContainerId","weekStart","weekEnd"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","x_google_ignoreList":[1,2,3,4,5,6,7,8,9,10,11,12,13]}