@hortonstudio/main 1.9.23 → 1.9.24

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.
Files changed (98) hide show
  1. package/README.md +62 -64
  2. package/dist/assets/hs-animations-BDMqlbof.js +3 -0
  3. package/dist/assets/hs-animations-BDMqlbof.js. +3 -0
  4. package/dist/assets/hs-animations-BDMqlbof.js.gz +0 -0
  5. package/dist/assets/hs-animations-BDMqlbof.js.map +1 -0
  6. package/dist/assets/hs-attributeSelector-6pGcDBo-.js +2 -0
  7. package/dist/assets/hs-attributeSelector-6pGcDBo-.js.map +1 -0
  8. package/dist/assets/hs-comparison-Ja8EiSGD.js +2 -0
  9. package/dist/assets/hs-comparison-Ja8EiSGD.js. +2 -0
  10. package/dist/assets/hs-comparison-Ja8EiSGD.js.gz +0 -0
  11. package/dist/assets/hs-comparison-Ja8EiSGD.js.map +1 -0
  12. package/dist/assets/hs-counter-Bfh7_P60.js +2 -0
  13. package/dist/assets/hs-counter-Bfh7_P60.js. +2 -0
  14. package/dist/assets/hs-counter-Bfh7_P60.js.gz +0 -0
  15. package/dist/assets/hs-counter-Bfh7_P60.js.map +1 -0
  16. package/dist/assets/hs-cssVariables-BjuwJfDJ.js +2 -0
  17. package/dist/assets/hs-cssVariables-BjuwJfDJ.js.map +1 -0
  18. package/dist/assets/hs-default-CLmDRb9d.js +2 -0
  19. package/dist/assets/hs-default-CLmDRb9d.js. +2 -0
  20. package/dist/assets/hs-default-CLmDRb9d.js.gz +0 -0
  21. package/dist/assets/hs-default-CLmDRb9d.js.map +1 -0
  22. package/dist/assets/hs-form-COFGgawz.js +2 -0
  23. package/dist/assets/hs-form-COFGgawz.js. +2 -0
  24. package/dist/assets/hs-form-COFGgawz.js.gz +0 -0
  25. package/dist/assets/hs-form-COFGgawz.js.map +1 -0
  26. package/dist/assets/hs-marquee-CZ9pmCbT.js +2 -0
  27. package/dist/assets/hs-marquee-CZ9pmCbT.js. +2 -0
  28. package/dist/assets/hs-marquee-CZ9pmCbT.js.gz +0 -0
  29. package/dist/assets/hs-marquee-CZ9pmCbT.js.map +1 -0
  30. package/dist/assets/hs-modalManager-H_YegPAO.js +2 -0
  31. package/dist/assets/hs-modalManager-H_YegPAO.js. +2 -0
  32. package/dist/assets/hs-modalManager-H_YegPAO.js.gz +0 -0
  33. package/dist/assets/hs-modalManager-H_YegPAO.js.map +1 -0
  34. package/dist/assets/hs-normalize-CTwtG5-a.js +2 -0
  35. package/dist/assets/hs-normalize-CTwtG5-a.js. +2 -0
  36. package/dist/assets/hs-normalize-CTwtG5-a.js.gz +0 -0
  37. package/dist/assets/hs-normalize-CTwtG5-a.js.map +1 -0
  38. package/dist/assets/hs-orchestrator-J8b7XRk1.js +2 -0
  39. package/dist/assets/hs-orchestrator-J8b7XRk1.js. +2 -0
  40. package/dist/assets/hs-orchestrator-J8b7XRk1.js.gz +0 -0
  41. package/dist/assets/hs-orchestrator-J8b7XRk1.js.map +1 -0
  42. package/dist/assets/hs-pagination-DcOxmDPJ.js +2 -0
  43. package/dist/assets/hs-pagination-DcOxmDPJ.js. +2 -0
  44. package/dist/assets/hs-pagination-DcOxmDPJ.js.gz +0 -0
  45. package/dist/assets/hs-pagination-DcOxmDPJ.js.map +1 -0
  46. package/dist/assets/hs-structure-DhNix64P.js +3 -0
  47. package/dist/assets/hs-structure-DhNix64P.js. +3 -0
  48. package/dist/assets/hs-structure-DhNix64P.js.gz +0 -0
  49. package/dist/assets/hs-structure-DhNix64P.js.map +1 -0
  50. package/dist/assets/hs-tabs-CaxqHoGW.js +2 -0
  51. package/dist/assets/hs-tabs-CaxqHoGW.js. +2 -0
  52. package/dist/assets/hs-tabs-CaxqHoGW.js.gz +0 -0
  53. package/dist/assets/hs-tabs-CaxqHoGW.js.map +1 -0
  54. package/dist/assets/hs-toc-fxIQS7tz.js +2 -0
  55. package/dist/assets/hs-toc-fxIQS7tz.js. +2 -0
  56. package/dist/assets/hs-toc-fxIQS7tz.js.gz +0 -0
  57. package/dist/assets/hs-toc-fxIQS7tz.js.map +1 -0
  58. package/dist/assets/hs-transition-CDNuGJNq.js +2 -0
  59. package/dist/assets/hs-transition-CDNuGJNq.js. +2 -0
  60. package/dist/assets/hs-transition-CDNuGJNq.js.gz +0 -0
  61. package/dist/assets/hs-transition-CDNuGJNq.js.map +1 -0
  62. package/dist/assets/hs-utils-CKm6QhLw.js +2 -0
  63. package/dist/assets/hs-utils-CKm6QhLw.js.map +1 -0
  64. package/dist/main.js +2 -2
  65. package/dist/main.js. +2 -2
  66. package/dist/main.js.gz +0 -0
  67. package/dist/main.js.map +1 -1
  68. package/package.json +1 -1
  69. package/dist/assets/animations-igIF6V0K.js +0 -3
  70. package/dist/assets/animations-igIF6V0K.js. +0 -3
  71. package/dist/assets/animations-igIF6V0K.js.gz +0 -0
  72. package/dist/assets/animations-igIF6V0K.js.map +0 -1
  73. package/dist/assets/counter-B9xmgh8V.js +0 -2
  74. package/dist/assets/counter-B9xmgh8V.js. +0 -2
  75. package/dist/assets/counter-B9xmgh8V.js.gz +0 -0
  76. package/dist/assets/counter-B9xmgh8V.js.map +0 -1
  77. package/dist/assets/cssVariables-n9wQSSYb.js +0 -2
  78. package/dist/assets/cssVariables-n9wQSSYb.js.map +0 -1
  79. package/dist/assets/default-CZ6vle49.js +0 -2
  80. package/dist/assets/default-CZ6vle49.js. +0 -2
  81. package/dist/assets/default-CZ6vle49.js.gz +0 -0
  82. package/dist/assets/default-CZ6vle49.js.map +0 -1
  83. package/dist/assets/modalManager-LtDi9OJz.js +0 -2
  84. package/dist/assets/modalManager-LtDi9OJz.js. +0 -2
  85. package/dist/assets/modalManager-LtDi9OJz.js.gz +0 -0
  86. package/dist/assets/modalManager-LtDi9OJz.js.map +0 -1
  87. package/dist/assets/normalize-DWI4olFS.js +0 -2
  88. package/dist/assets/normalize-DWI4olFS.js. +0 -2
  89. package/dist/assets/normalize-DWI4olFS.js.gz +0 -0
  90. package/dist/assets/normalize-DWI4olFS.js.map +0 -1
  91. package/dist/assets/structure--7b3v7AH.js +0 -2
  92. package/dist/assets/structure--7b3v7AH.js. +0 -2
  93. package/dist/assets/structure--7b3v7AH.js.gz +0 -0
  94. package/dist/assets/structure--7b3v7AH.js.map +0 -1
  95. package/dist/assets/utils-DA-PANmk.js +0 -2
  96. package/dist/assets/utils-DA-PANmk.js.map +0 -1
  97. package/dist/bootstrap.js +0 -2
  98. package/dist/bootstrap.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hs-default-CLmDRb9d.js","sources":["../../src/modules/default/functions/smooth-scroll.ts","../../src/modules/default/functions/navbar/functions/dropdown.ts","../../src/modules/default/functions/navbar/functions/menu.ts","../../src/modules/default/functions/navbar/functions/arrow-navigation.ts","../../src/modules/default/functions/navbar/navbar.ts","../../src/modules/default/functions/accordion.ts","../../src/modules/default/default.ts"],"sourcesContent":["/**\n * Smooth Scroll\n *\n * Provides smooth animated scrolling for anchor links with optional offset.\n * Automatically intercepts anchor link clicks, animates scroll with GSAP,\n * and handles accessibility (focus management, keyboard navigation).\n *\n * Features:\n * - Auto-detects and handles all anchor links (a[href^=\"#\"])\n * - Dynamic offset via proxy element's computed CSS top value\n * - GSAP animation with reduced motion support\n * - Keyboard navigation (Enter/Space on links)\n * - Focus management for screen readers\n * - Disables Webflow's native scroll behavior\n * - Triggers scroll-based animations on init\n *\n * Structure:\n * Optional offset proxy element with CSS top value:\n * <div data-hs-scroll-offset=\"proxy\" style=\"top: var(--_hs---scroll-offset)\"></div>\n */\n\nimport { getGsap, prefersReducedMotion, querySelector } from '@utils';\n\n// Type declaration for jQuery (runtime dependency)\ndeclare const $: any;\n\ninterface ModuleConfig {\n attributes: {\n elements: {\n 'offset-proxy': {\n primary: string;\n aliases: string[];\n };\n };\n };\n}\n\nexport async function init(config: ModuleConfig) {\n // Store event handlers for cleanup\n let clickHandler: ((e: Event) => void) | null = null;\n let keydownHandler: ((e: KeyboardEvent) => void) | null = null;\n\n // Disable Webflow's native scroll behavior (jQuery-based)\n // This runs immediately since default module already waits for IX3\n if (typeof $ !== 'undefined') {\n $(document).off('click.wf-scroll');\n }\n\n // Disable CSS smooth scrolling\n document.documentElement.style.scrollBehavior = 'auto';\n document.body.style.scrollBehavior = 'auto';\n\n function getScrollOffset(): number {\n // Find element with data-hs-scroll-offset=\"proxy\" and read its computed top value\n const proxyElement = querySelector(config, 'offset-proxy');\n console.log('[smooth-scroll] Proxy element:', proxyElement);\n if (proxyElement && proxyElement instanceof HTMLElement) {\n const computedTop = getComputedStyle(proxyElement).top;\n const offset = parseFloat(computedTop) || 0;\n console.log('[smooth-scroll] Computed top:', computedTop, '-> offset:', offset);\n return offset;\n }\n console.log('[smooth-scroll] No proxy element found, using offset: 0');\n return 0;\n }\n\n // Smooth scroll to element with offset\n function scrollToElement(target: HTMLElement, offset = 0): void {\n if (!target) return;\n\n const gsapLib = getGsap('smooth-scroll', false);\n\n // Skip animation if user prefers reduced motion or GSAP not available\n if (prefersReducedMotion() || !gsapLib) {\n const targetPosition = target.getBoundingClientRect().top + window.scrollY - offset;\n window.scrollTo(0, targetPosition);\n target.setAttribute('tabindex', '-1');\n target.focus({ preventScroll: true });\n return;\n }\n\n gsapLib.gsap.to(window, {\n duration: 1,\n scrollTo: {\n y: target,\n offsetY: offset,\n },\n ease: 'power2.out',\n onComplete: function () {\n target.setAttribute('tabindex', '-1');\n target.focus({ preventScroll: true });\n },\n });\n }\n\n function handleAnchorActivation(e: Event): void {\n const link = (e.target as Element).closest('a[href^=\"#\"]');\n if (!link) return;\n\n const href = link.getAttribute('href');\n if (!href || href === '#') return;\n\n const targetId = href.substring(1);\n const targetElement = document.getElementById(targetId);\n\n if (targetElement) {\n e.preventDefault();\n if (history.replaceState) {\n history.replaceState(null, null, `#${targetElement.id}`);\n }\n const offset = getScrollOffset();\n scrollToElement(targetElement, offset);\n }\n }\n\n // Handle anchor link clicks and keyboard activation\n function handleAnchorClicks(): void {\n clickHandler = handleAnchorActivation;\n keydownHandler = (e: KeyboardEvent): void => {\n if (e.key === 'Enter' || e.key === ' ') {\n handleAnchorActivation(e);\n }\n };\n\n document.addEventListener('click', clickHandler);\n document.addEventListener('keydown', keydownHandler);\n }\n\n // Initialize anchor link handling\n handleAnchorClicks();\n\n // Mock scroll to trigger scroll-based animations\n const gsapLib = getGsap('smooth-scroll', false);\n if (gsapLib && document.body.scrollHeight > window.innerHeight) {\n gsapLib.gsap.set(window, { scrollTo: 1 });\n gsapLib.gsap.set(window, { scrollTo: 0 });\n }\n\n return {\n result: 'autoInit-smooth-scroll initialized',\n destroy: () => {\n // Remove event listeners\n if (clickHandler) {\n document.removeEventListener('click', clickHandler);\n clickHandler = null;\n }\n if (keydownHandler) {\n document.removeEventListener('keydown', keydownHandler);\n keydownHandler = null;\n }\n\n // Re-enable CSS smooth scrolling\n document.documentElement.style.scrollBehavior = '';\n document.body.style.scrollBehavior = '';\n },\n };\n}\n","/**\n * Dropdown\n *\n * Provides accessible navigation dropdowns with hover or click behavior.\n * Handles ARIA states, keyboard navigation, optional height animation,\n * and automatic focus management for both desktop hover and mobile click modes.\n *\n * Features:\n * - Hover mode: Desktop hover with full keyboard navigation (ArrowDown/Up, Escape)\n * - Click mode: Mobile/accordion click-only with simple keyboard (Space, Enter, Escape)\n * - Automatic ARIA state management (aria-expanded, aria-controls, role=menu)\n * - Optional height animation via data-hs-height wrapper\n * - Inert state for collapsed dropdowns (non-interactive)\n * - MutationObserver syncs ARIA with visual state changes\n * - Focus management for keyboard and screen reader users\n *\n * Structure:\n * <div data-hs-nav-dropdown=\"wrapper\" data-hs-nav-dropdown-type=\"hover\">\n * <button data-hs-clickable=\"button\">Menu</button>\n * <div data-hs-nav-dropdown=\"list\" role=\"menu\">\n * <a href=\"#\" data-hs-clickable=\"button\" role=\"menuitem\">Item 1</a>\n * <a href=\"#\" data-hs-clickable=\"button\" role=\"menuitem\">Item 2</a>\n * </div>\n * </div>\n */\n\nimport {\n querySelectorAll,\n querySelector,\n getSelector,\n globalConfig,\n animateHeight,\n setHeight,\n} from '@utils';\n\ninterface EventHandler {\n element: Element;\n event: string;\n handler: EventListener;\n options?: AddEventListenerOptions;\n}\n\ninterface ModuleConfig {\n attributes: {\n elements: Record<string, { primary: string; aliases?: string[] }>;\n properties?: Record<string, string>;\n };\n}\n\n// Module-scoped config (set during init)\nlet moduleConfig: ModuleConfig | null = null;\n\nexport function init(config: ModuleConfig) {\n // Store config at module scope for helper functions\n moduleConfig = config;\n\n const cleanup = {\n observers: [] as MutationObserver[],\n handlers: [] as EventHandler[],\n };\n\n const addObserver = (observer: MutationObserver): void => {\n cleanup.observers.push(observer);\n };\n const addHandler = (\n element: Element,\n event: string,\n handler: EventListener,\n options?: AddEventListenerOptions\n ): void => {\n element.addEventListener(event, handler, options);\n cleanup.handlers.push({ element, event, handler, options });\n };\n\n function sanitizeForID(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/^-+|-+$/g, '')\n .substring(0, 50);\n }\n\n function setupDropdown(\n addObserver: (observer: MutationObserver) => void,\n addHandler: (\n element: Element,\n event: string,\n handler: EventListener,\n options?: AddEventListenerOptions\n ) => void\n ): void {\n const dropdownWrappers = querySelectorAll(moduleConfig as any, 'wrapper');\n const hoverDropdowns: Element[] = []; // Track hover-type dropdowns for focus-loss handling\n\n dropdownWrappers.forEach((wrapper) => {\n const clickableSelector = getSelector(globalConfig.clickable as any, 'button');\n const toggle = wrapper.querySelector(clickableSelector);\n const dropdownList = querySelector(moduleConfig as any, 'list', wrapper);\n\n if (!toggle || !dropdownList) {\n console.warn('[dropdown] Dropdown wrapper missing required elements:', wrapper);\n return;\n }\n\n // Get dropdown type (hover or click)\n const type = wrapper.getAttribute('data-hs-nav-dropdown-type') || 'hover';\n\n // Check for visual height wrapper (contains data-hs-height=\"element\")\n // If found, animate that instead of the list (list is for ARIA only)\n // If not found, no height animation (optional feature)\n const heightWrapper = wrapper.querySelector('[data-hs-height=\"element\"]');\n const animationTarget = heightWrapper ? heightWrapper.parentElement : null;\n\n const toggleText = toggle.textContent?.trim() || 'dropdown';\n const sanitizedText = sanitizeForID(toggleText);\n const toggleId = `navbar-dropdown-${sanitizedText}-toggle`;\n const listId = `navbar-dropdown-${sanitizedText}-list`;\n\n toggle.id = toggleId;\n toggle.setAttribute('aria-haspopup', 'menu');\n toggle.setAttribute('aria-expanded', 'false');\n toggle.setAttribute('aria-controls', listId);\n\n dropdownList.id = listId;\n dropdownList.setAttribute('role', 'menu');\n (dropdownList as HTMLElement).inert = true; // Initial state: hidden and non-interactive\n\n const menuItems = Array.from(dropdownList.querySelectorAll(clickableSelector));\n menuItems.forEach((item, index) => {\n item.setAttribute('role', 'menuitem');\n item.setAttribute('tabindex', '-1');\n\n // Add context for first item to help screen readers understand dropdown content\n if (index === 0) {\n const toggleText = toggle.textContent?.trim() || 'menu';\n const existingLabel = item.getAttribute('aria-label');\n if (!existingLabel) {\n item.setAttribute('aria-label', `${item.textContent?.trim()}, ${toggleText} submenu`);\n }\n }\n });\n\n let currentMenuItemIndex = -1;\n\n // Function to check if dropdown is open\n function isDropdownOpen() {\n return wrapper.classList.contains(globalConfig.classes.active);\n }\n\n // Update ARIA states based on current visual state\n function updateARIAStates() {\n const isOpen = isDropdownOpen();\n const wasOpen = toggle.getAttribute('aria-expanded') === 'true';\n\n // If dropdown is closing (was open, now closed), focus the toggle first\n if (wasOpen && !isOpen && dropdownList.contains(document.activeElement)) {\n (toggle as HTMLElement).focus();\n }\n\n toggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');\n (dropdownList as HTMLElement).inert = !isOpen; // Enable/disable interaction based on state\n menuItems.forEach((item) => {\n item.setAttribute('tabindex', isOpen ? '0' : '-1');\n });\n\n if (!isOpen) {\n currentMenuItemIndex = -1;\n }\n\n // Animate height wrapper (visual container, not ARIA list)\n animateHeight(animationTarget, isOpen, {\n duration: type === 'hover' ? 200 : 300,\n ease: 'power2.inOut',\n });\n }\n\n // Set initial height without animation\n setHeight(animationTarget, isDropdownOpen());\n\n // Set initial ARIA states\n updateARIAStates();\n\n // Monitor for class changes and update ARIA states\n const observer = new MutationObserver(() => {\n updateARIAStates();\n });\n\n observer.observe(wrapper, {\n attributes: true,\n attributeFilter: ['class'],\n });\n\n addObserver(observer);\n\n // ========================================\n // TYPE-SPECIFIC HANDLERS\n // ========================================\n\n if (type === 'hover') {\n // HOVER TYPE: Desktop behavior with hover + full keyboard navigation\n\n // Track this as a hover dropdown for focus-loss handling\n hoverDropdowns.push(wrapper);\n\n // Hover handlers\n const mouseenterHandler = () => {\n wrapper.classList.add('is-active');\n };\n\n const mouseleaveHandler = () => {\n wrapper.classList.remove('is-active');\n };\n\n addHandler(wrapper, 'mouseenter', mouseenterHandler);\n addHandler(wrapper, 'mouseleave', mouseleaveHandler);\n\n // Full keyboard navigation for toggle\n const toggleKeydownHandler = (e: KeyboardEvent): void => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n\n if (!isDropdownOpen()) {\n wrapper.classList.add(globalConfig.classes.active);\n\n // Focus first menu item after brief delay\n if (menuItems.length > 0) {\n setTimeout(() => {\n currentMenuItemIndex = 0;\n (menuItems[0] as HTMLElement).focus();\n }, 100);\n }\n }\n } else if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n\n if (!isDropdownOpen()) {\n wrapper.classList.add(globalConfig.classes.active);\n\n // Focus first menu item after brief delay\n if (menuItems.length > 0) {\n setTimeout(() => {\n currentMenuItemIndex = 0;\n (menuItems[0] as HTMLElement).focus();\n }, 100);\n }\n } else {\n wrapper.classList.remove(globalConfig.classes.active);\n }\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n\n if (!isDropdownOpen()) {\n wrapper.classList.add(globalConfig.classes.active);\n\n // Focus last menu item after brief delay\n if (menuItems.length > 0) {\n setTimeout(() => {\n currentMenuItemIndex = menuItems.length - 1;\n (menuItems[currentMenuItemIndex] as HTMLElement).focus();\n }, 100);\n }\n }\n } else if (e.key === 'Escape') {\n e.preventDefault();\n\n if (isDropdownOpen()) {\n wrapper.classList.remove(globalConfig.classes.active);\n }\n }\n };\n\n addHandler(toggle, 'keydown', toggleKeydownHandler);\n\n // Handle navigation within open dropdown (arrow keys)\n const dropdownKeydownHandler = (e: KeyboardEvent): void => {\n if (!isDropdownOpen()) return;\n if (!wrapper.contains(document.activeElement)) return;\n\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (currentMenuItemIndex < menuItems.length - 1) {\n currentMenuItemIndex++;\n (menuItems[currentMenuItemIndex] as HTMLElement).focus();\n }\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (currentMenuItemIndex === 0) {\n wrapper.classList.remove(globalConfig.classes.active);\n (toggle as HTMLElement).focus();\n currentMenuItemIndex = -1;\n } else if (currentMenuItemIndex > 0) {\n currentMenuItemIndex--;\n (menuItems[currentMenuItemIndex] as HTMLElement).focus();\n } else {\n (toggle as HTMLElement).focus();\n currentMenuItemIndex = -1;\n }\n } else if (e.key === 'Escape') {\n e.preventDefault();\n wrapper.classList.remove('is-active');\n }\n };\n\n addHandler(wrapper, 'keydown', dropdownKeydownHandler);\n } else if (type === 'click') {\n // CLICK TYPE: Mobile/accordion behavior with click only + simple keyboard\n\n // Click handler to toggle\n const clickHandler = (e: MouseEvent): void => {\n e.preventDefault();\n wrapper.classList.toggle(globalConfig.classes.active);\n };\n\n addHandler(toggle, 'click', clickHandler);\n\n // Simple keyboard navigation (NO arrow keys)\n const toggleKeydownHandler = (e: KeyboardEvent): void => {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n wrapper.classList.toggle(globalConfig.classes.active);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n if (isDropdownOpen()) {\n wrapper.classList.remove(globalConfig.classes.active);\n }\n }\n };\n\n addHandler(toggle, 'keydown', toggleKeydownHandler);\n }\n });\n\n // Close hover dropdowns when focus leaves (click dropdowns stay open)\n const focusinHandler = (e: FocusEvent): void => {\n hoverDropdowns.forEach((wrapper) => {\n if (wrapper.classList.contains('is-active') && !wrapper.contains(e.target as Node)) {\n wrapper.classList.remove('is-active');\n }\n });\n };\n\n // Only add handler if there are hover dropdowns\n if (hoverDropdowns.length > 0) {\n addHandler(document.body, 'focusin', focusinHandler);\n }\n }\n\n setupDropdown(addObserver, addHandler);\n\n return {\n result: 'dropdown initialized',\n destroy: () => {\n // Disconnect all observers\n cleanup.observers.forEach((obs) => obs.disconnect());\n cleanup.observers.length = 0;\n\n // Remove all event listeners\n cleanup.handlers.forEach(({ element, event, handler, options }) => {\n element.removeEventListener(event, handler, options);\n });\n cleanup.handlers.length = 0;\n\n // Clear module config\n moduleConfig = null;\n },\n };\n}\n","/**\n * Menu\n *\n * Provides mobile menu button and modal behavior for navigation.\n * Handles menu toggle with modal overlay, focus trap, ARIA states,\n * and automatic inert management for collapsed dropdowns in the menu.\n *\n * Features:\n * - Modal behavior with overlay and body scroll lock\n * - Focus trap keeps keyboard navigation within open menu\n * - ARIA state management (aria-expanded, aria-controls)\n * - Inert state for collapsed menu dropdowns (non-interactive)\n * - MutationObserver syncs inert state with dropdown visual state\n * - Escape key to close menu\n * - Returns focus to menu button on close\n *\n * Structure:\n * <button data-hs-nav-menu=\"button\">Menu</button>\n * <div data-hs-nav-menu=\"wrapper\" aria-labelledby=\"menu-button\">\n * <!-- Menu content with dropdowns -->\n * </div>\n */\n\nimport {\n querySelectorAll,\n querySelector,\n getSelector,\n globalConfig,\n cssVariables,\n animateHeight,\n setHeight,\n openModal,\n closeModal,\n} from '@utils';\n\ninterface EventHandler {\n element: Element | Document;\n event: string;\n handler: EventListener;\n options?: AddEventListenerOptions;\n}\n\ninterface ModuleConfig {\n attributes: {\n elements: Record<string, { primary: string; aliases?: string[] }>;\n };\n}\n\nexport function init(config: ModuleConfig, navbarConfig?: ModuleConfig) {\n const cleanup = {\n observers: [] as MutationObserver[],\n handlers: [] as EventHandler[],\n state: {\n focusTrapHandler: null as ((e: KeyboardEvent) => void) | null,\n },\n };\n\n const addObserver = (observer: MutationObserver): void => {\n cleanup.observers.push(observer);\n };\n const addHandler = (\n element: Element | Document,\n event: string,\n handler: EventListener,\n options?: AddEventListenerOptions\n ): void => {\n element.addEventListener(event, handler, options);\n cleanup.handlers.push({ element, event, handler, options });\n };\n\n function createFocusTrap(menuButton: Element): ((e: KeyboardEvent) => void) | undefined {\n const navbarWrapper = navbarConfig\n ? querySelector(navbarConfig as any, 'wrapper')\n : document.querySelector('[data-hs-nav=\"wrapper\"]');\n\n if (!navbarWrapper) return;\n\n const focusTrapHandler = (e: KeyboardEvent): void => {\n if (e.key === 'Tab') {\n const clickableSelector = getSelector(globalConfig.clickable as any, 'button');\n const clickableItems = Array.from(navbarWrapper.querySelectorAll(clickableSelector));\n const formElements = navbarWrapper.querySelectorAll(\n 'input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n const focusableArray = [...clickableItems, ...Array.from(formElements)];\n const firstElement = focusableArray[0];\n const lastElement = focusableArray[focusableArray.length - 1];\n\n if (e.shiftKey) {\n // Shift+Tab: moving backwards\n if (document.activeElement === firstElement) {\n e.preventDefault();\n (lastElement as HTMLElement).focus();\n }\n } else {\n // Tab: moving forwards\n if (document.activeElement === lastElement) {\n e.preventDefault();\n (firstElement as HTMLElement).focus();\n }\n }\n }\n };\n\n document.addEventListener('keydown', focusTrapHandler);\n return focusTrapHandler;\n }\n\n function removeFocusTrap(focusTrapHandler: ((e: KeyboardEvent) => void) | null): void {\n if (focusTrapHandler) {\n document.removeEventListener('keydown', focusTrapHandler);\n }\n }\n\n function setupMenu(\n addObserver: (observer: MutationObserver) => void,\n addHandler: (\n element: Element | Document,\n event: string,\n handler: EventListener,\n options?: AddEventListenerOptions\n ) => void\n ): void {\n const menuButtons = querySelectorAll(config as any, 'button');\n const menu = querySelector(config as any, 'wrapper');\n\n if (!menuButtons.length || !menu) return;\n\n // Get navbar wrapper for styling (e.g., backdrop blur)\n const navbarWrapper = navbarConfig ? querySelector(navbarConfig as any, 'wrapper') : null;\n\n const menuId = `menu-${Date.now()}`;\n\n menu.id = menuId;\n menu.setAttribute('role', 'dialog');\n menu.setAttribute('aria-modal', 'true');\n (menu as HTMLElement).inert = true; // Initial state: hidden and non-interactive\n\n // Check for visual height wrapper (optional)\n // Only look for a descendant with data-hs-height=\"element\"\n // If found, animate that element's parent. If not found, no height animation.\n const heightWrapper = menu.querySelector('[data-hs-height=\"element\"]');\n const animationTarget = heightWrapper ? heightWrapper.parentElement : null;\n\n menuButtons.forEach((menuButton) => {\n menuButton.setAttribute('aria-expanded', 'false');\n menuButton.setAttribute('aria-controls', menuId);\n menuButton.setAttribute('aria-label', 'Open navigation menu');\n\n let focusTrapHandler: ((e: KeyboardEvent) => void) | null = null;\n let shouldAutoFocus: boolean | 'last' = false; // Track if menu should autofocus (keyboard activation)\n\n // Check if menu is open by looking for is-active class on button\n function isMenuOpen() {\n return menuButton.classList.contains(globalConfig.classes.active);\n }\n\n // Update ARIA states and menu behavior based on current visual state\n function updateMenuState() {\n const isOpen = isMenuOpen();\n const wasOpen = menuButton.getAttribute('aria-expanded') === 'true';\n\n if (isOpen && !wasOpen) {\n // Opening\n openModal();\n\n // Add is-active to menu wrapper and enable interaction\n menu.classList.add(globalConfig.classes.active);\n (menu as HTMLElement).inert = false; // Enable interaction\n\n // Add class to navbar wrapper for styling (e.g., backdrop blur)\n if (navbarWrapper) {\n navbarWrapper.classList.add('hs-menu-open');\n }\n\n menuButtons.forEach((btn) => {\n btn.setAttribute('aria-expanded', 'true');\n btn.setAttribute('aria-label', 'Close navigation menu');\n });\n\n // Animate height if configured\n if (animationTarget) {\n animateHeight(animationTarget, true, { duration: 300, ease: 'power2.inOut' });\n }\n\n // Create focus trap for navbar\n focusTrapHandler = createFocusTrap(menuButton);\n\n // Only autofocus for keyboard activation\n if (shouldAutoFocus) {\n setTimeout(() => {\n const menuClickableSelector = getSelector(globalConfig.clickable as any, 'button');\n const allElements = Array.from(menu.querySelectorAll(menuClickableSelector));\n\n if (shouldAutoFocus === 'last') {\n // Focus last item (ArrowUp)\n const lastElement = allElements[allElements.length - 1];\n if (lastElement) {\n (lastElement as HTMLElement).focus();\n }\n } else {\n // Focus first item (Space/Enter/ArrowDown)\n const firstElement = allElements[0];\n if (firstElement) {\n (firstElement as HTMLElement).focus();\n }\n }\n }, 100);\n shouldAutoFocus = false; // Reset flag\n }\n } else if (!isOpen && wasOpen) {\n // Closing - focus button BEFORE updating ARIA\n if (menu.contains(document.activeElement)) {\n (menuButton as HTMLElement).focus();\n }\n\n // Now update ARIA and visual state\n closeModal();\n\n // Remove is-active from menu wrapper and disable interaction\n menu.classList.remove(globalConfig.classes.active);\n (menu as HTMLElement).inert = true; // Disable interaction\n\n // Remove class from navbar wrapper\n if (navbarWrapper) {\n navbarWrapper.classList.remove('hs-menu-open');\n }\n\n menuButtons.forEach((btn) => {\n btn.setAttribute('aria-expanded', 'false');\n btn.setAttribute('aria-label', 'Open navigation menu');\n });\n\n // Animate height if configured\n if (animationTarget) {\n animateHeight(animationTarget, false, { duration: 300, ease: 'power2.inOut' });\n }\n\n // Remove focus trap\n removeFocusTrap(focusTrapHandler);\n focusTrapHandler = null;\n }\n }\n\n // Set initial height without animation (if configured)\n if (animationTarget) {\n setHeight(animationTarget, isMenuOpen());\n }\n\n // Set initial ARIA states\n updateMenuState();\n\n // Monitor for class changes on button and update menu state\n const observer = new MutationObserver(() => {\n updateMenuState();\n });\n\n observer.observe(menuButton, {\n attributes: true,\n attributeFilter: ['class'],\n });\n\n addObserver(observer);\n\n // Click handler\n const clickHandler = function (e) {\n e.preventDefault();\n menuButton.classList.toggle('is-active');\n };\n\n addHandler(menuButton, 'click', clickHandler);\n\n // Keyboard navigation (dialog/modal pattern)\n const keydownHandler = function (e) {\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n shouldAutoFocus = true; // Set flag for keyboard activation\n menuButton.classList.toggle(globalConfig.classes.active);\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (!isMenuOpen()) {\n shouldAutoFocus = true; // Open and focus first item\n menuButton.classList.add(globalConfig.classes.active);\n }\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (!isMenuOpen()) {\n shouldAutoFocus = 'last'; // Open and focus last item\n menuButton.classList.add(globalConfig.classes.active);\n }\n } else if (e.key === 'Escape') {\n e.preventDefault();\n\n if (isMenuOpen()) {\n menuButton.classList.remove(globalConfig.classes.active);\n }\n }\n };\n\n addHandler(menuButton, 'keydown', keydownHandler);\n\n // Store focus trap handler for cleanup\n cleanup.state.focusTrapHandler = focusTrapHandler;\n });\n }\n\n function setupMenuDisplayObserver(addObserver) {\n const menu = querySelector(config, 'wrapper');\n if (!menu) return;\n\n let previousState = null;\n\n function handleStateChange() {\n const computedStyle = window.getComputedStyle(menu);\n const currentState = computedStyle.getPropertyValue(cssVariables.state).trim();\n\n // Detect state change from active (1) to inactive (0)\n if (\n previousState === globalConfig.cssVars.state.values.active &&\n currentState === globalConfig.cssVars.state.values.inactive\n ) {\n // Get menu button to check if menu is open\n const menuButton = document.querySelector('[data-hs-nav-menu=\"button\"]');\n const isMenuOpen = menuButton && menuButton.getAttribute('aria-expanded') === 'true';\n\n // If menu is open, close it cleanly (triggers animation and proper cleanup)\n if (isMenuOpen && menuButton) {\n menuButton.classList.remove('is-active');\n }\n }\n\n previousState = currentState;\n }\n\n const stateObserver = new ResizeObserver(handleStateChange);\n stateObserver.observe(menu);\n addObserver(stateObserver);\n // Initial check\n handleStateChange();\n }\n\n setupMenu(addObserver, addHandler);\n setupMenuDisplayObserver(addObserver);\n\n return {\n result: 'menu initialized',\n destroy: () => {\n // Clean up focus trap\n if (cleanup.state.focusTrapHandler) {\n document.removeEventListener('keydown', cleanup.state.focusTrapHandler);\n cleanup.state.focusTrapHandler = null;\n }\n\n // Disconnect all observers\n cleanup.observers.forEach((obs) => obs.disconnect());\n cleanup.observers.length = 0;\n\n // Remove all event listeners\n cleanup.handlers.forEach(({ element, event, handler, options }) => {\n element.removeEventListener(event, handler, options);\n });\n cleanup.handlers.length = 0;\n\n // Remove body overflow class if present\n document.body.classList.remove('u-overflow-hidden');\n },\n };\n}\n","/**\n * Arrow Navigation\n *\n * Provides keyboard arrow navigation for navbar and mobile menu.\n * Handles ArrowLeft/Right in desktop navbar and ArrowUp/Down in mobile menu,\n * plus Home/End/Escape keys for complete keyboard accessibility.\n *\n * Features:\n * - Desktop: ArrowLeft/Right to navigate navbar items\n * - Mobile menu: ArrowUp/Down, Home/End navigation\n * - Skips hidden elements and inactive dropdowns\n * - Respects inert state for collapsed accordions\n * - Escape to close mobile menu\n * - ArrowLeft/Right to collapse/expand mobile dropdowns\n */\n\nimport { getSelector, globalConfig, querySelector } from '@utils';\n\ninterface EventHandler {\n element: Element | Document;\n event: string;\n handler: EventListener;\n options?: AddEventListenerOptions;\n}\n\ninterface ModuleConfig {\n attributes: {\n elements: Record<string, { primary: string; aliases?: string[] }>;\n };\n}\n\ninterface NavbarConfig {\n attributes: {\n elements: {\n wrapper: { primary: string; aliases?: string[] };\n 'skip-link': { primary: string; aliases?: string[] };\n };\n };\n menu: ModuleConfig;\n}\n\nexport function init(config: ModuleConfig, navbarConfig?: NavbarConfig) {\n const cleanup = {\n handlers: [] as EventHandler[],\n };\n\n const addHandler = (\n element: Element | Document,\n event: string,\n handler: EventListener,\n options?: AddEventListenerOptions\n ): void => {\n element.addEventListener(event, handler, options);\n cleanup.handlers.push({ element, event, handler, options });\n };\n\n function setupDesktopArrowNavigation(\n addHandler: (\n element: Element | Document,\n event: string,\n handler: EventListener,\n options?: AddEventListenerOptions\n ) => void\n ): void {\n const keydownHandler = (e: KeyboardEvent): void => {\n if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return;\n\n const menu = navbarConfig\n ? querySelector(navbarConfig.menu as any, 'wrapper')\n : document.querySelector('[data-hs-nav-menu=\"wrapper\"]');\n if (menu && menu.contains(document.activeElement)) return;\n\n const navbar = navbarConfig\n ? querySelector(navbarConfig as any, 'wrapper')\n : document.querySelector('[data-hs-nav=\"wrapper\"]');\n\n if (!navbar || !navbar.contains(document.activeElement)) return;\n\n // Check if focus is inside an open dropdown (using .is-active class)\n const openDropdown = navbar.querySelector(\n `.${globalConfig.classes.active}[data-hs-nav-dropdown]`\n );\n if (openDropdown && openDropdown.contains(document.activeElement)) return;\n\n e.preventDefault();\n\n const clickableSelector = getSelector(globalConfig.clickable as any, 'button');\n const allNavbarElements = Array.from(navbar.querySelectorAll(clickableSelector));\n const focusableElements = Array.from(allNavbarElements).filter((el) => {\n if (el.getAttribute('tabindex') === '-1') return false;\n\n const isInDropdownList = el.closest('[role=\"menu\"]');\n if (isInDropdownList) return false;\n\n const menuSelector = navbarConfig\n ? navbarConfig.menu.attributes.elements.wrapper.primary.split('=')[0]\n : 'data-hs-nav-menu';\n const isInMenu = el.closest(`[${menuSelector}=\"wrapper\"]`);\n if (isInMenu) return false;\n\n const skipSelector = navbarConfig\n ? navbarConfig.attributes.elements['skip-link'].primary.split('=')[0]\n : 'data-hs-nav';\n const isInSkipLink = el.closest(`[${skipSelector}=\"skip-link\"]`);\n if (isInSkipLink) return false;\n\n const computedStyle = window.getComputedStyle(el);\n const htmlEl = el as HTMLElement;\n const isHidden =\n computedStyle.display === 'none' ||\n computedStyle.visibility === 'hidden' ||\n computedStyle.opacity === '0' ||\n htmlEl.offsetWidth === 0 ||\n htmlEl.offsetHeight === 0;\n if (isHidden) return false;\n\n let parent = el.parentElement;\n while (parent && parent !== navbar) {\n const parentStyle = window.getComputedStyle(parent);\n const parentHtmlEl = parent as HTMLElement;\n const parentHidden =\n parentStyle.display === 'none' ||\n parentStyle.visibility === 'hidden' ||\n parentHtmlEl.offsetWidth === 0 ||\n parentHtmlEl.offsetHeight === 0;\n if (parentHidden) return false;\n parent = parent.parentElement;\n }\n\n return true;\n });\n\n const currentIndex = focusableElements.indexOf(document.activeElement as Element);\n if (currentIndex === -1) return;\n\n if (e.key === 'ArrowRight') {\n if (currentIndex < focusableElements.length - 1) {\n const nextIndex = currentIndex + 1;\n (focusableElements[nextIndex] as HTMLElement).focus();\n }\n } else {\n if (currentIndex > 0) {\n const nextIndex = currentIndex - 1;\n (focusableElements[nextIndex] as HTMLElement).focus();\n }\n }\n };\n\n addHandler(document, 'keydown', keydownHandler);\n }\n\n function setupMenuArrowNavigation(\n addHandler: (\n element: Element | Document,\n event: string,\n handler: EventListener,\n options?: AddEventListenerOptions\n ) => void\n ): void {\n const menuContainer = navbarConfig\n ? querySelector(navbarConfig.menu as any, 'wrapper')\n : document.querySelector('[data-hs-nav-menu=\"wrapper\"]');\n if (!menuContainer) return;\n\n function getFocusableElements(): Element[] {\n const menuClickableSelector = getSelector(globalConfig.clickable as any, 'button');\n const allElements = Array.from(menuContainer.querySelectorAll(menuClickableSelector));\n return Array.from(allElements).filter((el) => {\n // Check if element or any ancestor is inert (inactive dropdown)\n let current: Element | null = el;\n while (current && current !== menuContainer) {\n if ((current as HTMLElement).inert) {\n return false;\n }\n current = current.parentElement;\n }\n return true;\n });\n }\n\n let currentFocusIndex = -1;\n\n const keydownHandler = (e: KeyboardEvent): void => {\n const focusableElements = getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const activeElement = document.activeElement;\n currentFocusIndex = focusableElements.indexOf(activeElement as Element);\n\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (currentFocusIndex < focusableElements.length - 1) {\n currentFocusIndex = currentFocusIndex + 1;\n (focusableElements[currentFocusIndex] as HTMLElement).focus();\n }\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (currentFocusIndex > 0) {\n currentFocusIndex = currentFocusIndex - 1;\n (focusableElements[currentFocusIndex] as HTMLElement).focus();\n }\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n if (\n activeElement &&\n (activeElement as HTMLElement).tagName === 'BUTTON' &&\n activeElement.hasAttribute('aria-controls')\n ) {\n const isExpanded = activeElement.getAttribute('aria-expanded') === 'true';\n if (!isExpanded) {\n (activeElement as HTMLElement).click();\n }\n return;\n }\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault();\n if (\n activeElement &&\n (activeElement as HTMLElement).tagName === 'BUTTON' &&\n activeElement.hasAttribute('aria-controls')\n ) {\n const isExpanded = activeElement.getAttribute('aria-expanded') === 'true';\n if (isExpanded) {\n (activeElement as HTMLElement).click();\n }\n return;\n }\n } else if (e.key === 'Home') {\n e.preventDefault();\n currentFocusIndex = 0;\n (focusableElements[0] as HTMLElement).focus();\n } else if (e.key === 'End') {\n e.preventDefault();\n currentFocusIndex = focusableElements.length - 1;\n (focusableElements[focusableElements.length - 1] as HTMLElement).focus();\n } else if (e.key === ' ' && activeElement && (activeElement as HTMLElement).tagName === 'A') {\n e.preventDefault();\n } else if (e.key === 'Escape') {\n const menuButton = navbarConfig\n ? querySelector(navbarConfig.menu as any, 'button')\n : document.querySelector('[data-hs-nav-menu=\"button\"]');\n if (menuButton) {\n (menuButton as HTMLElement).click();\n (menuButton as HTMLElement).focus();\n }\n }\n };\n\n addHandler(menuContainer, 'keydown', keydownHandler);\n }\n\n setupDesktopArrowNavigation(addHandler);\n setupMenuArrowNavigation(addHandler);\n\n return {\n result: 'arrow-navigation initialized',\n destroy: () => {\n // Remove all event listeners\n cleanup.handlers.forEach(({ element, event, handler, options }) => {\n element.removeEventListener(event, handler, options);\n });\n cleanup.handlers.length = 0;\n },\n };\n}\n","/**\n * Navbar Orchestrator\n * Manages navigation functions in parallel\n *\n * Uses static imports and passes config down to functions\n */\nimport { init as dropdownInit } from './functions/dropdown.ts';\nimport { init as menuInit } from './functions/menu.ts';\nimport { init as arrowNavigationInit } from './functions/arrow-navigation.ts';\n\nexport async function init(navbarConfig) {\n const cleanup = { destroyFunctions: [] };\n\n // Load all functions in parallel - use allSettled for resilient loading\n const results = await Promise.allSettled([\n dropdownInit(navbarConfig.dropdown),\n menuInit(navbarConfig.menu, navbarConfig),\n arrowNavigationInit(navbarConfig['arrow-navigation'], navbarConfig),\n ]);\n\n // Collect destroy functions from successful inits\n results.forEach((result) => {\n if (result.status === 'fulfilled' && result.value?.destroy) {\n cleanup.destroyFunctions.push(result.value.destroy);\n }\n });\n\n // Log summary\n const succeeded = results.filter((r) => r.status === 'fulfilled').length;\n const failed = results.length - succeeded;\n if (failed > 0) {\n console.warn(\n `[navbar] ${succeeded}/${results.length} functions loaded successfully. ${failed} failed but won't affect other functions.`\n );\n }\n\n return {\n result: 'navbar initialized',\n destroy: () => {\n cleanup.destroyFunctions.forEach((destroyFn) => {\n try {\n destroyFn();\n } catch (error) {\n console.error('[navbar] Error during cleanup:', error);\n }\n });\n cleanup.destroyFunctions.length = 0;\n },\n };\n}\n","/**\n * Accordion Module\n *\n * Accessible accordion/collapsible panels with smooth height animations.\n * Syncs ARIA states with visual state via class changes and MutationObserver.\n *\n * Features:\n * - ARIA-compliant (aria-expanded, aria-controls, inert)\n * - Optional button text state swap (open/closed text)\n * - Smooth GSAP height animations\n * - Focus management (returns focus to button when closing)\n * - Default open state support\n *\n * Structure:\n * <div data-hs-accordion=\"wrapper\" data-hs-accordion-default=\"open\">\n * <button data-hs-accordion=\"toggle\">\n * Question\n * <span data-hs-accordion=\"state\">Open</span>\n * </button>\n * <div data-hs-accordion=\"content\">\n * <div data-hs-height=\"element\">Answer content</div>\n * </div>\n * </div>\n */\n\nimport {\n querySelectorAll,\n querySelector,\n getSelector,\n globalConfig,\n animateHeight,\n setHeight,\n} from '@utils';\n\ninterface EventHandler {\n element: Element | Document;\n event: string;\n handler: EventListener;\n options?: AddEventListenerOptions;\n}\n\nexport function init(config: any) {\n const cleanup = {\n observers: [] as MutationObserver[],\n handlers: [] as EventHandler[],\n };\n\n const addObserver = (observer: MutationObserver): number => cleanup.observers.push(observer);\n const addHandler = (\n element: Element | Document,\n event: string,\n handler: EventListener,\n options?: AddEventListenerOptions\n ): void => {\n element.addEventListener(event, handler, options);\n cleanup.handlers.push({ element, event, handler, options });\n };\n\n function setupAccordionAccessibility(\n addObserver: (observer: MutationObserver) => number,\n addHandler: (\n element: Element | Document,\n event: string,\n handler: EventListener,\n options?: AddEventListenerOptions\n ) => void\n ): number {\n const accordionWrappers = querySelectorAll(config, 'wrapper');\n\n if (accordionWrappers.length === 0) {\n return 0;\n }\n\n let initializedCount = 0;\n\n accordionWrappers.forEach((wrapper, index) => {\n const button = querySelector(config, 'toggle', wrapper);\n const content = querySelector(config, 'content', wrapper);\n\n if (!button || !content) {\n return;\n }\n\n initializedCount++;\n\n // Check for visual height wrapper (contains data-hs-height=\"element\")\n // If found, animate that instead of the content (content is for ARIA only)\n const heightSelector = `[${globalConfig.attributes.height}=\"${globalConfig.attributes.heightValue}\"]`;\n const heightWrapper = wrapper.querySelector(heightSelector);\n const animationTarget = heightWrapper ? heightWrapper.parentElement : content;\n\n // Generate unique IDs\n const buttonId = `hs-accordion-btn-${index}`;\n const contentId = `hs-accordion-content-${index}`;\n\n // Get text state attributes (optional)\n const openText = wrapper.getAttribute(config.attributes.properties.open);\n const closedText = wrapper.getAttribute(config.attributes.properties.closed);\n const hasTextSwap = openText && closedText;\n\n // Find all state text elements (if text swap enabled)\n let stateElements = [];\n if (hasTextSwap) {\n const stateSelector = getSelector(config, 'state');\n stateElements = Array.from(button.querySelectorAll(stateSelector));\n }\n\n // Function to update state text elements\n function updateStateText(text: string): void {\n if (!hasTextSwap) return;\n stateElements.forEach((el) => {\n el.textContent = text;\n });\n }\n\n // Set initial IDs and ARIA attributes\n button.setAttribute('id', buttonId);\n content.setAttribute('id', contentId);\n content.setAttribute('role', 'region');\n content.setAttribute('aria-labelledby', buttonId);\n button.setAttribute('aria-controls', contentId);\n\n // Function to check if accordion is open\n function isAccordionOpen() {\n return wrapper.classList.contains(globalConfig.classes.active);\n }\n\n // Update ARIA states based on current visual state\n function updateARIAStates() {\n const isOpen = isAccordionOpen();\n const wasOpen = button.getAttribute('aria-expanded') === 'true';\n\n // If closing and focus is inside content, return focus first\n if (wasOpen && !isOpen && content.contains(document.activeElement)) {\n const buttonEl = button as HTMLElement;\n buttonEl.focus();\n }\n\n // Update ARIA attributes\n button.setAttribute('aria-expanded', isOpen ? 'true' : 'false');\n const contentEl = content as HTMLElement;\n contentEl.inert = !isOpen; // Use inert instead of aria-hidden\n\n // Update state text if text swap enabled\n if (hasTextSwap && stateElements.length > 0) {\n updateStateText(isOpen ? openText : closedText);\n }\n\n // Animate height wrapper (visual container, not ARIA content)\n animateHeight(animationTarget, isOpen, { duration: 300, ease: 'power2.inOut' });\n }\n\n // Handle default open state\n const defaultState = wrapper.getAttribute(config.attributes.properties.default);\n if (defaultState && defaultState.toLowerCase() === 'open') {\n wrapper.classList.add(globalConfig.classes.active);\n }\n\n // Set initial height without animation\n setHeight(animationTarget, isAccordionOpen());\n\n // Set initial state based on existing is-active class\n updateARIAStates();\n\n // Add click handler to button\n const clickHandler = (e: Event) => {\n e.preventDefault();\n wrapper.classList.toggle(globalConfig.classes.active);\n };\n addHandler(button, 'click', clickHandler);\n\n // Monitor for class changes on wrapper\n const observer = new MutationObserver(() => {\n updateARIAStates();\n });\n\n observer.observe(wrapper, {\n attributes: true,\n attributeFilter: ['class'],\n });\n\n addObserver(observer);\n });\n\n return initializedCount;\n }\n\n setupAccordionAccessibility(addObserver, addHandler);\n\n return {\n result: 'accordion initialized',\n destroy: () => {\n // Disconnect all observers\n cleanup.observers.forEach((obs) => obs.disconnect());\n cleanup.observers.length = 0;\n\n // Remove all event listeners\n cleanup.handlers.forEach(({ element, event, handler, options }) => {\n element.removeEventListener(event, handler, options);\n });\n cleanup.handlers.length = 0;\n },\n };\n}\n","/**\n * Default Orchestrator\n * Manages default interactive modules in parallel (Phase 3)\n *\n * Uses static imports and passes config down to functions\n */\nimport config from '@config';\nimport { init as smoothScrollInit } from './functions/smooth-scroll.ts';\nimport { init as navbarInit } from './functions/navbar/navbar.ts';\nimport { init as accordionInit } from './functions/accordion.ts';\n\nconst CONFIG_ROOT = 'default';\n\nexport async function init() {\n const cleanup = { destroyFunctions: [] };\n const moduleConfig = config[CONFIG_ROOT];\n\n // Start all functions in parallel\n const modulePromises = [\n smoothScrollInit(moduleConfig['smooth-scroll'] as any),\n navbarInit(moduleConfig.navbar),\n accordionInit(moduleConfig.accordion),\n ];\n\n const results = await Promise.allSettled(modulePromises);\n\n // Collect destroy functions from successful inits\n results.forEach((result) => {\n if (result.status === 'fulfilled' && result.value?.destroy) {\n cleanup.destroyFunctions.push(result.value.destroy);\n }\n });\n\n // Log summary\n const succeeded = results.filter((r) => r.status === 'fulfilled').length;\n const failed = results.length - succeeded;\n if (failed > 0) {\n console.warn(\n `[default] ${succeeded}/${results.length} functions loaded successfully. ${failed} failed but won't affect other functions.`\n );\n }\n\n return {\n result: 'default initialized',\n destroy: () => {\n cleanup.destroyFunctions.forEach((destroyFn) => {\n try {\n destroyFn();\n } catch (error) {\n console.error('[default] Error during cleanup:', error);\n }\n });\n cleanup.destroyFunctions.length = 0;\n },\n };\n}\n"],"names":["async","init","config","clickHandler","keydownHandler","handleAnchorActivation","e","link","target","closest","href","getAttribute","targetId","substring","targetElement","document","getElementById","preventDefault","history","replaceState","id","offset","gsapLib","getGsap","prefersReducedMotion","targetPosition","getBoundingClientRect","top","window","scrollY","scrollTo","setAttribute","focus","preventScroll","gsap","to","duration","y","offsetY","ease","onComplete","scrollToElement","proxyElement","querySelector","console","log","HTMLElement","computedTop","getComputedStyle","parseFloat","getScrollOffset","$","off","documentElement","style","scrollBehavior","body","key","addEventListener","scrollHeight","innerHeight","set","result","destroy","removeEventListener","moduleConfig","cleanup","observers","handlers","addObserver","addHandler","dropdownWrappers","querySelectorAll","hoverDropdowns","forEach","wrapper","clickableSelector","getSelector","globalConfig","clickable","toggle","dropdownList","warn","type","heightWrapper","animationTarget","parentElement","toggleText","textContent","trim","sanitizedText","toLowerCase","replace","toggleId","listId","inert","menuItems","Array","from","item","index","currentMenuItemIndex","isDropdownOpen","classList","contains","classes","active","updateARIAStates","isOpen","activeElement","animateHeight","setHeight","observer","MutationObserver","observe","attributes","attributeFilter","push","mouseenterHandler","add","mouseleaveHandler","remove","length","setTimeout","dropdownKeydownHandler","focusinHandler","setupDropdown","element","event","handler","options","obs","disconnect","navbarConfig","state","focusTrapHandler","menuButtons","menu","navbarWrapper","menuId","Date","now","menuButton","shouldAutoFocus","isMenuOpen","updateMenuState","wasOpen","openModal","btn","clickableItems","formElements","focusableArray","firstElement","lastElement","shiftKey","createFocusTrap","menuClickableSelector","allElements","closeModal","removeFocusTrap","setupMenu","previousState","handleStateChange","currentState","getPropertyValue","cssVariables","cssVars","values","inactive","stateObserver","ResizeObserver","setupMenuDisplayObserver","navbar","openDropdown","allNavbarElements","focusableElements","filter","el","menuSelector","elements","primary","split","skipSelector","computedStyle","htmlEl","display","visibility","opacity","offsetWidth","offsetHeight","parent","parentStyle","parentHtmlEl","currentIndex","indexOf","menuContainer","currentFocusIndex","current","getFocusableElements","tagName","hasAttribute","click","setupMenuArrowNavigation","destroyFunctions","results","Promise","allSettled","dropdownInit","dropdown","menuInit","arrowNavigationInit","status","value","succeeded","r","failed","destroyFn","error","accordionWrappers","initializedCount","button","content","heightSelector","height","heightValue","buttonId","contentId","openText","properties","open","closedText","closed","hasTextSwap","stateElements","stateSelector","isAccordionOpen","text","defaultState","default","setupAccordionAccessibility","modulePromises","smoothScrollInit","navbarInit","accordionInit","accordion"],"mappings":"iRAqCAA,eAAsBC,EAAKC,GAEzB,IAAIC,EAA4C,KAC5CC,EAAsD,KAuD1D,SAASC,EAAuBC,GAC9B,MAAMC,EAAQD,EAAEE,OAAmBC,QAAQ,gBAC3C,IAAKF,EAAM,OAEX,MAAMG,EAAOH,EAAKI,aAAa,QAC/B,IAAKD,GAAiB,MAATA,EAAc,OAE3B,MAAME,EAAWF,EAAKG,UAAU,GAC1BC,EAAgBC,SAASC,eAAeJ,GAE9C,GAAIE,EAAe,CACjBR,EAAEW,iBACEC,QAAQC,cACVD,QAAQC,aAAa,KAAM,KAAM,IAAIL,EAAcM,OAzCzD,SAAyBZ,EAAqBa,EAAS,GACrD,IAAKb,EAAQ,OAEb,MAAMc,EAAUC,EAAQ,iBAAiB,GAGzC,GAAIC,MAA2BF,EAAS,CACtC,MAAMG,EAAiBjB,EAAOkB,wBAAwBC,IAAMC,OAAOC,QAAUR,EAI7E,OAHAO,OAAOE,SAAS,EAAGL,GACnBjB,EAAOuB,aAAa,WAAY,WAChCvB,EAAOwB,MAAM,CAAEC,eAAe,GAEhC,CAEAX,EAAQY,KAAKC,GAAGP,OAAQ,CACtBQ,SAAU,EACVN,SAAU,CACRO,EAAG7B,EACH8B,QAASjB,GAEXkB,KAAM,aACNC,WAAY,WACVhC,EAAOuB,aAAa,WAAY,MAChCvB,EAAOwB,MAAM,CAAEC,eAAe,GAChC,GAEJ,CAkBIQ,CAAgB3B,EA3DpB,WAEE,MAAM4B,EAAeC,EAAczC,EAAQ,gBAE3C,GADA0C,QAAQC,IAAI,iCAAkCH,GAC1CA,GAAgBA,aAAwBI,YAAa,CACvD,MAAMC,EAAcC,iBAAiBN,GAAcf,IAC7CN,EAAS4B,WAAWF,IAAgB,EAE1C,OADAH,QAAQC,IAAI,gCAAiCE,EAAa,aAAc1B,GACjEA,CACT,CAEA,OADAuB,QAAQC,IAAI,2DACL,CACT,CA8CmBK,GAEjB,CACF,CArEiB,oBAANC,GACTA,EAAEpC,UAAUqC,IAAI,mBAIlBrC,SAASsC,gBAAgBC,MAAMC,eAAiB,OAChDxC,SAASyC,KAAKF,MAAMC,eAAiB,OAmEnCpD,EAAeE,EACfD,EAAkBE,IACF,UAAVA,EAAEmD,KAA6B,MAAVnD,EAAEmD,KACzBpD,EAAuBC,IAI3BS,SAAS2C,iBAAiB,QAASvD,GACnCY,SAAS2C,iBAAiB,UAAWtD,GAOvC,MAAMkB,EAAUC,EAAQ,iBAAiB,GAMzC,OALID,GAAWP,SAASyC,KAAKG,aAAe/B,OAAOgC,cACjDtC,EAAQY,KAAK2B,IAAIjC,OAAQ,CAAEE,SAAU,IACrCR,EAAQY,KAAK2B,IAAIjC,OAAQ,CAAEE,SAAU,KAGhC,CACLgC,OAAQ,qCACRC,QAAS,KAEH5D,IACFY,SAASiD,oBAAoB,QAAS7D,GACtCA,EAAe,MAEbC,IACFW,SAASiD,oBAAoB,UAAW5D,GACxCA,EAAiB,MAInBW,SAASsC,gBAAgBC,MAAMC,eAAiB,GAChDxC,SAASyC,KAAKF,MAAMC,eAAiB,IAG3C,CC1GA,IAAIU,EAAoC,KAEjC,SAAShE,EAAKC,GAEnB+D,EAAe/D,EAEf,MAAMgE,EAAU,CACdC,UAAW,GACXC,SAAU,IAoSZ,OA3QA,SACEC,EACAC,GAOA,MAAMC,EAAmBC,EAAiBP,EAAqB,WACzDQ,EAA4B,GAElCF,EAAiBG,QAASC,IACxB,MAAMC,EAAoBC,EAAYC,EAAaC,UAAkB,UAC/DC,EAASL,EAAQhC,cAAciC,GAC/BK,EAAetC,EAAcsB,EAAqB,OAAQU,GAEhE,IAAKK,IAAWC,EAEd,YADArC,QAAQsC,KAAK,yDAA0DP,GAKzE,MAAMQ,EAAOR,EAAQhE,aAAa,8BAAgC,QAK5DyE,EAAgBT,EAAQhC,cAAc,8BACtC0C,EAAkBD,EAAgBA,EAAcE,cAAgB,KAEhEC,EAAaP,EAAOQ,aAAaC,QAAU,WAC3CC,EAA8BH,EAvCnCI,cACAC,QAAQ,eAAgB,IACxBA,QAAQ,OAAQ,KAChBA,QAAQ,WAAY,IACpB/E,UAAU,EAAG,IAoCd,MAAMgF,EAAW,mBAAmBH,WAC9BI,EAAS,mBAAmBJ,SAElCV,EAAO5D,GAAKyE,EACZb,EAAOjD,aAAa,gBAAiB,QACrCiD,EAAOjD,aAAa,gBAAiB,SACrCiD,EAAOjD,aAAa,gBAAiB+D,GAErCb,EAAa7D,GAAK0E,EAClBb,EAAalD,aAAa,OAAQ,QACjCkD,EAA6Bc,OAAQ,EAEtC,MAAMC,EAAYC,MAAMC,KAAKjB,EAAaT,iBAAiBI,IAC3DoB,EAAUtB,QAAQ,CAACyB,EAAMC,KAKvB,GAJAD,EAAKpE,aAAa,OAAQ,YAC1BoE,EAAKpE,aAAa,WAAY,MAGhB,IAAVqE,EAAa,CACf,MAAMb,EAAaP,EAAOQ,aAAaC,QAAU,OAC3BU,EAAKxF,aAAa,eAEtCwF,EAAKpE,aAAa,aAAc,GAAGoE,EAAKX,aAAaC,WAAWF,YAEpE,IAGF,IAAIc,GAAuB,EAG3B,SAASC,IACP,OAAO3B,EAAQ4B,UAAUC,SAAS1B,EAAa2B,QAAQC,OACzD,CAGA,SAASC,IACP,MAAMC,EAASN,IAC0C,SAAzCtB,EAAOrE,aAAa,mBAGpBiG,GAAU3B,EAAauB,SAASzF,SAAS8F,gBACtD7B,EAAuBhD,QAG1BgD,EAAOjD,aAAa,gBAAiB6E,EAAS,OAAS,SACtD3B,EAA6Bc,OAASa,EACvCZ,EAAUtB,QAASyB,IACjBA,EAAKpE,aAAa,WAAY6E,EAAS,IAAM,QAG1CA,IACHP,GAAuB,GAIzBS,EAAczB,EAAiBuB,EAAQ,CACrCxE,SAAmB,UAAT+C,EAAmB,IAAM,IACnC5C,KAAM,gBAEV,CAGAwE,EAAU1B,EAAiBiB,KAG3BK,IAGA,MAAMK,EAAW,IAAIC,iBAAiB,KACpCN,MAcF,GAXAK,EAASE,QAAQvC,EAAS,CACxBwC,YAAY,EACZC,gBAAiB,CAAC,WAGpB/C,EAAY2C,GAMC,UAAT7B,EAAkB,CAIpBV,EAAe4C,KAAK1C,GAGpB,MAAM2C,EAAoB,KACxB3C,EAAQ4B,UAAUgB,IAAI,cAGlBC,EAAoB,KACxB7C,EAAQ4B,UAAUkB,OAAO,cAG3BnD,EAAWK,EAAS,aAAc2C,GAClChD,EAAWK,EAAS,aAAc6C,GAyDlClD,EAAWU,EAAQ,UAtDW1E,IACd,cAAVA,EAAEmD,KACJnD,EAAEW,iBAEGqF,MACH3B,EAAQ4B,UAAUgB,IAAIzC,EAAa2B,QAAQC,QAGvCV,EAAU0B,OAAS,GACrBC,WAAW,KACTtB,EAAuB,EACtBL,EAAU,GAAmBhE,SAC7B,OAGY,MAAV1B,EAAEmD,KAAyB,UAAVnD,EAAEmD,KAC5BnD,EAAEW,iBAEGqF,IAWH3B,EAAQ4B,UAAUkB,OAAO3C,EAAa2B,QAAQC,SAV9C/B,EAAQ4B,UAAUgB,IAAIzC,EAAa2B,QAAQC,QAGvCV,EAAU0B,OAAS,GACrBC,WAAW,KACTtB,EAAuB,EACtBL,EAAU,GAAmBhE,SAC7B,OAKY,YAAV1B,EAAEmD,KACXnD,EAAEW,iBAEGqF,MACH3B,EAAQ4B,UAAUgB,IAAIzC,EAAa2B,QAAQC,QAGvCV,EAAU0B,OAAS,GACrBC,WAAW,KACTtB,EAAuBL,EAAU0B,OAAS,EACzC1B,EAAUK,GAAsCrE,SAChD,OAGY,WAAV1B,EAAEmD,MACXnD,EAAEW,iBAEEqF,KACF3B,EAAQ4B,UAAUkB,OAAO3C,EAAa2B,QAAQC,WAQpD,MAAMkB,EAA0BtH,IACzBgG,KACA3B,EAAQ6B,SAASzF,SAAS8F,iBAEjB,cAAVvG,EAAEmD,KACJnD,EAAEW,iBACEoF,EAAuBL,EAAU0B,OAAS,IAC5CrB,IACCL,EAAUK,GAAsCrE,UAEhC,YAAV1B,EAAEmD,KACXnD,EAAEW,iBAC2B,IAAzBoF,GACF1B,EAAQ4B,UAAUkB,OAAO3C,EAAa2B,QAAQC,QAC7C1B,EAAuBhD,QACxBqE,GAAuB,GACdA,EAAuB,GAChCA,IACCL,EAAUK,GAAsCrE,UAEhDgD,EAAuBhD,QACxBqE,GAAuB,IAEN,WAAV/F,EAAEmD,MACXnD,EAAEW,iBACF0D,EAAQ4B,UAAUkB,OAAO,gBAI7BnD,EAAWK,EAAS,UAAWiD,EACjC,MAAA,GAAoB,UAATzC,EAAkB,CAS3Bb,EAAWU,EAAQ,QALG1E,IACpBA,EAAEW,iBACF0D,EAAQ4B,UAAUvB,OAAOF,EAAa2B,QAAQC,UAkBhDpC,EAAWU,EAAQ,UAZW1E,IACd,MAAVA,EAAEmD,KAAyB,UAAVnD,EAAEmD,KACrBnD,EAAEW,iBACF0D,EAAQ4B,UAAUvB,OAAOF,EAAa2B,QAAQC,SAC3B,WAAVpG,EAAEmD,MACXnD,EAAEW,iBACEqF,KACF3B,EAAQ4B,UAAUkB,OAAO3C,EAAa2B,QAAQC,UAMtD,IAIF,MAAMmB,EAAkBvH,IACtBmE,EAAeC,QAASC,IAClBA,EAAQ4B,UAAUC,SAAS,eAAiB7B,EAAQ6B,SAASlG,EAAEE,SACjEmE,EAAQ4B,UAAUkB,OAAO,gBAM3BhD,EAAeiD,OAAS,GAC1BpD,EAAWvD,SAASyC,KAAM,UAAWqE,EAEzC,CAEAC,CA/RqBd,IACnB9C,EAAQC,UAAUkD,KAAKL,IAEN,CACjBe,EACAC,EACAC,EACAC,KAEAH,EAAQrE,iBAAiBsE,EAAOC,EAASC,GACzChE,EAAQE,SAASiD,KAAK,CAAEU,UAASC,QAAOC,UAASC,cAuR5C,CACLpE,OAAQ,uBACRC,QAAS,KAEPG,EAAQC,UAAUO,QAASyD,GAAQA,EAAIC,cACvClE,EAAQC,UAAUuD,OAAS,EAG3BxD,EAAQE,SAASM,QAAQ,EAAGqD,UAASC,QAAOC,UAASC,cACnDH,EAAQ/D,oBAAoBgE,EAAOC,EAASC,KAE9ChE,EAAQE,SAASsD,OAAS,EAG1BzD,EAAe,MAGrB,CC/TO,SAAShE,EAAKC,EAAsBmI,GACzC,MAAMnE,EAAU,CACdC,UAAW,GACXC,SAAU,GACVkE,MAAO,CACLC,iBAAkB,OAIhBlE,EAAe2C,IACnB9C,EAAQC,UAAUkD,KAAKL,IA8RzB,OAtOA,SACE3C,EACAC,GAOA,MAAMkE,EAAchE,EAAiBtE,EAAe,UAC9CuI,EAAO9F,EAAczC,EAAe,WAE1C,IAAKsI,EAAYd,SAAWe,EAAM,OAGlC,MAAMC,EAAgBL,EAAe1F,EAAc0F,EAAqB,WAAa,KAE/EM,EAAS,QAAQC,KAAKC,QAE5BJ,EAAKrH,GAAKuH,EACVF,EAAK1G,aAAa,OAAQ,UAC1B0G,EAAK1G,aAAa,aAAc,QAC/B0G,EAAqB1C,OAAQ,EAK9B,MAAMX,EAAgBqD,EAAK9F,cAAc,8BACnC0C,EAAkBD,EAAgBA,EAAcE,cAAgB,KAEtEkD,EAAY9D,QAASoE,IACnBA,EAAW/G,aAAa,gBAAiB,SACzC+G,EAAW/G,aAAa,gBAAiB4G,GACzCG,EAAW/G,aAAa,aAAc,wBAEtC,IAAIwG,EAAwD,KACxDQ,GAAoC,EAGxC,SAASC,IACP,OAAOF,EAAWvC,UAAUC,SAAS1B,EAAa2B,QAAQC,OAC5D,CAGA,SAASuC,IACP,MAAMrC,EAASoC,IACTE,EAAuD,SAA7CJ,EAAWnI,aAAa,iBAEpCiG,IAAWsC,GAEbC,IAGAV,EAAKlC,UAAUgB,IAAIzC,EAAa2B,QAAQC,QACvC+B,EAAqB1C,OAAQ,EAG1B2C,GACFA,EAAcnC,UAAUgB,IAAI,gBAG9BiB,EAAY9D,QAAS0E,IACnBA,EAAIrH,aAAa,gBAAiB,QAClCqH,EAAIrH,aAAa,aAAc,2BAI7BsD,GACFyB,EAAczB,GAAiB,EAAM,CAAEjD,SAAU,IAAKG,KAAM,iBAI9DgG,EApHR,WACE,MAAMG,EAAgBL,EAClB1F,EAAc0F,EAAqB,WACnCtH,SAAS4B,cAAc,2BAE3B,IAAK+F,EAAe,OAEpB,MAAMH,EAAoBjI,IACxB,GAAc,QAAVA,EAAEmD,IAAe,CACnB,MAAMmB,EAAoBC,EAAYC,EAAaC,UAAkB,UAC/DsE,EAAiBpD,MAAMC,KAAKwC,EAAclE,iBAAiBI,IAC3D0E,EAAeZ,EAAclE,iBACjC,4DAEI+E,EAAiB,IAAIF,KAAmBpD,MAAMC,KAAKoD,IACnDE,EAAeD,EAAe,GAC9BE,EAAcF,EAAeA,EAAe7B,OAAS,GAEvDpH,EAAEoJ,SAEA3I,SAAS8F,gBAAkB2C,IAC7BlJ,EAAEW,iBACDwI,EAA4BzH,SAI3BjB,SAAS8F,gBAAkB4C,IAC7BnJ,EAAEW,iBACDuI,EAA6BxH,QAGpC,GAIF,OADAjB,SAAS2C,iBAAiB,UAAW6E,GAC9BA,CACT,CAgF2BoB,GAGfZ,IACFpB,WAAW,KACT,MAAMiC,EAAwB/E,EAAYC,EAAaC,UAAkB,UACnE8E,EAAc5D,MAAMC,KAAKuC,EAAKjE,iBAAiBoF,IAErD,GAAwB,SAApBb,EAA4B,CAE9B,MAAMU,EAAcI,EAAYA,EAAYnC,OAAS,GACjD+B,GACDA,EAA4BzH,OAEjC,KAAO,CAEL,MAAMwH,EAAeK,EAAY,GAC7BL,GACDA,EAA6BxH,OAElC,GACC,KACH+G,GAAkB,KAEVnC,GAAUsC,IAEhBT,EAAKjC,SAASzF,SAAS8F,gBACxBiC,EAA2B9G,QAI9B8H,IAGArB,EAAKlC,UAAUkB,OAAO3C,EAAa2B,QAAQC,QAC1C+B,EAAqB1C,OAAQ,EAG1B2C,GACFA,EAAcnC,UAAUkB,OAAO,gBAGjCe,EAAY9D,QAAS0E,IACnBA,EAAIrH,aAAa,gBAAiB,SAClCqH,EAAIrH,aAAa,aAAc,0BAI7BsD,GACFyB,EAAczB,GAAiB,EAAO,CAAEjD,SAAU,IAAKG,KAAM,iBA/HvE,SAAyBgG,GACnBA,GACFxH,SAASiD,oBAAoB,UAAWuE,EAE5C,CA+HQwB,CAAgBxB,GAChBA,EAAmB,KAEvB,CAGIlD,GACF0B,EAAU1B,EAAiB2D,KAI7BC,IAGA,MAAMjC,EAAW,IAAIC,iBAAiB,KACpCgC,MAGFjC,EAASE,QAAQ4B,EAAY,CAC3B3B,YAAY,EACZC,gBAAiB,CAAC,WAGpB/C,EAAY2C,GAQZ1C,EAAWwE,EAAY,QALF,SAAUxI,GAC7BA,EAAEW,iBACF6H,EAAWvC,UAAUvB,OAAO,YAC9B,GA+BAV,EAAWwE,EAAY,UA1BA,SAAUxI,GACjB,MAAVA,EAAEmD,KAAyB,UAAVnD,EAAEmD,KACrBnD,EAAEW,iBACF8H,GAAkB,EAClBD,EAAWvC,UAAUvB,OAAOF,EAAa2B,QAAQC,SAC9B,cAAVpG,EAAEmD,KACXnD,EAAEW,iBACG+H,MACHD,GAAkB,EAClBD,EAAWvC,UAAUgB,IAAIzC,EAAa2B,QAAQC,UAE7B,YAAVpG,EAAEmD,KACXnD,EAAEW,iBACG+H,MACHD,EAAkB,OAClBD,EAAWvC,UAAUgB,IAAIzC,EAAa2B,QAAQC,UAE7B,WAAVpG,EAAEmD,MACXnD,EAAEW,iBAEE+H,KACFF,EAAWvC,UAAUkB,OAAO3C,EAAa2B,QAAQC,QAGvD,GAKAxC,EAAQoE,MAAMC,iBAAmBA,GAErC,CAqCAyB,CAAU3F,EAzRS,CACjB0D,EACAC,EACAC,EACAC,KAEAH,EAAQrE,iBAAiBsE,EAAOC,EAASC,GACzChE,EAAQE,SAASiD,KAAK,CAAEU,UAASC,QAAOC,UAASC,cA+OnD,SAAkC7D,GAChC,MAAMoE,EAAO9F,EAAczC,EAAQ,WACnC,IAAKuI,EAAM,OAEX,IAAIwB,EAAgB,KAEpB,SAASC,IACP,MACMC,EADgBvI,OAAOoB,iBAAiByF,GACX2B,iBAAiBC,EAAa/B,OAAO7C,OAGxE,GACEwE,IAAkBnF,EAAawF,QAAQhC,MAAMiC,OAAO7D,QACpDyD,IAAiBrF,EAAawF,QAAQhC,MAAMiC,OAAOC,SACnD,CAEA,MAAM1B,EAAa/H,SAAS4B,cAAc,+BACvBmG,GAA2D,SAA7CA,EAAWnI,aAAa,kBAGvCmI,GAChBA,EAAWvC,UAAUkB,OAAO,YAEhC,CAEAwC,EAAgBE,CAClB,CAEA,MAAMM,EAAgB,IAAIC,eAAeR,GACzCO,EAAcvD,QAAQuB,GACtBpE,EAAYoG,GAEZP,GACF,CAGAS,CAAyBtG,GAElB,CACLP,OAAQ,mBACRC,QAAS,KAEHG,EAAQoE,MAAMC,mBAChBxH,SAASiD,oBAAoB,UAAWE,EAAQoE,MAAMC,kBACtDrE,EAAQoE,MAAMC,iBAAmB,MAInCrE,EAAQC,UAAUO,QAASyD,GAAQA,EAAIC,cACvClE,EAAQC,UAAUuD,OAAS,EAG3BxD,EAAQE,SAASM,QAAQ,EAAGqD,UAASC,QAAOC,UAASC,cACnDH,EAAQ/D,oBAAoBgE,EAAOC,EAASC,KAE9ChE,EAAQE,SAASsD,OAAS,EAG1B3G,SAASyC,KAAK+C,UAAUkB,OAAO,sBAGrC,CCtUO,SAASxH,EAAKC,EAAsBmI,GACzC,MAAMnE,EAAU,CACdE,SAAU,IAGNE,EAAa,CACjByD,EACAC,EACAC,EACAC,KAEAH,EAAQrE,iBAAiBsE,EAAOC,EAASC,GACzChE,EAAQE,SAASiD,KAAK,CAAEU,UAASC,QAAOC,UAASC,aAyMnD,OAH4B5D,EAvGfvD,SAAU,UApFGT,IACtB,GAAc,cAAVA,EAAEmD,KAAiC,eAAVnD,EAAEmD,IAAsB,OAErD,MAAMgF,EAAOJ,EACT1F,EAAc0F,EAAaI,KAAa,WACxC1H,SAAS4B,cAAc,gCAC3B,GAAI8F,GAAQA,EAAKjC,SAASzF,SAAS8F,eAAgB,OAEnD,MAAM+D,EAASvC,EACX1F,EAAc0F,EAAqB,WACnCtH,SAAS4B,cAAc,2BAE3B,IAAKiI,IAAWA,EAAOpE,SAASzF,SAAS8F,eAAgB,OAGzD,MAAMgE,EAAeD,EAAOjI,cAC1B,IAAImC,EAAa2B,QAAQC,gCAE3B,GAAImE,GAAgBA,EAAarE,SAASzF,SAAS8F,eAAgB,OAEnEvG,EAAEW,iBAEF,MAAM2D,EAAoBC,EAAYC,EAAaC,UAAkB,UAC/D+F,EAAoB7E,MAAMC,KAAK0E,EAAOpG,iBAAiBI,IACvDmG,EAAoB9E,MAAMC,KAAK4E,GAAmBE,OAAQC,IAC9D,GAAoC,OAAhCA,EAAGtK,aAAa,YAAsB,OAAO,EAGjD,GADyBsK,EAAGxK,QAAQ,iBACd,OAAO,EAE7B,MAAMyK,EAAe7C,EACjBA,EAAaI,KAAKtB,WAAWgE,SAASxG,QAAQyG,QAAQC,MAAM,KAAK,GACjE,mBAEJ,GADiBJ,EAAGxK,QAAQ,IAAIyK,gBAClB,OAAO,EAErB,MAAMI,EAAejD,EACjBA,EAAalB,WAAWgE,SAAS,aAAaC,QAAQC,MAAM,KAAK,GACjE,cAEJ,GADqBJ,EAAGxK,QAAQ,IAAI6K,kBAClB,OAAO,EAEzB,MAAMC,EAAgB3J,OAAOoB,iBAAiBiI,GACxCO,EAASP,EAOf,GAL4B,SAA1BM,EAAcE,SACe,WAA7BF,EAAcG,YACY,MAA1BH,EAAcI,SACS,IAAvBH,EAAOI,aACiB,IAAxBJ,EAAOK,aACK,OAAO,EAErB,IAAIC,EAASb,EAAG3F,cAChB,KAAOwG,GAAUA,IAAWlB,GAAQ,CAClC,MAAMmB,EAAcnK,OAAOoB,iBAAiB8I,GACtCE,EAAeF,EAMrB,GAJ0B,SAAxBC,EAAYN,SACe,WAA3BM,EAAYL,YACiB,IAA7BM,EAAaJ,aACiB,IAA9BI,EAAaH,aACG,OAAO,EACzBC,EAASA,EAAOxG,aAClB,CAEA,OAAO,IAGH2G,EAAelB,EAAkBmB,QAAQnL,SAAS8F,gBACnC,IAAjBoF,IAEU,eAAV3L,EAAEmD,IACAwI,EAAelB,EAAkBrD,OAAS,GAE3CqD,EADiBkB,EAAe,GACajK,QAG5CiK,EAAe,GAEhBlB,EADiBkB,EAAe,GACajK,WAQtD,SACEsC,GAOA,MAAM6H,EAAgB9D,EAClB1F,EAAc0F,EAAaI,KAAa,WACxC1H,SAAS4B,cAAc,gCAC3B,IAAKwJ,EAAe,OAkBpB,IAAIC,GAAoB,EAoExB9H,EAAW6H,EAAe,UAlEF7L,IACtB,MAAMyK,EAnBR,WACE,MAAMnB,EAAwB/E,EAAYC,EAAaC,UAAkB,UACnE8E,EAAc5D,MAAMC,KAAKiG,EAAc3H,iBAAiBoF,IAC9D,OAAO3D,MAAMC,KAAK2D,GAAamB,OAAQC,IAErC,IAAIoB,EAA0BpB,EAC9B,KAAOoB,GAAWA,IAAYF,GAAe,CAC3C,GAAKE,EAAwBtG,MAC3B,OAAO,EAETsG,EAAUA,EAAQ/G,aACpB,CACA,OAAO,GAEX,CAK4BgH,GAC1B,GAAiC,IAA7BvB,EAAkBrD,OAAc,OAEpC,MAAMb,EAAgB9F,SAAS8F,cAG/B,GAFAuF,EAAoBrB,EAAkBmB,QAAQrF,GAEhC,cAAVvG,EAAEmD,IACJnD,EAAEW,iBACEmL,EAAoBrB,EAAkBrD,OAAS,IACjD0E,GAAwC,EACvCrB,EAAkBqB,GAAmCpK,cAE1D,GAAqB,YAAV1B,EAAEmD,IACXnD,EAAEW,iBACEmL,EAAoB,IACtBA,GAAwC,EACvCrB,EAAkBqB,GAAmCpK,cAE1D,GAAqB,eAAV1B,EAAEmD,KAEX,GADAnD,EAAEW,iBAEA4F,GAC2C,WAA1CA,EAA8B0F,SAC/B1F,EAAc2F,aAAa,iBAC3B,CAKA,YAJmE,SAAhD3F,EAAclG,aAAa,kBAE3CkG,EAA8B4F,QAGnC,OACF,GAAqB,cAAVnM,EAAEmD,KAEX,GADAnD,EAAEW,iBAEA4F,GAC2C,WAA1CA,EAA8B0F,SAC/B1F,EAAc2F,aAAa,iBAC3B,CAKA,YAJmE,SAAhD3F,EAAclG,aAAa,kBAE3CkG,EAA8B4F,QAGnC,OACF,GAAqB,SAAVnM,EAAEmD,IACXnD,EAAEW,iBACFmL,EAAoB,EACnBrB,EAAkB,GAAmB/I,aACxC,GAAqB,QAAV1B,EAAEmD,IACXnD,EAAEW,iBACFmL,EAAoBrB,EAAkBrD,OAAS,EAC9CqD,EAAkBA,EAAkBrD,OAAS,GAAmB1F,gBAC9C,MAAV1B,EAAEmD,KAAeoD,GAA4D,MAA1CA,EAA8B0F,QAC1EjM,EAAEW,sBACJ,GAAqB,WAAVX,EAAEmD,IAAkB,CAC7B,MAAMqF,EAAaT,EACf1F,EAAc0F,EAAaI,KAAa,UACxC1H,SAAS4B,cAAc,+BACvBmG,IACDA,EAA2B2D,QAC3B3D,EAA2B9G,QAEhC,GAIJ,CAGA0K,CAAyBpI,GAElB,CACLR,OAAQ,+BACRC,QAAS,KAEPG,EAAQE,SAASM,QAAQ,EAAGqD,UAASC,QAAOC,UAASC,cACnDH,EAAQ/D,oBAAoBgE,EAAOC,EAASC,KAE9ChE,EAAQE,SAASsD,OAAS,GAGhC,CC9PA1H,eAAsBC,EAAKoI,GACzB,MAAMnE,EAAU,CAAEyI,iBAAkB,IAG9BC,QAAgBC,QAAQC,WAAW,CACvCC,EAAa1E,EAAa2E,UAC1BC,EAAS5E,EAAaI,KAAMJ,GAC5B6E,EAAoB7E,EAAa,oBAAqBA,KAIxDuE,EAAQlI,QAASZ,IACO,cAAlBA,EAAOqJ,QAA0BrJ,EAAOsJ,OAAOrJ,SACjDG,EAAQyI,iBAAiBtF,KAAKvD,EAAOsJ,MAAMrJ,WAK/C,MAAMsJ,EAAYT,EAAQ5B,OAAQsC,GAAmB,cAAbA,EAAEH,QAAwBzF,OAC5D6F,EAASX,EAAQlF,OAAS2F,EAOhC,OANIE,EAAS,GACX3K,QAAQsC,KACN,YAAYmI,KAAaT,EAAQlF,yCAAyC6F,8CAIvE,CACLzJ,OAAQ,qBACRC,QAAS,KACPG,EAAQyI,iBAAiBjI,QAAS8I,IAChC,IACEA,GACF,OAASC,GACP7K,QAAQ6K,MAAM,iCAAkCA,EAClD,IAEFvJ,EAAQyI,iBAAiBjF,OAAS,GAGxC,CCRO,SAASzH,EAAKC,GACnB,MAAMgE,EAAU,CACdC,UAAW,GACXC,SAAU,IAiJZ,OAnIA,SACEC,EACAC,GAOA,MAAMoJ,EAAoBlJ,EAAiBtE,EAAQ,WAEnD,GAAiC,IAA7BwN,EAAkBhG,OACpB,OAAO,EAGT,IAAIiG,EAAmB,EAEvBD,EAAkBhJ,QAAQ,CAACC,EAASyB,KAClC,MAAMwH,EAASjL,EAAczC,EAAQ,SAAUyE,GACzCkJ,EAAUlL,EAAczC,EAAQ,UAAWyE,GAEjD,IAAKiJ,IAAWC,EACd,OAGFF,IAIA,MAAMG,EAAiB,IAAIhJ,EAAaqC,WAAW4G,WAAWjJ,EAAaqC,WAAW6G,gBAChF5I,EAAgBT,EAAQhC,cAAcmL,GACtCzI,EAAkBD,EAAgBA,EAAcE,cAAgBuI,EAGhEI,EAAW,oBAAoB7H,IAC/B8H,EAAY,wBAAwB9H,IAGpC+H,EAAWxJ,EAAQhE,aAAaT,EAAOiH,WAAWiH,WAAWC,MAC7DC,EAAa3J,EAAQhE,aAAaT,EAAOiH,WAAWiH,WAAWG,QAC/DC,EAAcL,GAAYG,EAGhC,IAAIG,EAAgB,GACpB,GAAID,EAAa,CACf,MAAME,EAAgB7J,EAAY3E,EAAQ,SAC1CuO,EAAgBxI,MAAMC,KAAK0H,EAAOpJ,iBAAiBkK,GACrD,CAkBA,SAASC,IACP,OAAOhK,EAAQ4B,UAAUC,SAAS1B,EAAa2B,QAAQC,OACzD,CAGA,SAASC,IACP,MAAMC,EAAS+H,IAIf,GAHyD,SAAzCf,EAAOjN,aAAa,mBAGpBiG,GAAUiH,EAAQrH,SAASzF,SAAS8F,eAAgB,CACjD+G,EACR5L,OACX,CAGA4L,EAAO7L,aAAa,gBAAiB6E,EAAS,OAAS,SA/BzD,IAAyBgI,EAgCLf,EACR9H,OAASa,EAGf4H,GAAeC,EAAc/G,OAAS,IApCnBkH,EAqCLhI,EAASuH,EAAWG,EApCjCE,GACLC,EAAc/J,QAASuG,IACrBA,EAAGzF,YAAcoJ,KAsCnB9H,EAAczB,EAAiBuB,EAAQ,CAAExE,SAAU,IAAKG,KAAM,gBAChE,CAlCAqL,EAAO7L,aAAa,KAAMkM,GAC1BJ,EAAQ9L,aAAa,KAAMmM,GAC3BL,EAAQ9L,aAAa,OAAQ,UAC7B8L,EAAQ9L,aAAa,kBAAmBkM,GACxCL,EAAO7L,aAAa,gBAAiBmM,GAiCrC,MAAMW,EAAelK,EAAQhE,aAAaT,EAAOiH,WAAWiH,WAAWU,SACnED,GAA+C,SAA/BA,EAAalJ,eAC/BhB,EAAQ4B,UAAUgB,IAAIzC,EAAa2B,QAAQC,QAI7CK,EAAU1B,EAAiBsJ,KAG3BhI,IAOArC,EAAWsJ,EAAQ,QAJGtN,IACpBA,EAAEW,iBACF0D,EAAQ4B,UAAUvB,OAAOF,EAAa2B,QAAQC,UAKhD,MAAMM,EAAW,IAAIC,iBAAiB,KACpCN,MAGFK,EAASE,QAAQvC,EAAS,CACxBwC,YAAY,EACZC,gBAAiB,CAAC,WAGpB/C,EAAY2C,IAIhB,CAEA+H,CA5IqB/H,GAAuC9C,EAAQC,UAAUkD,KAAKL,GAChE,CACjBe,EACAC,EACAC,EACAC,KAEAH,EAAQrE,iBAAiBsE,EAAOC,EAASC,GACzChE,EAAQE,SAASiD,KAAK,CAAEU,UAASC,QAAOC,UAASC,cAsI5C,CACLpE,OAAQ,wBACRC,QAAS,KAEPG,EAAQC,UAAUO,QAASyD,GAAQA,EAAIC,cACvClE,EAAQC,UAAUuD,OAAS,EAG3BxD,EAAQE,SAASM,QAAQ,EAAGqD,UAASC,QAAOC,UAASC,cACnDH,EAAQ/D,oBAAoBgE,EAAOC,EAASC,KAE9ChE,EAAQE,SAASsD,OAAS,GAGhC,CC9LA1H,eAAsBC,IACpB,MAAMiE,EAAU,CAAEyI,iBAAkB,IAC9B1I,EAAe/D,EAAkB,QAGjC8O,EAAiB,CACrBC,EAAiBhL,EAAa,kBAC9BiL,EAAWjL,EAAa2G,QACxBuE,EAAclL,EAAamL,YAGvBxC,QAAgBC,QAAQC,WAAWkC,GAGzCpC,EAAQlI,QAASZ,IACO,cAAlBA,EAAOqJ,QAA0BrJ,EAAOsJ,OAAOrJ,SACjDG,EAAQyI,iBAAiBtF,KAAKvD,EAAOsJ,MAAMrJ,WAK/C,MAAMsJ,EAAYT,EAAQ5B,OAAQsC,GAAmB,cAAbA,EAAEH,QAAwBzF,OAC5D6F,EAASX,EAAQlF,OAAS2F,EAOhC,OANIE,EAAS,GACX3K,QAAQsC,KACN,aAAamI,KAAaT,EAAQlF,yCAAyC6F,8CAIxE,CACLzJ,OAAQ,sBACRC,QAAS,KACPG,EAAQyI,iBAAiBjI,QAAS8I,IAChC,IACEA,GACF,OAASC,GACP7K,QAAQ6K,MAAM,kCAAmCA,EACnD,IAEFvJ,EAAQyI,iBAAiBjF,OAAS,GAGxC"}
@@ -0,0 +1,2 @@
1
+ import{c as e}from"../main.js";import{a as t,q as n,g as o}from"./hs-attributeSelector-6pGcDBo-.js";import{s as a,o as r,c as s,a as i}from"./hs-modalManager-H_YegPAO.js";function l(o){const a={handlers:[],domContentLoadedHandler:null},r=(e,t,n)=>{e.addEventListener(t,n),a.handlers.push({element:e,event:t,handler:n})};function s(){n(o,"wrapper").forEach(n=>{const a=n;a.dataset.hsFormRangeInit||(a.dataset.hsFormRangeInit="true",function(n,a){const r=n.querySelector("input[type='range']");if(!r)return void console.warn('[range] Missing <input type="range"> element in wrapper',n);const s=t(o,"output",n),i=()=>{const t=r.min?+r.min:0,a=r.max?+r.max:100,i=+r.value||t,l=(i-t)/(a-t);n.style.setProperty(`${e._global.cssVars.prefix}${o.cssVars?.progress||"progress"}`,String(l)),s&&(s.textContent=String(i))};a(r,"input",i),i()}(a,r))})}return"loading"===document.readyState?(a.domContentLoadedHandler=s,document.addEventListener("DOMContentLoaded",a.domContentLoadedHandler)):s(),{result:"range initialized",destroy:()=>{a.domContentLoadedHandler&&(document.removeEventListener("DOMContentLoaded",a.domContentLoadedHandler),a.domContentLoadedHandler=null),a.handlers.forEach(({element:e,event:t,handler:n})=>{e.removeEventListener(t,n)}),a.handlers.length=0;n(o,"wrapper").forEach(e=>{delete e.dataset.hsFormRangeInit})}}}const c=[{name:"Alabama",value:"AL"},{name:"Alaska",value:"AK"},{name:"Arizona",value:"AZ"},{name:"Arkansas",value:"AR"},{name:"California",value:"CA"},{name:"Colorado",value:"CO"},{name:"Connecticut",value:"CT"},{name:"Delaware",value:"DE"},{name:"Florida",value:"FL"},{name:"Georgia",value:"GA"},{name:"Hawaii",value:"HI"},{name:"Idaho",value:"ID"},{name:"Illinois",value:"IL"},{name:"Indiana",value:"IN"},{name:"Iowa",value:"IA"},{name:"Kansas",value:"KS"},{name:"Kentucky",value:"KY"},{name:"Louisiana",value:"LA"},{name:"Maine",value:"ME"},{name:"Maryland",value:"MD"},{name:"Massachusetts",value:"MA"},{name:"Michigan",value:"MI"},{name:"Minnesota",value:"MN"},{name:"Mississippi",value:"MS"},{name:"Missouri",value:"MO"},{name:"Montana",value:"MT"},{name:"Nebraska",value:"NE"},{name:"Nevada",value:"NV"},{name:"New Hampshire",value:"NH"},{name:"New Jersey",value:"NJ"},{name:"New Mexico",value:"NM"},{name:"New York",value:"NY"},{name:"North Carolina",value:"NC"},{name:"North Dakota",value:"ND"},{name:"Ohio",value:"OH"},{name:"Oklahoma",value:"OK"},{name:"Oregon",value:"OR"},{name:"Pennsylvania",value:"PA"},{name:"Rhode Island",value:"RI"},{name:"South Carolina",value:"SC"},{name:"South Dakota",value:"SD"},{name:"Tennessee",value:"TN"},{name:"Texas",value:"TX"},{name:"Utah",value:"UT"},{name:"Vermont",value:"VT"},{name:"Virginia",value:"VA"},{name:"Washington",value:"WA"},{name:"West Virginia",value:"WV"},{name:"Wisconsin",value:"WI"},{name:"Wyoming",value:"WY"}];function u(e){const o={observers:[],handlers:[],timeouts:[],domContentLoadedHandler:null},l=e=>o.observers.push(e),c=(e,t,n,a)=>{e.addEventListener(t,n,a),o.handlers.push({element:e,event:t,handler:n,options:a})},u=e=>o.timeouts.push(e);function d(){document.querySelectorAll("select > div").forEach(e=>{const t=e.parentElement;for(;e.firstChild;)t.appendChild(e.firstChild);e.remove()});n(e,"wrapper").forEach(n=>{!function(n,l,c,u){const d=n.querySelector("select");if(!d)return void console.warn("[select] Missing <select> element in custom select wrapper",n);d.setAttribute("aria-hidden","true"),d.setAttribute("tabindex","-1");const m=d.getAttribute("name")||"custom-select",v=t(e,"list",n),p=t(e,"button",n);if(!v||!p)return void console.warn("[select] Missing required elements (list or button) in custom select wrapper",n);function f(){d.disabled?(p.disabled=!0,p.setAttribute("aria-disabled","true")):(p.disabled=!1,p.removeAttribute("aria-disabled"))}f();const h=v.firstElementChild;if(!h)return void console.warn("[select] Missing option template in custom select list",n);const y=h.cloneNode(!0);h.remove();d.querySelectorAll("option").forEach((e,t)=>{const n=y.cloneNode(!0),o=n.querySelector("span");if(o&&(o.textContent=e.textContent),n.setAttribute("data-value",e.value),n.setAttribute("role","option"),n.setAttribute("id",`${m}-option-${t}`),n.setAttribute("tabindex","-1"),e.selected){n.setAttribute("aria-selected","true");const t=p.querySelector("span")||p;"SPAN"===t.tagName&&(t.textContent=e.textContent),e.value?p.classList.add("is-filled"):p.classList.remove("is-filled")}else n.setAttribute("aria-selected","false");v.appendChild(n)}),v.setAttribute("role","listbox"),v.setAttribute("id",`${m}-listbox`),v.setAttribute("tabindex","-1"),v.setAttribute("aria-hidden","true"),v.inert=!0,p.setAttribute("role","combobox"),p.setAttribute("aria-haspopup","listbox"),p.setAttribute("aria-controls",`${m}-listbox`),p.setAttribute("aria-expanded","false"),p.setAttribute("id",`${m}-button`);const b=n.querySelector("label")||document.querySelector(`label[for="${d.id}"]`);if(b){const e=b.id||`${m}-label`;b.id=e,d.id||(d.id=`${m}-select`),b.setAttribute("for",d.id),p.setAttribute("aria-labelledby",e)}const g=n.querySelector('[data-hs-height="element"]'),A=g||null;let L="",C=null;function E(){return n.classList.contains("is-active")}function S(){const e=E(),t="true"===p.getAttribute("aria-expanded");if(t&&!e&&v.contains(document.activeElement)&&p.focus(),p.setAttribute("aria-expanded",e?"true":"false"),v.setAttribute("aria-hidden",e?"false":"true"),v.inert=!e,e){v.querySelectorAll('[role="option"]').forEach(e=>{e.setAttribute("tabindex","0")}),t||r()}else{p.removeAttribute("aria-activedescendant");v.querySelectorAll('[role="option"]').forEach(e=>{e.setAttribute("tabindex","-1")}),t&&s()}A&&i(A,e,{duration:300,ease:"power2.inOut"})}A&&a(A,E());function w(e){const t=v.querySelectorAll('[role="option"]');e<0||e>=t.length||(t.forEach(e=>{e.classList.remove("focused"),e.setAttribute("tabindex","-1")}),t[e].classList.add("focused"),t[e].setAttribute("tabindex","0"),t[e].focus(),p.setAttribute("aria-activedescendant",t[e].id))}function x(e){if(1!==e.length)return!1;if(null!==C){clearTimeout(C);const e=o.timeouts.indexOf(C);e>-1&&o.timeouts.splice(e,1)}const t=Array.from(v.querySelectorAll('[role="option"]'));if(0===t.length)return!1;L+=e.toLowerCase();const a=t.findIndex(e=>e.classList.contains("focused"));if(1===L.length||L.split("").every(e=>e===L[0])){const e=L[0];let o=a+1;for(let a=0;a<t.length;a++){const r=(o+a)%t.length;if((t[r].querySelector("span")?.textContent||t[r].textContent).toLowerCase().startsWith(e))return w(r),E()||n.classList.add("is-active"),C=setTimeout(q,500),u(C),!0}}else{const e=t.findIndex(e=>(e.querySelector("span")?.textContent||e.textContent).toLowerCase().startsWith(L));if(-1!==e)return w(e),E()||n.classList.add("is-active"),C=setTimeout(q,500),u(C),!0}return C=setTimeout(q,500),u(C),!1}function q(){L="",C=null}function k(e){const t=e.getAttribute("data-value")||"",o=e.querySelector("span")?.textContent||e.textContent;d.value=t,d.dispatchEvent(new Event("change",{bubbles:!0}));const a=p.querySelector("span")||p;"SPAN"===a.tagName&&(a.textContent=o),t?p.classList.add("is-filled"):p.classList.remove("is-filled"),v.querySelectorAll('[role="option"]').forEach(e=>{e.setAttribute("aria-selected","false")}),e.setAttribute("aria-selected","true"),n.classList.remove("is-active")}S();const D=e=>{e.preventDefault(),n.classList.toggle("is-active")};l(p,"click",D);const N=e=>{switch(e.key){case"Enter":e.preventDefault();const t=p.closest("form");if(t){const e=t.querySelector('button[type="submit"], input[type="submit"]')||t.querySelector("button:not([type])");e&&e.click()}break;case" ":e.preventDefault(),n.classList.toggle("is-active");break;case"ArrowDown":e.preventDefault(),E()?w(0):(n.classList.add("is-active"),requestAnimationFrame(()=>{w(0)}));break;case"ArrowUp":if(e.preventDefault(),E()){w(v.querySelectorAll('[role="option"]').length-1)}else n.classList.add("is-active"),requestAnimationFrame(()=>{w(0)});break;case"Escape":E()&&(e.preventDefault(),n.classList.remove("is-active"));break;case"Home":e.preventDefault(),E()||n.classList.add("is-active"),w(0);break;case"End":e.preventDefault(),E()||n.classList.add("is-active");w(v.querySelectorAll('[role="option"]').length-1);break;default:x(e.key)&&e.preventDefault()}};l(p,"keydown",N);const M=e=>{const t=e.target.closest('[role="option"]');if(!t)return;const o=Array.from(v.querySelectorAll('[role="option"]')),a=o.indexOf(t);switch(e.key){case"ArrowDown":e.preventDefault(),a<o.length-1&&w(a+1);break;case"ArrowUp":e.preventDefault(),a>0&&w(a-1);break;case"Enter":e.preventDefault(),k(t);break;case"Escape":e.preventDefault(),n.classList.remove("is-active"),p.focus();break;case"Home":e.preventDefault(),w(0);break;case"End":e.preventDefault(),w(o.length-1);break;default:x(e.key)&&e.preventDefault()}};l(v,"keydown",M);l(v,"click",e=>{const t=e.target.closest('[role="option"]');t&&k(t)});const F=e=>{e.relatedTarget&&n.contains(e.relatedTarget)||!n.classList.contains("is-active")||n.classList.remove("is-active")};l(v,"focusout",F);const H=e=>{n.classList.contains("is-active")&&!n.contains(e.target)&&n.classList.remove("is-active")};l(document,"click",H);const T=new MutationObserver(()=>{S()});T.observe(n,{attributes:!0,attributeFilter:["class"]}),c(T);const I=new MutationObserver(()=>{f()});I.observe(d,{attributes:!0,attributeFilter:["disabled"]}),c(I);const O=()=>{const e=d.options[d.selectedIndex];if(e){const t=v.querySelectorAll('[role="option"]'),n=Array.from(t).find(t=>t.getAttribute("data-value")===e.value);if(n){const o=n.querySelector("span")?.textContent||n.textContent,a=p.querySelector("span")||p;"SPAN"===a.tagName&&(a.textContent=o),e.value?p.classList.add("is-filled"):p.classList.remove("is-filled"),t.forEach(e=>{e.setAttribute("aria-selected","false")}),n.setAttribute("aria-selected","true")}}};l(d,"change",O),l(d,"input",O);const $=d.closest("form");if($){l($,"reset",()=>{setTimeout(()=>{O()},0)})}}(n,c,l,u)})}return"loading"===document.readyState?(o.domContentLoadedHandler=d,document.addEventListener("DOMContentLoaded",o.domContentLoadedHandler)):d(),window.initCustomSelects=d,{result:"select initialized",destroy:()=>{o.domContentLoadedHandler&&(document.removeEventListener("DOMContentLoaded",o.domContentLoadedHandler),o.domContentLoadedHandler=null),o.observers.forEach(e=>e.disconnect()),o.observers.length=0,o.timeouts.forEach(e=>clearTimeout(e)),o.timeouts.length=0,o.handlers.forEach(({element:e,event:t,handler:n,options:o})=>{e.removeEventListener(t,n,o)}),o.handlers.length=0,window.initCustomSelects&&delete window.initCustomSelects}}}async function d(e){const t={destroyFunctions:[]};try{const o=function(e){const t=n(e,"states");return t.forEach(e=>{const t=e;if("SELECT"!==t.tagName)return void console.warn('[select-states] data-hs-form-select="states" must be on a <select> element',t);const n=t.querySelectorAll("option");if(1!==n.length)return void console.warn("[select-states] Select must have exactly 1 default template option (placeholder). Found:",n.length,t);const o=n[0];if(""!==o.value)return void console.warn("[select-states] Template option must have empty value for placeholder. Found value:",o.value,t);const a=o.textContent;t.innerHTML="";const r=document.createElement("option");r.value="",r.textContent=a,t.appendChild(r),c.forEach(e=>{const n=document.createElement("option");n.value=e.value,n.textContent=e.name,t.appendChild(n)})}),{result:`states initialized on ${t.length} select${1!==t.length?"s":""}`,destroy:()=>{}}}(e.states);o?.destroy&&t.destroyFunctions.push(o.destroy);const a=u(e["custom-select"]);return a?.destroy&&t.destroyFunctions.push(a.destroy),{result:"select initialized",destroy:()=>{t.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[select] Error during cleanup:",t)}}),t.destroyFunctions.length=0}}}catch(o){throw console.error("[select] Initialization failed:",o),t.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[select] Error during error cleanup:",t)}}),o}}async function m(){const a=e.structure.form,r={destroyFunctions:[]},s=o(a.honeypot,"form-handler");if(document.querySelector(s))try{const e=function(e){const n={honeypotHandler:null},o=n=>{const o=n.target;if("FORM"!==o.tagName)return;const a=t(e,"form-handler",o);return a&&a.value?(n.preventDefault(),n.stopPropagation(),n.stopImmediatePropagation(),!1):void 0};return n.honeypotHandler=o,document.addEventListener("submit",o,!0),{result:"honeypot initialized",destroy:()=>{n.honeypotHandler&&(document.removeEventListener("submit",n.honeypotHandler,!0),n.honeypotHandler=null)}}}(a.honeypot);e?.destroy&&r.destroyFunctions.push(e.destroy)}catch(m){console.error("[form] Error initializing honeypot:",m)}const i=o(a.range,"wrapper");if(document.querySelector(i))try{const e=l(a.range);e?.destroy&&r.destroyFunctions.push(e.destroy)}catch(m){console.error("[form] Error initializing range:",m)}const c=o(a.test,"wrapper");if(document.querySelector(c))try{const e=function(e){const o={handlers:[]},a=(e,t,n,a)=>{e.addEventListener(t,n,a),o.handlers.push({element:e,event:t,handler:n,options:a})},r=n(e,"wrapper");return r.forEach(n=>{const o=n.querySelector("form");if(!o)return void console.warn('[form-test] No <form> element found within data-hs-form-test="wrapper"',n);const r=t(e,"info",n),s=()=>{const e=new FormData(o),t={};for(const[n,o]of e.entries())t[n]=o;if(r){const e=document.createElement("pre");e.textContent=JSON.stringify(t,null,2),r.innerHTML="",r.appendChild(document.createTextNode("Test mode active - Live form data:")),r.appendChild(e)}};r&&(r.textContent="Test mode active, preventing native submissions",s()),a(o,"input",s),a(o,"change",s);const i=o.querySelector('button[type="submit"], input[type="submit"]')||o.querySelector("button:not([type])");i&&a(i,"click",()=>{console.log("[form-test] Submit button clicked"),requestAnimationFrame(()=>{o.checkValidity()||console.log("[form-test] Browser blocked submission - validation failed")})}),a(o,"submit",e=>{e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),console.log("[form-test] Submission prevented - displaying test results");const t=new FormData(o),n={};for(const[o,r]of t.entries())n[o]=r;const a=`✅ Form would submit successfully at ${(new Date).toLocaleTimeString()}`;if(r){const e=document.createElement("pre");e.textContent=JSON.stringify(n,null,2),r.innerHTML="",r.appendChild(document.createTextNode(a)),r.appendChild(e)}else console.log(a),console.log("Form data:",n);return!1},!0)}),{result:`test initialized on ${r.length} form${1!==r.length?"s":""}`,destroy:()=>{o.handlers.forEach(({element:e,event:t,handler:n,options:o})=>{e.removeEventListener(t,n,o)}),o.handlers.length=0}}}(a.test);e?.destroy&&r.destroyFunctions.push(e.destroy)}catch(m){console.error("[form] Error initializing test:",m)}const u=o(a.select,"wrapper");if(document.querySelector(u))try{const e=await d(a.select);e?.destroy&&r.destroyFunctions.push(e.destroy)}catch(m){console.error("[form] Error initializing select:",m)}return{result:`form initialized (${r.destroyFunctions.length} modules active)`,destroy:()=>{r.destroyFunctions.forEach(e=>{try{e()}catch(m){console.error("[form] Error during cleanup:",m)}}),r.destroyFunctions.length=0}}}export{m as init};
2
+ //# sourceMappingURL=hs-form-COFGgawz.js.map
@@ -0,0 +1,2 @@
1
+ import{c as e}from"../main.js";import{a as t,q as n,g as o}from"./hs-attributeSelector-6pGcDBo-.js";import{s as a,o as r,c as s,a as i}from"./hs-modalManager-H_YegPAO.js";function l(o){const a={handlers:[],domContentLoadedHandler:null},r=(e,t,n)=>{e.addEventListener(t,n),a.handlers.push({element:e,event:t,handler:n})};function s(){n(o,"wrapper").forEach(n=>{const a=n;a.dataset.hsFormRangeInit||(a.dataset.hsFormRangeInit="true",function(n,a){const r=n.querySelector("input[type='range']");if(!r)return void console.warn('[range] Missing <input type="range"> element in wrapper',n);const s=t(o,"output",n),i=()=>{const t=r.min?+r.min:0,a=r.max?+r.max:100,i=+r.value||t,l=(i-t)/(a-t);n.style.setProperty(`${e._global.cssVars.prefix}${o.cssVars?.progress||"progress"}`,String(l)),s&&(s.textContent=String(i))};a(r,"input",i),i()}(a,r))})}return"loading"===document.readyState?(a.domContentLoadedHandler=s,document.addEventListener("DOMContentLoaded",a.domContentLoadedHandler)):s(),{result:"range initialized",destroy:()=>{a.domContentLoadedHandler&&(document.removeEventListener("DOMContentLoaded",a.domContentLoadedHandler),a.domContentLoadedHandler=null),a.handlers.forEach(({element:e,event:t,handler:n})=>{e.removeEventListener(t,n)}),a.handlers.length=0;n(o,"wrapper").forEach(e=>{delete e.dataset.hsFormRangeInit})}}}const c=[{name:"Alabama",value:"AL"},{name:"Alaska",value:"AK"},{name:"Arizona",value:"AZ"},{name:"Arkansas",value:"AR"},{name:"California",value:"CA"},{name:"Colorado",value:"CO"},{name:"Connecticut",value:"CT"},{name:"Delaware",value:"DE"},{name:"Florida",value:"FL"},{name:"Georgia",value:"GA"},{name:"Hawaii",value:"HI"},{name:"Idaho",value:"ID"},{name:"Illinois",value:"IL"},{name:"Indiana",value:"IN"},{name:"Iowa",value:"IA"},{name:"Kansas",value:"KS"},{name:"Kentucky",value:"KY"},{name:"Louisiana",value:"LA"},{name:"Maine",value:"ME"},{name:"Maryland",value:"MD"},{name:"Massachusetts",value:"MA"},{name:"Michigan",value:"MI"},{name:"Minnesota",value:"MN"},{name:"Mississippi",value:"MS"},{name:"Missouri",value:"MO"},{name:"Montana",value:"MT"},{name:"Nebraska",value:"NE"},{name:"Nevada",value:"NV"},{name:"New Hampshire",value:"NH"},{name:"New Jersey",value:"NJ"},{name:"New Mexico",value:"NM"},{name:"New York",value:"NY"},{name:"North Carolina",value:"NC"},{name:"North Dakota",value:"ND"},{name:"Ohio",value:"OH"},{name:"Oklahoma",value:"OK"},{name:"Oregon",value:"OR"},{name:"Pennsylvania",value:"PA"},{name:"Rhode Island",value:"RI"},{name:"South Carolina",value:"SC"},{name:"South Dakota",value:"SD"},{name:"Tennessee",value:"TN"},{name:"Texas",value:"TX"},{name:"Utah",value:"UT"},{name:"Vermont",value:"VT"},{name:"Virginia",value:"VA"},{name:"Washington",value:"WA"},{name:"West Virginia",value:"WV"},{name:"Wisconsin",value:"WI"},{name:"Wyoming",value:"WY"}];function u(e){const o={observers:[],handlers:[],timeouts:[],domContentLoadedHandler:null},l=e=>o.observers.push(e),c=(e,t,n,a)=>{e.addEventListener(t,n,a),o.handlers.push({element:e,event:t,handler:n,options:a})},u=e=>o.timeouts.push(e);function d(){document.querySelectorAll("select > div").forEach(e=>{const t=e.parentElement;for(;e.firstChild;)t.appendChild(e.firstChild);e.remove()});n(e,"wrapper").forEach(n=>{!function(n,l,c,u){const d=n.querySelector("select");if(!d)return void console.warn("[select] Missing <select> element in custom select wrapper",n);d.setAttribute("aria-hidden","true"),d.setAttribute("tabindex","-1");const m=d.getAttribute("name")||"custom-select",v=t(e,"list",n),p=t(e,"button",n);if(!v||!p)return void console.warn("[select] Missing required elements (list or button) in custom select wrapper",n);function f(){d.disabled?(p.disabled=!0,p.setAttribute("aria-disabled","true")):(p.disabled=!1,p.removeAttribute("aria-disabled"))}f();const h=v.firstElementChild;if(!h)return void console.warn("[select] Missing option template in custom select list",n);const y=h.cloneNode(!0);h.remove();d.querySelectorAll("option").forEach((e,t)=>{const n=y.cloneNode(!0),o=n.querySelector("span");if(o&&(o.textContent=e.textContent),n.setAttribute("data-value",e.value),n.setAttribute("role","option"),n.setAttribute("id",`${m}-option-${t}`),n.setAttribute("tabindex","-1"),e.selected){n.setAttribute("aria-selected","true");const t=p.querySelector("span")||p;"SPAN"===t.tagName&&(t.textContent=e.textContent),e.value?p.classList.add("is-filled"):p.classList.remove("is-filled")}else n.setAttribute("aria-selected","false");v.appendChild(n)}),v.setAttribute("role","listbox"),v.setAttribute("id",`${m}-listbox`),v.setAttribute("tabindex","-1"),v.setAttribute("aria-hidden","true"),v.inert=!0,p.setAttribute("role","combobox"),p.setAttribute("aria-haspopup","listbox"),p.setAttribute("aria-controls",`${m}-listbox`),p.setAttribute("aria-expanded","false"),p.setAttribute("id",`${m}-button`);const b=n.querySelector("label")||document.querySelector(`label[for="${d.id}"]`);if(b){const e=b.id||`${m}-label`;b.id=e,d.id||(d.id=`${m}-select`),b.setAttribute("for",d.id),p.setAttribute("aria-labelledby",e)}const g=n.querySelector('[data-hs-height="element"]'),A=g||null;let L="",C=null;function E(){return n.classList.contains("is-active")}function S(){const e=E(),t="true"===p.getAttribute("aria-expanded");if(t&&!e&&v.contains(document.activeElement)&&p.focus(),p.setAttribute("aria-expanded",e?"true":"false"),v.setAttribute("aria-hidden",e?"false":"true"),v.inert=!e,e){v.querySelectorAll('[role="option"]').forEach(e=>{e.setAttribute("tabindex","0")}),t||r()}else{p.removeAttribute("aria-activedescendant");v.querySelectorAll('[role="option"]').forEach(e=>{e.setAttribute("tabindex","-1")}),t&&s()}A&&i(A,e,{duration:300,ease:"power2.inOut"})}A&&a(A,E());function w(e){const t=v.querySelectorAll('[role="option"]');e<0||e>=t.length||(t.forEach(e=>{e.classList.remove("focused"),e.setAttribute("tabindex","-1")}),t[e].classList.add("focused"),t[e].setAttribute("tabindex","0"),t[e].focus(),p.setAttribute("aria-activedescendant",t[e].id))}function x(e){if(1!==e.length)return!1;if(null!==C){clearTimeout(C);const e=o.timeouts.indexOf(C);e>-1&&o.timeouts.splice(e,1)}const t=Array.from(v.querySelectorAll('[role="option"]'));if(0===t.length)return!1;L+=e.toLowerCase();const a=t.findIndex(e=>e.classList.contains("focused"));if(1===L.length||L.split("").every(e=>e===L[0])){const e=L[0];let o=a+1;for(let a=0;a<t.length;a++){const r=(o+a)%t.length;if((t[r].querySelector("span")?.textContent||t[r].textContent).toLowerCase().startsWith(e))return w(r),E()||n.classList.add("is-active"),C=setTimeout(q,500),u(C),!0}}else{const e=t.findIndex(e=>(e.querySelector("span")?.textContent||e.textContent).toLowerCase().startsWith(L));if(-1!==e)return w(e),E()||n.classList.add("is-active"),C=setTimeout(q,500),u(C),!0}return C=setTimeout(q,500),u(C),!1}function q(){L="",C=null}function k(e){const t=e.getAttribute("data-value")||"",o=e.querySelector("span")?.textContent||e.textContent;d.value=t,d.dispatchEvent(new Event("change",{bubbles:!0}));const a=p.querySelector("span")||p;"SPAN"===a.tagName&&(a.textContent=o),t?p.classList.add("is-filled"):p.classList.remove("is-filled"),v.querySelectorAll('[role="option"]').forEach(e=>{e.setAttribute("aria-selected","false")}),e.setAttribute("aria-selected","true"),n.classList.remove("is-active")}S();const D=e=>{e.preventDefault(),n.classList.toggle("is-active")};l(p,"click",D);const N=e=>{switch(e.key){case"Enter":e.preventDefault();const t=p.closest("form");if(t){const e=t.querySelector('button[type="submit"], input[type="submit"]')||t.querySelector("button:not([type])");e&&e.click()}break;case" ":e.preventDefault(),n.classList.toggle("is-active");break;case"ArrowDown":e.preventDefault(),E()?w(0):(n.classList.add("is-active"),requestAnimationFrame(()=>{w(0)}));break;case"ArrowUp":if(e.preventDefault(),E()){w(v.querySelectorAll('[role="option"]').length-1)}else n.classList.add("is-active"),requestAnimationFrame(()=>{w(0)});break;case"Escape":E()&&(e.preventDefault(),n.classList.remove("is-active"));break;case"Home":e.preventDefault(),E()||n.classList.add("is-active"),w(0);break;case"End":e.preventDefault(),E()||n.classList.add("is-active");w(v.querySelectorAll('[role="option"]').length-1);break;default:x(e.key)&&e.preventDefault()}};l(p,"keydown",N);const M=e=>{const t=e.target.closest('[role="option"]');if(!t)return;const o=Array.from(v.querySelectorAll('[role="option"]')),a=o.indexOf(t);switch(e.key){case"ArrowDown":e.preventDefault(),a<o.length-1&&w(a+1);break;case"ArrowUp":e.preventDefault(),a>0&&w(a-1);break;case"Enter":e.preventDefault(),k(t);break;case"Escape":e.preventDefault(),n.classList.remove("is-active"),p.focus();break;case"Home":e.preventDefault(),w(0);break;case"End":e.preventDefault(),w(o.length-1);break;default:x(e.key)&&e.preventDefault()}};l(v,"keydown",M);l(v,"click",e=>{const t=e.target.closest('[role="option"]');t&&k(t)});const F=e=>{e.relatedTarget&&n.contains(e.relatedTarget)||!n.classList.contains("is-active")||n.classList.remove("is-active")};l(v,"focusout",F);const H=e=>{n.classList.contains("is-active")&&!n.contains(e.target)&&n.classList.remove("is-active")};l(document,"click",H);const T=new MutationObserver(()=>{S()});T.observe(n,{attributes:!0,attributeFilter:["class"]}),c(T);const I=new MutationObserver(()=>{f()});I.observe(d,{attributes:!0,attributeFilter:["disabled"]}),c(I);const O=()=>{const e=d.options[d.selectedIndex];if(e){const t=v.querySelectorAll('[role="option"]'),n=Array.from(t).find(t=>t.getAttribute("data-value")===e.value);if(n){const o=n.querySelector("span")?.textContent||n.textContent,a=p.querySelector("span")||p;"SPAN"===a.tagName&&(a.textContent=o),e.value?p.classList.add("is-filled"):p.classList.remove("is-filled"),t.forEach(e=>{e.setAttribute("aria-selected","false")}),n.setAttribute("aria-selected","true")}}};l(d,"change",O),l(d,"input",O);const $=d.closest("form");if($){l($,"reset",()=>{setTimeout(()=>{O()},0)})}}(n,c,l,u)})}return"loading"===document.readyState?(o.domContentLoadedHandler=d,document.addEventListener("DOMContentLoaded",o.domContentLoadedHandler)):d(),window.initCustomSelects=d,{result:"select initialized",destroy:()=>{o.domContentLoadedHandler&&(document.removeEventListener("DOMContentLoaded",o.domContentLoadedHandler),o.domContentLoadedHandler=null),o.observers.forEach(e=>e.disconnect()),o.observers.length=0,o.timeouts.forEach(e=>clearTimeout(e)),o.timeouts.length=0,o.handlers.forEach(({element:e,event:t,handler:n,options:o})=>{e.removeEventListener(t,n,o)}),o.handlers.length=0,window.initCustomSelects&&delete window.initCustomSelects}}}async function d(e){const t={destroyFunctions:[]};try{const o=function(e){const t=n(e,"states");return t.forEach(e=>{const t=e;if("SELECT"!==t.tagName)return void console.warn('[select-states] data-hs-form-select="states" must be on a <select> element',t);const n=t.querySelectorAll("option");if(1!==n.length)return void console.warn("[select-states] Select must have exactly 1 default template option (placeholder). Found:",n.length,t);const o=n[0];if(""!==o.value)return void console.warn("[select-states] Template option must have empty value for placeholder. Found value:",o.value,t);const a=o.textContent;t.innerHTML="";const r=document.createElement("option");r.value="",r.textContent=a,t.appendChild(r),c.forEach(e=>{const n=document.createElement("option");n.value=e.value,n.textContent=e.name,t.appendChild(n)})}),{result:`states initialized on ${t.length} select${1!==t.length?"s":""}`,destroy:()=>{}}}(e.states);o?.destroy&&t.destroyFunctions.push(o.destroy);const a=u(e["custom-select"]);return a?.destroy&&t.destroyFunctions.push(a.destroy),{result:"select initialized",destroy:()=>{t.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[select] Error during cleanup:",t)}}),t.destroyFunctions.length=0}}}catch(o){throw console.error("[select] Initialization failed:",o),t.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[select] Error during error cleanup:",t)}}),o}}async function m(){const a=e.structure.form,r={destroyFunctions:[]},s=o(a.honeypot,"form-handler");if(document.querySelector(s))try{const e=function(e){const n={honeypotHandler:null},o=n=>{const o=n.target;if("FORM"!==o.tagName)return;const a=t(e,"form-handler",o);return a&&a.value?(n.preventDefault(),n.stopPropagation(),n.stopImmediatePropagation(),!1):void 0};return n.honeypotHandler=o,document.addEventListener("submit",o,!0),{result:"honeypot initialized",destroy:()=>{n.honeypotHandler&&(document.removeEventListener("submit",n.honeypotHandler,!0),n.honeypotHandler=null)}}}(a.honeypot);e?.destroy&&r.destroyFunctions.push(e.destroy)}catch(m){console.error("[form] Error initializing honeypot:",m)}const i=o(a.range,"wrapper");if(document.querySelector(i))try{const e=l(a.range);e?.destroy&&r.destroyFunctions.push(e.destroy)}catch(m){console.error("[form] Error initializing range:",m)}const c=o(a.test,"wrapper");if(document.querySelector(c))try{const e=function(e){const o={handlers:[]},a=(e,t,n,a)=>{e.addEventListener(t,n,a),o.handlers.push({element:e,event:t,handler:n,options:a})},r=n(e,"wrapper");return r.forEach(n=>{const o=n.querySelector("form");if(!o)return void console.warn('[form-test] No <form> element found within data-hs-form-test="wrapper"',n);const r=t(e,"info",n),s=()=>{const e=new FormData(o),t={};for(const[n,o]of e.entries())t[n]=o;if(r){const e=document.createElement("pre");e.textContent=JSON.stringify(t,null,2),r.innerHTML="",r.appendChild(document.createTextNode("Test mode active - Live form data:")),r.appendChild(e)}};r&&(r.textContent="Test mode active, preventing native submissions",s()),a(o,"input",s),a(o,"change",s);const i=o.querySelector('button[type="submit"], input[type="submit"]')||o.querySelector("button:not([type])");i&&a(i,"click",()=>{console.log("[form-test] Submit button clicked"),requestAnimationFrame(()=>{o.checkValidity()||console.log("[form-test] Browser blocked submission - validation failed")})}),a(o,"submit",e=>{e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),console.log("[form-test] Submission prevented - displaying test results");const t=new FormData(o),n={};for(const[o,r]of t.entries())n[o]=r;const a=`✅ Form would submit successfully at ${(new Date).toLocaleTimeString()}`;if(r){const e=document.createElement("pre");e.textContent=JSON.stringify(n,null,2),r.innerHTML="",r.appendChild(document.createTextNode(a)),r.appendChild(e)}else console.log(a),console.log("Form data:",n);return!1},!0)}),{result:`test initialized on ${r.length} form${1!==r.length?"s":""}`,destroy:()=>{o.handlers.forEach(({element:e,event:t,handler:n,options:o})=>{e.removeEventListener(t,n,o)}),o.handlers.length=0}}}(a.test);e?.destroy&&r.destroyFunctions.push(e.destroy)}catch(m){console.error("[form] Error initializing test:",m)}const u=o(a.select,"wrapper");if(document.querySelector(u))try{const e=await d(a.select);e?.destroy&&r.destroyFunctions.push(e.destroy)}catch(m){console.error("[form] Error initializing select:",m)}return{result:`form initialized (${r.destroyFunctions.length} modules active)`,destroy:()=>{r.destroyFunctions.forEach(e=>{try{e()}catch(m){console.error("[form] Error during cleanup:",m)}}),r.destroyFunctions.length=0}}}export{m as init};
2
+ //# sourceMappingURL=hs-form-COFGgawz.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hs-form-COFGgawz.js","sources":["../../src/modules/structure/functions/form/functions/range.ts","../../src/modules/structure/functions/form/functions/select/functions/states.ts","../../src/modules/structure/functions/form/functions/select/functions/custom-select.ts","../../src/modules/structure/functions/form/functions/select/select.ts","../../src/modules/structure/functions/form/form.ts","../../src/modules/structure/functions/form/functions/honeypot.ts","../../src/modules/structure/functions/form/functions/test.ts"],"sourcesContent":["/**\n * Range Slider Component\n *\n * Custom range slider that syncs with native <input type=\"range\"> for proper form submission.\n * Automatically updates output display and sets CSS custom property for progress styling.\n *\n * Features:\n * - Calculates normalized progress (0-1) from min/max values\n * - Sets CSS custom property (--_hs---progress) on wrapper\n * - Updates optional output element with current value\n * - Prevents duplicate initialization with dataset flag\n * - Works with negative min values and custom step sizes\n *\n * HTML Structure:\n * <div data-hs-form-range=\"wrapper\">\n * <input type=\"range\" min=\"0\" max=\"100\" value=\"50\">\n * <span data-hs-form-range=\"output\">50</span>\n * </div>\n *\n * CSS Usage:\n * .range-fill { width: calc(var(--_hs---progress) * 100%); }\n */\n\nimport { querySelectorAll, querySelector } from '@utils';\nimport globalConfig from '@config';\n\ninterface ModuleConfig {\n attributes: {\n elements: Record<string, { primary: string; aliases?: string[] }>;\n };\n cssVars?: {\n progress?: string;\n };\n}\n\nexport function init(config: ModuleConfig) {\n // Centralized cleanup tracking\n const cleanup = {\n handlers: [],\n domContentLoadedHandler: null,\n };\n\n const addHandler = (element: Element, event: string, handler: EventListener) => {\n element.addEventListener(event, handler);\n cleanup.handlers.push({ element, event, handler });\n };\n\n // Helper: Get CSS var name with global prefix\n function getProgressVarName(): string {\n const prefix = globalConfig._global.cssVars.prefix;\n const varName = config.cssVars?.progress || 'progress';\n return `${prefix}${varName}`;\n }\n\n // Initialize all range components\n function initRangeComponents() {\n const rangeWrappers = querySelectorAll(config, 'wrapper');\n\n rangeWrappers.forEach((wrapper) => {\n const htmlWrapper = wrapper as HTMLElement;\n // Prevent duplicate initialization\n if (htmlWrapper.dataset.hsFormRangeInit) return;\n htmlWrapper.dataset.hsFormRangeInit = 'true';\n\n initSingleRange(htmlWrapper, addHandler);\n });\n }\n\n // Initialize a single range component\n function initSingleRange(\n wrapper: HTMLElement,\n addHandler: (element: Element, event: string, handler: EventListener) => void\n ) {\n const input = wrapper.querySelector(\"input[type='range']\") as HTMLInputElement;\n if (!input) {\n console.warn('[range] Missing <input type=\"range\"> element in wrapper', wrapper);\n return;\n }\n\n const output = querySelector(config, 'output', wrapper);\n\n // Update function\n const update = () => {\n const min = input.min ? +input.min : 0;\n const max = input.max ? +input.max : 100;\n const val = +input.value || min;\n const progress = (val - min) / (max - min);\n\n // Set CSS custom property using global config\n wrapper.style.setProperty(getProgressVarName(), String(progress));\n\n // Update output text if exists\n if (output) {\n output.textContent = String(val);\n }\n };\n\n // Add input event listener\n addHandler(input, 'input', update);\n\n // Initialize on load\n update();\n }\n\n // Initialize on DOM ready\n if (document.readyState === 'loading') {\n cleanup.domContentLoadedHandler = initRangeComponents;\n document.addEventListener('DOMContentLoaded', cleanup.domContentLoadedHandler);\n } else {\n initRangeComponents();\n }\n\n return {\n result: 'range initialized',\n destroy: () => {\n // Remove DOMContentLoaded listener\n if (cleanup.domContentLoadedHandler) {\n document.removeEventListener('DOMContentLoaded', cleanup.domContentLoadedHandler);\n cleanup.domContentLoadedHandler = null;\n }\n\n // Remove all event listeners\n cleanup.handlers.forEach(({ element, event, handler }) => {\n element.removeEventListener(event, handler);\n });\n cleanup.handlers.length = 0;\n\n // Remove init flags\n const rangeWrappers = querySelectorAll(config, 'wrapper');\n rangeWrappers.forEach((wrapper) => {\n delete (wrapper as HTMLElement).dataset.hsFormRangeInit;\n });\n },\n };\n}\n","/**\n * US States Select Populator\n *\n * Automatically populates a <select> element with all 50 US states.\n * Maintains the existing placeholder option and adds state options dynamically.\n *\n * Features:\n * - Auto-populates all 50 US states (full names + abbreviations)\n * - Preserves placeholder option (must have empty value)\n * - Validates select has exactly 1 template option\n * - State values use standard 2-letter abbreviations (CA, NY, TX, etc.)\n * - Works with both native and custom select components\n *\n * HTML Structure:\n * <select data-hs-form-select=\"states\">\n * <option value=\"\">Select a state</option>\n * </select>\n *\n * Result:\n * <select data-hs-form-select=\"states\">\n * <option value=\"\">Select a state</option>\n * <option value=\"AL\">Alabama</option>\n * <option value=\"AK\">Alaska</option>\n * ...all 50 states...\n * </select>\n *\n * Validation:\n * - Must be applied to <select> element\n * - Must have exactly 1 existing option (placeholder)\n * - Placeholder must have empty value=\"\"\n */\n\nimport { querySelectorAll } from '@utils';\n\nconst US_STATES = [\n { name: 'Alabama', value: 'AL' },\n { name: 'Alaska', value: 'AK' },\n { name: 'Arizona', value: 'AZ' },\n { name: 'Arkansas', value: 'AR' },\n { name: 'California', value: 'CA' },\n { name: 'Colorado', value: 'CO' },\n { name: 'Connecticut', value: 'CT' },\n { name: 'Delaware', value: 'DE' },\n { name: 'Florida', value: 'FL' },\n { name: 'Georgia', value: 'GA' },\n { name: 'Hawaii', value: 'HI' },\n { name: 'Idaho', value: 'ID' },\n { name: 'Illinois', value: 'IL' },\n { name: 'Indiana', value: 'IN' },\n { name: 'Iowa', value: 'IA' },\n { name: 'Kansas', value: 'KS' },\n { name: 'Kentucky', value: 'KY' },\n { name: 'Louisiana', value: 'LA' },\n { name: 'Maine', value: 'ME' },\n { name: 'Maryland', value: 'MD' },\n { name: 'Massachusetts', value: 'MA' },\n { name: 'Michigan', value: 'MI' },\n { name: 'Minnesota', value: 'MN' },\n { name: 'Mississippi', value: 'MS' },\n { name: 'Missouri', value: 'MO' },\n { name: 'Montana', value: 'MT' },\n { name: 'Nebraska', value: 'NE' },\n { name: 'Nevada', value: 'NV' },\n { name: 'New Hampshire', value: 'NH' },\n { name: 'New Jersey', value: 'NJ' },\n { name: 'New Mexico', value: 'NM' },\n { name: 'New York', value: 'NY' },\n { name: 'North Carolina', value: 'NC' },\n { name: 'North Dakota', value: 'ND' },\n { name: 'Ohio', value: 'OH' },\n { name: 'Oklahoma', value: 'OK' },\n { name: 'Oregon', value: 'OR' },\n { name: 'Pennsylvania', value: 'PA' },\n { name: 'Rhode Island', value: 'RI' },\n { name: 'South Carolina', value: 'SC' },\n { name: 'South Dakota', value: 'SD' },\n { name: 'Tennessee', value: 'TN' },\n { name: 'Texas', value: 'TX' },\n { name: 'Utah', value: 'UT' },\n { name: 'Vermont', value: 'VT' },\n { name: 'Virginia', value: 'VA' },\n { name: 'Washington', value: 'WA' },\n { name: 'West Virginia', value: 'WV' },\n { name: 'Wisconsin', value: 'WI' },\n { name: 'Wyoming', value: 'WY' },\n];\n\nexport function init(config) {\n // Find all select elements with data-hs-form-select=\"states\"\n const stateSelects = querySelectorAll(config, 'states');\n\n stateSelects.forEach((selectElement) => {\n const select = selectElement as HTMLSelectElement;\n if (select.tagName !== 'SELECT') {\n console.warn(\n '[select-states] data-hs-form-select=\"states\" must be on a <select> element',\n select\n );\n return;\n }\n\n const existingOptions = select.querySelectorAll('option') as NodeListOf<HTMLOptionElement>;\n\n // Validate: Must have exactly 1 option (placeholder template)\n if (existingOptions.length !== 1) {\n console.warn(\n '[select-states] Select must have exactly 1 default template option (placeholder). Found:',\n existingOptions.length,\n select\n );\n return;\n }\n\n const templateOption = existingOptions[0];\n\n // Validate: Template option must have empty value\n if (templateOption.value !== '') {\n console.warn(\n '[select-states] Template option must have empty value for placeholder. Found value:',\n templateOption.value,\n select\n );\n return;\n }\n\n // Store placeholder text and clear select\n const placeholderText = templateOption.textContent;\n select.innerHTML = '';\n\n // Re-create placeholder as first option\n const placeholder = document.createElement('option');\n placeholder.value = '';\n placeholder.textContent = placeholderText;\n select.appendChild(placeholder);\n\n // Add all 50 states after placeholder\n US_STATES.forEach((state) => {\n const option = document.createElement('option');\n option.value = state.value;\n option.textContent = state.name;\n select.appendChild(option);\n });\n });\n\n return {\n result: `states initialized on ${stateSelects.length} select${stateSelects.length !== 1 ? 's' : ''}`,\n destroy: () => {\n // No cleanup needed - states are just populated into native select\n },\n };\n}\n","/**\n * Custom Select Component\n *\n * Transforms native <select> elements into fully accessible custom dropdowns.\n * Maintains sync with native select for proper form submission and accessibility.\n *\n * Features:\n * - Full keyboard navigation (Arrow keys, Home/End, Enter, Space, Escape)\n * - Typeahead search (type letters to jump to options)\n * - ARIA-compliant with screen reader support\n * - Syncs with native select value changes and form resets\n * - Disabled state support with mutation observer\n * - Optional height animation with GSAP\n * - Modal scroll prevention when open\n * - Click outside to close\n * - Auto-unwraps Webflow component slot divs\n *\n * HTML Structure:\n * <div data-hs-form-select=\"wrapper\">\n * <label>Choose option</label>\n * <select name=\"example\">\n * <option value=\"\">Select...</option>\n * <option value=\"1\">Option 1</option>\n * </select>\n * <button data-hs-form-select=\"button\">\n * <span>Placeholder text</span>\n * </button>\n * <div data-hs-height=\"element\">\n * <div data-hs-form-select=\"list\">\n * <div role=\"option\"><span>Template</span></div>\n * </div>\n * </div>\n * </div>\n *\n * Keyboard Controls:\n * - Space/Enter (button): Open dropdown\n * - Arrow Up/Down: Navigate options\n * - Home/End: Jump to first/last option\n * - Escape: Close dropdown\n * - Type letters: Typeahead search\n *\n * Accessibility:\n * - Native select hidden but kept for form submission\n * - Custom UI uses role=\"combobox\" and role=\"listbox\"\n * - aria-expanded, aria-selected, aria-activedescendant\n * - Label properly connected to native select\n */\n\nimport {\n querySelectorAll,\n querySelector,\n animateHeight,\n setHeight,\n openModal,\n closeModal,\n} from '@utils';\n\nexport function init(config) {\n // Centralized cleanup tracking\n const cleanup = {\n observers: [] as MutationObserver[],\n handlers: [] as Array<{\n element: Element | Document;\n event: string;\n handler: EventListener;\n options?: boolean | AddEventListenerOptions;\n }>,\n timeouts: [] as number[],\n domContentLoadedHandler: null as (() => void) | null,\n };\n\n const addObserver = (observer: MutationObserver) => cleanup.observers.push(observer);\n const addHandler = (\n element: Element | Document,\n event: string,\n handler: EventListener,\n options?: boolean | AddEventListenerOptions\n ) => {\n element.addEventListener(event, handler, options);\n cleanup.handlers.push({ element, event, handler, options });\n };\n const addTimeout = (timeoutId: number) => cleanup.timeouts.push(timeoutId);\n\n // Initialize all custom selects on the page\n function initCustomSelects() {\n // Unwrap any divs inside select elements (Webflow component slots)\n document.querySelectorAll('select > div').forEach((div) => {\n const select = div.parentElement;\n while (div.firstChild) {\n select.appendChild(div.firstChild);\n }\n div.remove();\n });\n\n const selectWrappers = querySelectorAll(config, 'wrapper');\n\n selectWrappers.forEach((wrapper) => {\n initSingleSelect(wrapper, addHandler, addObserver, addTimeout);\n });\n }\n\n // Initialize a single custom select\n function initSingleSelect(\n wrapper: Element,\n addHandler: (\n element: Element | Document,\n event: string,\n handler: EventListener,\n options?: boolean | AddEventListenerOptions\n ) => void,\n addObserver: (observer: MutationObserver) => void,\n addTimeout: (timeoutId: number) => void\n ) {\n // Find all required elements\n const realSelect = wrapper.querySelector('select') as HTMLSelectElement;\n if (!realSelect) {\n console.warn('[select] Missing <select> element in custom select wrapper', wrapper);\n return;\n }\n\n // Hide real select from screen readers since custom UI provides accessible alternative\n realSelect.setAttribute('aria-hidden', 'true');\n realSelect.setAttribute('tabindex', '-1');\n\n const selectName = realSelect.getAttribute('name') || 'custom-select';\n const customList = querySelector(config, 'list', wrapper) as HTMLElement;\n const button = querySelector(config, 'button', wrapper) as HTMLButtonElement;\n\n if (!customList || !button) {\n console.warn(\n '[select] Missing required elements (list or button) in custom select wrapper',\n wrapper\n );\n return;\n }\n\n // Sync disabled state from native select\n function updateDisabledState() {\n if (realSelect.disabled) {\n button.disabled = true;\n button.setAttribute('aria-disabled', 'true');\n } else {\n button.disabled = false;\n button.removeAttribute('aria-disabled');\n }\n }\n updateDisabledState();\n\n // Get and clone the option template\n const optionTemplate = customList.firstElementChild;\n if (!optionTemplate) {\n console.warn('[select] Missing option template in custom select list', wrapper);\n return;\n }\n\n const templateClone = optionTemplate.cloneNode(true);\n optionTemplate.remove();\n\n // Build options from real select\n const realOptions = realSelect.querySelectorAll('option');\n realOptions.forEach((option: HTMLOptionElement, index: number) => {\n const optionElement = templateClone.cloneNode(true) as HTMLElement;\n const textSpan = optionElement.querySelector('span');\n\n if (textSpan) {\n textSpan.textContent = option.textContent;\n }\n\n // Add attributes\n optionElement.setAttribute('data-value', option.value);\n optionElement.setAttribute('role', 'option');\n optionElement.setAttribute('id', `${selectName}-option-${index}`);\n optionElement.setAttribute('tabindex', '-1');\n\n // Set selected state if this option is selected\n if (option.selected) {\n optionElement.setAttribute('aria-selected', 'true');\n // Update button text\n const buttonText = button.querySelector('span') || button;\n if (buttonText.tagName === 'SPAN') {\n buttonText.textContent = option.textContent;\n }\n // Set initial is-filled state based on value\n if (option.value) {\n button.classList.add('is-filled');\n } else {\n button.classList.remove('is-filled');\n }\n } else {\n optionElement.setAttribute('aria-selected', 'false');\n }\n\n customList.appendChild(optionElement);\n });\n\n // Add ARIA attributes\n customList.setAttribute('role', 'listbox');\n customList.setAttribute('id', `${selectName}-listbox`);\n customList.setAttribute('tabindex', '-1');\n customList.setAttribute('aria-hidden', 'true'); // Initial state: hidden\n customList.inert = true; // Prevent keyboard/mouse interaction when closed\n\n button.setAttribute('role', 'combobox');\n button.setAttribute('aria-haspopup', 'listbox');\n button.setAttribute('aria-controls', `${selectName}-listbox`);\n button.setAttribute('aria-expanded', 'false');\n button.setAttribute('id', `${selectName}-button`);\n\n // Find and connect label if exists\n const label =\n wrapper.querySelector('label') || document.querySelector(`label[for=\"${realSelect.id}\"]`);\n if (label) {\n const labelId = label.id || `${selectName}-label`;\n label.id = labelId;\n // Ensure real select has proper ID for label connection\n if (!realSelect.id) {\n realSelect.id = `${selectName}-select`;\n }\n label.setAttribute('for', realSelect.id);\n button.setAttribute('aria-labelledby', labelId);\n }\n\n // Check for visual height wrapper (optional)\n // Only animate if data-hs-height=\"element\" exists in wrapper\n const heightElement = wrapper.querySelector('[data-hs-height=\"element\"]');\n const animationTarget = heightElement || null;\n\n // Track state\n let searchString = '';\n let searchTimeout: number | null = null;\n let enterPressed = false;\n\n // Function to check if select is open\n function isSelectOpen() {\n return wrapper.classList.contains('is-active');\n }\n\n // Update ARIA states based on current visual state\n function updateARIAStates() {\n const isCurrentlyOpen = isSelectOpen();\n const wasOpen = button.getAttribute('aria-expanded') === 'true';\n\n // If closing and focus is inside list, return focus first\n if (wasOpen && !isCurrentlyOpen && customList.contains(document.activeElement)) {\n button.focus();\n }\n\n // Update ARIA attributes\n button.setAttribute('aria-expanded', isCurrentlyOpen ? 'true' : 'false');\n customList.setAttribute('aria-hidden', isCurrentlyOpen ? 'false' : 'true');\n customList.inert = !isCurrentlyOpen; // Enable/disable interaction\n\n if (isCurrentlyOpen) {\n // Make all options tabbable when opened\n const options = customList.querySelectorAll('[role=\"option\"]');\n options.forEach((opt) => {\n opt.setAttribute('tabindex', '0');\n });\n\n // Register with modal manager to prevent body scroll (only when opening)\n if (!wasOpen) {\n openModal();\n }\n } else {\n // Reset on close\n button.removeAttribute('aria-activedescendant');\n const options = customList.querySelectorAll('[role=\"option\"]');\n options.forEach((opt) => {\n opt.setAttribute('tabindex', '-1');\n });\n\n // Unregister with modal manager to restore body scroll (only when closing)\n if (wasOpen) {\n closeModal();\n }\n }\n\n // Animate height if configured\n if (animationTarget) {\n animateHeight(animationTarget, isCurrentlyOpen, { duration: 300, ease: 'power2.inOut' });\n }\n }\n\n // Set initial height without animation (if configured)\n if (animationTarget) {\n setHeight(animationTarget, isSelectOpen());\n }\n\n // Set initial ARIA states\n updateARIAStates();\n\n // Focus option by index\n function focusOption(index: number) {\n const options = customList.querySelectorAll('[role=\"option\"]') as NodeListOf<HTMLElement>;\n if (index < 0 || index >= options.length) return;\n\n // Remove previous focus\n options.forEach((opt) => {\n opt.classList.remove('focused');\n opt.setAttribute('tabindex', '-1');\n });\n\n // Add new focus\n options[index].classList.add('focused');\n options[index].setAttribute('tabindex', '0');\n options[index].focus();\n button.setAttribute('aria-activedescendant', options[index].id);\n }\n\n // Typeahead search functionality\n function handleTypeahead(key: string) {\n // Only handle printable characters (single character keys)\n if (key.length !== 1) return false;\n\n // Clear existing timeout\n if (searchTimeout !== null) {\n clearTimeout(searchTimeout);\n // Remove from cleanup tracking\n const index = cleanup.timeouts.indexOf(searchTimeout);\n if (index > -1) cleanup.timeouts.splice(index, 1);\n }\n\n // Get all options\n const options = Array.from(customList.querySelectorAll('[role=\"option\"]'));\n if (options.length === 0) return false;\n\n // Append to search string\n searchString += key.toLowerCase();\n\n // Find currently focused option index\n const currentIndex = options.findIndex((opt) => opt.classList.contains('focused'));\n\n // If repeating single letter, cycle through options starting with that letter\n if (\n searchString.length === 1 ||\n searchString.split('').every((char) => char === searchString[0])\n ) {\n const letter = searchString[0];\n let startIndex = currentIndex + 1;\n\n // Search from next option onwards\n for (let i = 0; i < options.length; i++) {\n const index = (startIndex + i) % options.length;\n const text = (\n options[index].querySelector('span')?.textContent || options[index].textContent\n ).toLowerCase();\n if (text.startsWith(letter)) {\n focusOption(index);\n if (!isSelectOpen()) wrapper.classList.add('is-active'); // Open if closed\n searchTimeout = setTimeout(clearSearch, 500);\n addTimeout(searchTimeout);\n return true;\n }\n }\n } else {\n // Multi-character search - find first match starting with search string\n const matchIndex = options.findIndex((opt) => {\n const text = (opt.querySelector('span')?.textContent || opt.textContent).toLowerCase();\n return text.startsWith(searchString);\n });\n\n if (matchIndex !== -1) {\n focusOption(matchIndex);\n if (!isSelectOpen()) wrapper.classList.add('is-active'); // Open if closed\n searchTimeout = setTimeout(clearSearch, 500);\n addTimeout(searchTimeout);\n return true;\n }\n }\n\n // Reset timeout even if no match found\n searchTimeout = setTimeout(clearSearch, 500);\n addTimeout(searchTimeout);\n return false;\n }\n\n // Clear search string\n function clearSearch() {\n searchString = '';\n searchTimeout = null;\n }\n\n // Select option\n function selectOption(optionElement: HTMLElement) {\n const value = optionElement.getAttribute('data-value') || '';\n const text = optionElement.querySelector('span')?.textContent || optionElement.textContent;\n\n // Update real select\n realSelect.value = value;\n realSelect.dispatchEvent(new Event('change', { bubbles: true }));\n\n // Update button text\n const buttonText = button.querySelector('span') || button;\n if (buttonText.tagName === 'SPAN') {\n buttonText.textContent = text;\n }\n\n // Update is-filled class based on value\n if (value) {\n button.classList.add('is-filled');\n } else {\n button.classList.remove('is-filled');\n }\n\n // Update aria-selected\n customList.querySelectorAll('[role=\"option\"]').forEach((opt) => {\n opt.setAttribute('aria-selected', 'false');\n });\n optionElement.setAttribute('aria-selected', 'true');\n\n // Close dropdown by toggling wrapper\n wrapper.classList.remove('is-active');\n }\n\n // Button click handler\n const buttonClickHandler = (e: Event) => {\n // If Enter was pressed, don't toggle - allow form submission\n if (enterPressed) {\n enterPressed = false;\n return;\n }\n e.preventDefault();\n wrapper.classList.toggle('is-active');\n };\n addHandler(button, 'click', buttonClickHandler);\n\n // Button keyboard events\n const buttonKeydownHandler = (e: KeyboardEvent) => {\n switch (e.key) {\n case 'Enter':\n e.preventDefault();\n // Find the form's submit button and click it\n const formElement = button.closest('form');\n if (formElement) {\n const submitButton = (formElement.querySelector(\n 'button[type=\"submit\"], input[type=\"submit\"]'\n ) || formElement.querySelector('button:not([type])')) as HTMLElement | null;\n if (submitButton) {\n submitButton.click();\n }\n }\n break;\n\n case ' ':\n e.preventDefault();\n wrapper.classList.toggle('is-active');\n break;\n\n case 'ArrowDown':\n e.preventDefault();\n if (!isSelectOpen()) {\n wrapper.classList.add('is-active');\n // Wait for dropdown to open, then focus first option\n requestAnimationFrame(() => {\n focusOption(0);\n });\n } else {\n focusOption(0);\n }\n break;\n\n case 'ArrowUp':\n e.preventDefault();\n if (!isSelectOpen()) {\n wrapper.classList.add('is-active');\n // Wait for dropdown to open, then focus first option (matches native)\n requestAnimationFrame(() => {\n focusOption(0);\n });\n } else {\n const options = customList.querySelectorAll('[role=\"option\"]');\n focusOption(options.length - 1);\n }\n break;\n\n case 'Escape':\n if (isSelectOpen()) {\n e.preventDefault();\n wrapper.classList.remove('is-active');\n }\n break;\n\n case 'Home':\n e.preventDefault();\n if (!isSelectOpen()) {\n wrapper.classList.add('is-active');\n }\n focusOption(0);\n break;\n\n case 'End':\n e.preventDefault();\n if (!isSelectOpen()) {\n wrapper.classList.add('is-active');\n }\n const endOptions = customList.querySelectorAll('[role=\"option\"]');\n focusOption(endOptions.length - 1);\n break;\n\n default:\n // Handle typeahead search\n if (handleTypeahead(e.key)) {\n e.preventDefault();\n }\n break;\n }\n };\n addHandler(button, 'keydown', buttonKeydownHandler);\n\n // Option keyboard events (delegated)\n const listKeydownHandler = (e: KeyboardEvent) => {\n const option = (e.target as Element).closest('[role=\"option\"]') as HTMLElement | null;\n if (!option) return;\n\n const options = Array.from(customList.querySelectorAll('[role=\"option\"]'));\n const currentIdx = options.indexOf(option);\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (currentIdx < options.length - 1) {\n focusOption(currentIdx + 1);\n }\n break;\n\n case 'ArrowUp':\n e.preventDefault();\n if (currentIdx > 0) {\n focusOption(currentIdx - 1);\n }\n // Stay on first option if already there (matches native)\n break;\n\n case 'Enter':\n e.preventDefault();\n selectOption(option);\n break;\n\n case 'Escape':\n e.preventDefault();\n wrapper.classList.remove('is-active');\n button.focus();\n break;\n\n case 'Home':\n e.preventDefault();\n focusOption(0);\n break;\n\n case 'End':\n e.preventDefault();\n focusOption(options.length - 1);\n break;\n\n default:\n // Handle typeahead search\n if (handleTypeahead(e.key)) {\n e.preventDefault();\n }\n break;\n }\n };\n addHandler(customList, 'keydown', listKeydownHandler);\n\n // Option click events\n const listClickHandler = (e: MouseEvent) => {\n const option = (e.target as Element).closest('[role=\"option\"]') as HTMLElement | null;\n if (option) {\n selectOption(option);\n }\n };\n addHandler(customList, 'click', listClickHandler);\n\n // Handle tabbing out of select list\n const listFocusoutHandler = (e: FocusEvent) => {\n // Check if focus is moving outside the wrapper (or to browser chrome)\n if (\n (!e.relatedTarget || !wrapper.contains(e.relatedTarget as Node)) &&\n wrapper.classList.contains('is-active')\n ) {\n wrapper.classList.remove('is-active'); // Close the dropdown\n }\n };\n addHandler(customList, 'focusout', listFocusoutHandler);\n\n // Handle clicks outside to close dropdown\n const documentClickHandler = (e: MouseEvent) => {\n // If dropdown is open and click is outside wrapper, close it\n if (wrapper.classList.contains('is-active') && !wrapper.contains(e.target as Node)) {\n wrapper.classList.remove('is-active');\n }\n };\n addHandler(document, 'click', documentClickHandler);\n\n // Monitor for class changes on wrapper and update ARIA states\n const observer = new MutationObserver(() => {\n updateARIAStates();\n });\n\n observer.observe(wrapper, {\n attributes: true,\n attributeFilter: ['class'],\n });\n addObserver(observer);\n\n // Observe native select for disabled attribute changes\n const disabledObserver = new MutationObserver(() => {\n updateDisabledState();\n });\n disabledObserver.observe(realSelect, {\n attributes: true,\n attributeFilter: ['disabled'],\n });\n addObserver(disabledObserver);\n\n // Sync with real select changes\n const selectChangeHandler = () => {\n const selectedOption = realSelect.options[realSelect.selectedIndex];\n if (selectedOption) {\n const options = customList.querySelectorAll('[role=\"option\"]');\n const customOption = Array.from(options).find(\n (opt) => opt.getAttribute('data-value') === selectedOption.value\n );\n if (customOption) {\n // Update button text\n const text = customOption.querySelector('span')?.textContent || customOption.textContent;\n const buttonText = button.querySelector('span') || button;\n if (buttonText.tagName === 'SPAN') {\n buttonText.textContent = text;\n }\n\n // Update is-filled class based on value\n if (selectedOption.value) {\n button.classList.add('is-filled');\n } else {\n button.classList.remove('is-filled');\n }\n\n // Update aria-selected\n options.forEach((opt) => {\n opt.setAttribute('aria-selected', 'false');\n });\n customOption.setAttribute('aria-selected', 'true');\n }\n }\n };\n addHandler(realSelect, 'change', selectChangeHandler);\n addHandler(realSelect, 'input', selectChangeHandler);\n\n // Handle form reset\n const form = realSelect.closest('form') as HTMLFormElement | null;\n if (form) {\n const formResetHandler = () => {\n // Native select resets on next tick\n setTimeout(() => {\n selectChangeHandler();\n }, 0);\n };\n addHandler(form, 'reset', formResetHandler);\n }\n }\n\n // Initialize on DOM ready\n if (document.readyState === 'loading') {\n cleanup.domContentLoadedHandler = initCustomSelects;\n document.addEventListener('DOMContentLoaded', cleanup.domContentLoadedHandler);\n } else {\n initCustomSelects();\n }\n\n // INTERNAL API: Exposed for dynamic content reinitialization\n // WARNING: This is an internal API and may change without notice\n // Use window.hsmain.form.reinit() instead (if available in future versions)\n (window as any).initCustomSelects = initCustomSelects;\n\n return {\n result: 'select initialized',\n destroy: () => {\n // Remove DOMContentLoaded listener\n if (cleanup.domContentLoadedHandler) {\n document.removeEventListener('DOMContentLoaded', cleanup.domContentLoadedHandler);\n cleanup.domContentLoadedHandler = null;\n }\n\n // Disconnect all observers\n cleanup.observers.forEach((obs) => obs.disconnect());\n cleanup.observers.length = 0;\n\n // Clear all timeouts\n cleanup.timeouts.forEach((timeoutId) => clearTimeout(timeoutId));\n cleanup.timeouts.length = 0;\n\n // Remove all event listeners\n cleanup.handlers.forEach(({ element, event, handler, options }) => {\n element.removeEventListener(event, handler, options);\n });\n cleanup.handlers.length = 0;\n\n // Remove window API\n if ((window as any).initCustomSelects) {\n delete (window as any).initCustomSelects;\n }\n },\n };\n}\n","/**\n * Select Orchestrator\n *\n * Coordinates initialization of select enhancement functions in proper sequence.\n * Ensures states populate before custom UI is created.\n *\n * Features:\n * - Sequential initialization (states → custom-select)\n * - Error handling with partial cleanup\n * - Centralized cleanup/destroy management\n * - Passes individual configs to sub-functions\n *\n * Initialization Order:\n * 1. states - Populates native <select> with US states\n * 2. custom-select - Creates custom UI over native select\n *\n * This order is critical: custom-select needs to read the populated\n * options from the native select that states creates.\n */\nimport { init as statesInit } from './functions/states.ts';\nimport { init as customSelectInit } from './functions/custom-select.ts';\n\nexport async function init(selectConfig: any) {\n const cleanup = { destroyFunctions: [] as Array<() => void> };\n\n try {\n // IMPORTANT: Load states FIRST to populate native select,\n // then load custom-select to create custom UI\n const statesResult = statesInit(selectConfig.states);\n if (statesResult?.destroy) cleanup.destroyFunctions.push(statesResult.destroy);\n\n const customSelectResult = customSelectInit(selectConfig['custom-select']);\n if (customSelectResult?.destroy) cleanup.destroyFunctions.push(customSelectResult.destroy);\n\n return {\n result: 'select initialized',\n destroy: () => {\n cleanup.destroyFunctions.forEach((destroyFn) => {\n try {\n destroyFn();\n } catch (error) {\n console.error('[select] Error during cleanup:', error);\n }\n });\n cleanup.destroyFunctions.length = 0;\n },\n };\n } catch (error) {\n console.error('[select] Initialization failed:', error);\n // Cleanup any partial initialization\n cleanup.destroyFunctions.forEach((fn) => {\n try {\n fn();\n } catch (cleanupError) {\n console.error('[select] Error during error cleanup:', cleanupError);\n }\n });\n throw error;\n }\n}\n","/**\n * Form Orchestrator\n *\n * Loads form enhancement modules based on element presence.\n * Static imports ensure all modules bundle into single file.\n *\n * Features:\n * - Conditional initialization based on element presence\n * - Centralized cleanup management\n * - Single bundled output file\n *\n * Modules:\n * - honeypot: Spam prevention for forms\n * - range: Range slider with CSS custom properties\n * - test: Development mode form testing\n * - select: Custom select UI (handles states dependency internally)\n */\n\nimport config from '@config';\nimport { getSelector, type ModuleConfig } from '@utils';\nimport { init as honeypotInit } from './functions/honeypot.ts';\nimport { init as rangeInit } from './functions/range.ts';\nimport { init as testInit } from './functions/test.ts';\nimport { init as selectInit } from './functions/select/select.ts';\n\nexport async function init() {\n const moduleConfig = config.structure.form;\n const cleanup = {\n destroyFunctions: [] as Array<() => void>,\n };\n\n // Initialize honeypot if form-handler exists\n const honeypotSelector = getSelector(moduleConfig.honeypot as ModuleConfig, 'form-handler');\n if (document.querySelector(honeypotSelector)) {\n try {\n const result = honeypotInit(moduleConfig.honeypot);\n if (result?.destroy) {\n cleanup.destroyFunctions.push(result.destroy);\n }\n } catch (error) {\n console.error('[form] Error initializing honeypot:', error);\n }\n }\n\n // Initialize range if wrapper exists\n const rangeSelector = getSelector(moduleConfig.range as ModuleConfig, 'wrapper');\n if (document.querySelector(rangeSelector)) {\n try {\n const result = rangeInit(moduleConfig.range as any);\n if (result?.destroy) {\n cleanup.destroyFunctions.push(result.destroy);\n }\n } catch (error) {\n console.error('[form] Error initializing range:', error);\n }\n }\n\n // Initialize test if wrapper exists\n const testSelector = getSelector(moduleConfig.test as ModuleConfig, 'wrapper');\n if (document.querySelector(testSelector)) {\n try {\n const result = testInit(moduleConfig.test);\n if (result?.destroy) {\n cleanup.destroyFunctions.push(result.destroy);\n }\n } catch (error) {\n console.error('[form] Error initializing test:', error);\n }\n }\n\n // Initialize select if wrapper exists\n const selectSelector = getSelector(moduleConfig.select as ModuleConfig, 'wrapper');\n if (document.querySelector(selectSelector)) {\n try {\n const result = await selectInit(moduleConfig.select);\n if (result?.destroy) {\n cleanup.destroyFunctions.push(result.destroy);\n }\n } catch (error) {\n console.error('[form] Error initializing select:', error);\n }\n }\n\n return {\n result: `form initialized (${cleanup.destroyFunctions.length} modules active)`,\n destroy: () => {\n cleanup.destroyFunctions.forEach((destroyFn) => {\n try {\n destroyFn();\n } catch (error) {\n console.error('[form] Error during cleanup:', error);\n }\n });\n cleanup.destroyFunctions.length = 0;\n },\n };\n}\n","/**\n * Honeypot Spam Prevention\n *\n * Simple honeypot field implementation to prevent bot form submissions.\n * Bots auto-fill all fields including hidden ones; legitimate users only fill visible fields.\n *\n * Features:\n * - Listens for all form submissions on the page\n * - Checks if honeypot field (hidden) has been filled\n * - Blocks submission if honeypot contains a value (bot detected)\n * - Uses event capture phase for early interception\n *\n * HTML Structure:\n * <form>\n * <input type=\"text\" name=\"website\" data-hs-form=\"form-handler\" style=\"display:none\">\n * </form>\n *\n * Best Practices:\n * - Hide with CSS (display:none), not type=\"hidden\"\n * - Use realistic field names (\"website\", \"company\")\n * - No visible label or placeholder\n */\n\nimport { querySelector } from '@utils';\n\nexport function init(config) {\n // Centralized cleanup tracking\n const cleanup = {\n honeypotHandler: null,\n };\n\n // Honeypot spam prevention\n const honeypotHandler = (e: Event) => {\n const form = e.target as HTMLElement;\n if (form.tagName !== 'FORM') return;\n\n const honeypot = querySelector(config, 'form-handler', form) as HTMLInputElement;\n if (honeypot && honeypot.value) {\n // Honeypot filled - likely a bot\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n return false;\n }\n };\n\n cleanup.honeypotHandler = honeypotHandler;\n document.addEventListener('submit', honeypotHandler, true);\n\n return {\n result: 'honeypot initialized',\n destroy: () => {\n // Remove honeypot handler\n if (cleanup.honeypotHandler) {\n document.removeEventListener('submit', cleanup.honeypotHandler, true);\n cleanup.honeypotHandler = null;\n }\n },\n };\n}\n","/**\n * Form Test Mode\n *\n * Development tool that prevents form submissions and displays form data in real-time.\n * Useful for testing forms without actually submitting them to servers or triggering actions.\n *\n * Features:\n * - Prevents all form submissions (preventDefault with capture phase)\n * - Displays live form data as JSON on input/change\n * - Shows formatted submit data with timestamp on submit attempt\n * - Logs browser validation failures\n * - Works with native HTML5 form validation\n *\n * HTML Structure:\n * <div data-hs-form-test=\"wrapper\">\n * <form>\n * <input name=\"email\" required>\n * <button type=\"submit\">Submit</button>\n * </form>\n * <div data-hs-form-test=\"info\"></div>\n * </div>\n *\n * Console Output:\n * [form-test] Submit button clicked\n * [form-test] Submission prevented - displaying test results\n */\n\nimport { querySelectorAll, querySelector } from '@utils';\n\nexport function init(config) {\n // Centralized cleanup tracking\n const cleanup = {\n handlers: [],\n };\n\n const addHandler = (\n element: Element,\n event: string,\n handler: EventListener,\n options?: boolean\n ) => {\n element.addEventListener(event, handler, options);\n cleanup.handlers.push({ element, event, handler, options });\n };\n\n // Find all test wrappers\n const testWrappers = querySelectorAll(config, 'wrapper');\n\n testWrappers.forEach((wrapper) => {\n // Find form element within wrapper\n const form = wrapper.querySelector('form') as HTMLFormElement;\n if (!form) {\n console.warn(\n '[form-test] No <form> element found within data-hs-form-test=\"wrapper\"',\n wrapper\n );\n return;\n }\n\n // Find test info element (optional)\n const testInfo = querySelector(config, 'info', wrapper);\n\n // Function to collect and display current form data\n const updateLiveData = () => {\n const formData = new FormData(form);\n const data = {};\n for (const [key, value] of formData.entries()) {\n data[key] = value;\n }\n\n if (testInfo) {\n // Show live form data\n const liveDisplay = document.createElement('pre');\n liveDisplay.textContent = JSON.stringify(data, null, 2);\n\n testInfo.innerHTML = '';\n testInfo.appendChild(document.createTextNode('Test mode active - Live form data:'));\n testInfo.appendChild(liveDisplay);\n }\n };\n\n // Set initial message and data\n if (testInfo) {\n testInfo.textContent = 'Test mode active, preventing native submissions';\n // Show initial form state\n updateLiveData();\n }\n\n // Listen to all form inputs for live updates\n addHandler(form, 'input', updateLiveData);\n addHandler(form, 'change', updateLiveData);\n\n // Find submit button\n const submitButton =\n form.querySelector('button[type=\"submit\"], input[type=\"submit\"]') ||\n form.querySelector('button:not([type])');\n\n // Track button clicks to detect when browser validation blocks submission\n if (submitButton) {\n const clickHandler = () => {\n console.log('[form-test] Submit button clicked');\n\n // Use requestAnimationFrame to check if form will submit\n // If form is invalid, submit event won't fire\n requestAnimationFrame(() => {\n if (!form.checkValidity()) {\n console.log('[form-test] Browser blocked submission - validation failed');\n }\n });\n };\n addHandler(submitButton, 'click', clickHandler);\n }\n\n // Handle form submission\n const submitHandler = (e: Event) => {\n e.preventDefault(); // Prevent actual submission\n e.stopPropagation(); // Stop event from bubbling\n e.stopImmediatePropagation(); // Stop other listeners on same element\n\n console.log('[form-test] Submission prevented - displaying test results');\n\n // Get form data\n const formData = new FormData(form);\n const data = {};\n for (const [key, value] of formData.entries()) {\n data[key] = value;\n }\n\n // Create success message\n const timestamp = new Date().toLocaleTimeString();\n const message = `✅ Form would submit successfully at ${timestamp}`;\n\n // Display in test info element or console\n if (testInfo) {\n // Show form data in a formatted way\n const dataDisplay = document.createElement('pre');\n dataDisplay.textContent = JSON.stringify(data, null, 2);\n\n testInfo.innerHTML = ''; // Clear previous\n testInfo.appendChild(document.createTextNode(message));\n testInfo.appendChild(dataDisplay);\n } else {\n console.log(message);\n console.log('Form data:', data);\n }\n\n return false; // Extra insurance to prevent submission\n };\n\n // Use capture phase to catch submit event before anything else\n addHandler(form, 'submit', submitHandler, true);\n });\n\n return {\n result: `test initialized on ${testWrappers.length} form${testWrappers.length !== 1 ? 's' : ''}`,\n destroy: () => {\n // Remove all event listeners\n cleanup.handlers.forEach(({ element, event, handler, options }) => {\n element.removeEventListener(event, handler, options);\n });\n cleanup.handlers.length = 0;\n },\n };\n}\n"],"names":["init","config","cleanup","handlers","domContentLoadedHandler","addHandler","element","event","handler","addEventListener","push","initRangeComponents","querySelectorAll","forEach","wrapper","htmlWrapper","dataset","hsFormRangeInit","input","querySelector","console","warn","output","update","min","max","val","value","progress","style","setProperty","globalConfig","_global","cssVars","prefix","String","textContent","initSingleRange","document","readyState","result","destroy","removeEventListener","length","US_STATES","name","observers","timeouts","addObserver","observer","options","addTimeout","timeoutId","initCustomSelects","div","select","parentElement","firstChild","appendChild","remove","realSelect","setAttribute","selectName","getAttribute","customList","button","updateDisabledState","disabled","removeAttribute","optionTemplate","firstElementChild","templateClone","cloneNode","option","index","optionElement","textSpan","selected","buttonText","tagName","classList","add","inert","label","id","labelId","heightElement","animationTarget","searchString","searchTimeout","isSelectOpen","contains","updateARIAStates","isCurrentlyOpen","wasOpen","activeElement","focus","opt","openModal","closeModal","animateHeight","duration","ease","setHeight","focusOption","handleTypeahead","key","clearTimeout","indexOf","splice","Array","from","toLowerCase","currentIndex","findIndex","split","every","char","letter","startIndex","i","startsWith","setTimeout","clearSearch","matchIndex","selectOption","text","dispatchEvent","Event","bubbles","buttonClickHandler","e","preventDefault","toggle","buttonKeydownHandler","formElement","closest","submitButton","click","requestAnimationFrame","listKeydownHandler","target","currentIdx","listFocusoutHandler","relatedTarget","documentClickHandler","MutationObserver","observe","attributes","attributeFilter","disabledObserver","selectChangeHandler","selectedOption","selectedIndex","customOption","find","form","initSingleSelect","window","obs","disconnect","async","selectConfig","destroyFunctions","statesResult","stateSelects","selectElement","existingOptions","templateOption","placeholderText","innerHTML","placeholder","createElement","state","statesInit","states","customSelectResult","customSelectInit","destroyFn","error","fn","cleanupError","moduleConfig","structure","honeypotSelector","getSelector","honeypot","honeypotHandler","stopPropagation","stopImmediatePropagation","honeypotInit","rangeSelector","range","rangeInit","testSelector","test","testWrappers","testInfo","updateLiveData","formData","FormData","data","entries","liveDisplay","JSON","stringify","createTextNode","log","checkValidity","message","Date","toLocaleTimeString","dataDisplay","testInit","selectSelector","selectInit"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{g as e}from"./hs-utils-CKm6QhLw.js";import{p as r,g as t,w as s,i as a,b as i,d as n,e as o}from"./hs-modalManager-H_YegPAO.js";import"../main.js";const l='[data-hs-marquee="wrapper"]',c="data-hs-marquee-direction",u="data-hs-marquee-duration",g="data-hs-marquee-scroll",m="data-hs-marquee-type",d=25,p=0;async function h(){if(r())return{result:"marquee skipped - prefers-reduced-motion enabled"};const h=t("marquee");if(!h)return{result:"marquee skipped - GSAP not loaded"};const{gsap:f,ScrollTrigger:q}=h;s("marquee",["ScrollTrigger"],"error"),q&&f.registerPlugin(q),a(),i();const k=Array.from(document.querySelectorAll(l)),A={timelines:[],scrollTriggers:[],tickers:[]};return k.forEach(r=>{const t=r.getAttribute(c),s=Array.from(r.children);if(0===s.length)return void console.warn("[marquee] No children found in marquee wrapper:",r);const a=r.getAttribute(u),i=a?parseFloat(a):d,l=r.getAttribute(g),h=l?parseFloat(l):p,q=r.getAttribute(m);a||r.setAttribute(u,String(d)),l||r.setAttribute(g,String(p)),r.classList.add(e.classes.gsap);const k=f.timeline({repeat:-1});if(s.forEach(e=>{"left"===t?k.to(e,{xPercent:-100,duration:i,ease:"none"},0):"right"===t&&(f.set(e,{xPercent:-100}),k.to(e,{xPercent:0,duration:i,ease:"none"},0))}),A.timelines.push(k),h>0){let e=1;const r=()=>{const r=o(),t=n();let s=1;if("reverse"===q)if(1===t)s=1+r*h;else if(-1===t){const e=r*h;s=e>.5?-e:1}else s=1;else{s=1+r*h}Math.abs(s-e)>.001&&(k.timeScale(s),e=s)};f.ticker.add(r),A.tickers.push({tickerFunc:r,gsap:f})}}),{result:`marquee initialized (${k.length} instances)`,destroy:()=>{A.timelines.forEach(e=>{e&&e.kill()}),A.scrollTriggers.forEach(e=>{e&&e.kill()}),A.tickers.forEach(({tickerFunc:e,gsap:r})=>{r.ticker.remove(e)}),k.forEach(r=>{r.classList.remove(e.classes.gsap)}),A.timelines.length=0,A.scrollTriggers.length=0,A.tickers.length=0}}}export{h as init};
2
+ //# sourceMappingURL=hs-marquee-CZ9pmCbT.js.map
@@ -0,0 +1,2 @@
1
+ import{g as e}from"./hs-utils-CKm6QhLw.js";import{p as r,g as t,w as s,i as a,b as i,d as n,e as o}from"./hs-modalManager-H_YegPAO.js";import"../main.js";const l='[data-hs-marquee="wrapper"]',c="data-hs-marquee-direction",u="data-hs-marquee-duration",g="data-hs-marquee-scroll",m="data-hs-marquee-type",d=25,p=0;async function h(){if(r())return{result:"marquee skipped - prefers-reduced-motion enabled"};const h=t("marquee");if(!h)return{result:"marquee skipped - GSAP not loaded"};const{gsap:f,ScrollTrigger:q}=h;s("marquee",["ScrollTrigger"],"error"),q&&f.registerPlugin(q),a(),i();const k=Array.from(document.querySelectorAll(l)),A={timelines:[],scrollTriggers:[],tickers:[]};return k.forEach(r=>{const t=r.getAttribute(c),s=Array.from(r.children);if(0===s.length)return void console.warn("[marquee] No children found in marquee wrapper:",r);const a=r.getAttribute(u),i=a?parseFloat(a):d,l=r.getAttribute(g),h=l?parseFloat(l):p,q=r.getAttribute(m);a||r.setAttribute(u,String(d)),l||r.setAttribute(g,String(p)),r.classList.add(e.classes.gsap);const k=f.timeline({repeat:-1});if(s.forEach(e=>{"left"===t?k.to(e,{xPercent:-100,duration:i,ease:"none"},0):"right"===t&&(f.set(e,{xPercent:-100}),k.to(e,{xPercent:0,duration:i,ease:"none"},0))}),A.timelines.push(k),h>0){let e=1;const r=()=>{const r=o(),t=n();let s=1;if("reverse"===q)if(1===t)s=1+r*h;else if(-1===t){const e=r*h;s=e>.5?-e:1}else s=1;else{s=1+r*h}Math.abs(s-e)>.001&&(k.timeScale(s),e=s)};f.ticker.add(r),A.tickers.push({tickerFunc:r,gsap:f})}}),{result:`marquee initialized (${k.length} instances)`,destroy:()=>{A.timelines.forEach(e=>{e&&e.kill()}),A.scrollTriggers.forEach(e=>{e&&e.kill()}),A.tickers.forEach(({tickerFunc:e,gsap:r})=>{r.ticker.remove(e)}),k.forEach(r=>{r.classList.remove(e.classes.gsap)}),A.timelines.length=0,A.scrollTriggers.length=0,A.tickers.length=0}}}export{h as init};
2
+ //# sourceMappingURL=hs-marquee-CZ9pmCbT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hs-marquee-CZ9pmCbT.js","sources":["../../src/animations/functions/marquee.ts"],"sourcesContent":["/**\n * Marquee Module\n *\n * GSAP-powered infinite scrolling marquee with scroll-based interactions.\n * Works with normalize/dupe module for content duplication.\n *\n * Usage:\n * <div data-hs-marquee=\"wrapper\" data-hs-marquee-direction=\"left\">\n * <div data-hs-dupe=\"child\" data-hs-dupe-count=\"2\">\n * <!-- Content here -->\n * </div>\n * </div>\n *\n * Scroll Behavior:\n * - Default: Speeds up when scrolling (magnitude only)\n * - Type \"reverse\": Scroll down speeds up, scroll up reverses animation\n * - Smooth velocity interpolation for buttery transitions\n */\n\nimport {\n globalConfig,\n getGsap,\n prefersReducedMotion,\n warnMissingDependencies,\n initScrollVelocityTracking,\n initScrollTriggerRefresh,\n getScrollVelocity,\n getScrollDirection,\n type GsapTimeline,\n} from '@utils';\n\ninterface GsapInstance {\n timeline: (vars?: Record<string, unknown>) => GsapTimeline;\n set: (target: unknown, vars: Record<string, unknown>) => void;\n registerPlugin: (...plugins: unknown[]) => void;\n ticker: {\n add: (callback: () => void) => void;\n remove: (callback: () => void) => void;\n };\n}\n\n// Selectors and Attributes\nconst SELECTORS = {\n wrapper: '[data-hs-marquee=\"wrapper\"]',\n};\n\nconst ATTRIBUTES = {\n direction: 'data-hs-marquee-direction',\n duration: 'data-hs-marquee-duration',\n scroll: 'data-hs-marquee-scroll',\n type: 'data-hs-marquee-type',\n};\n\nconst DEFAULTS = {\n duration: 25,\n scrollMultiplier: 0,\n};\n\nexport async function init() {\n // Skip if user prefers reduced motion\n if (prefersReducedMotion()) {\n return { result: 'marquee skipped - prefers-reduced-motion enabled' };\n }\n\n const gsapLib = getGsap('marquee');\n if (!gsapLib) {\n return { result: 'marquee skipped - GSAP not loaded' };\n }\n\n const { gsap, ScrollTrigger } = gsapLib;\n\n // Warn about missing required dependencies (marquee needs ScrollTrigger for scroll effects)\n warnMissingDependencies('marquee', ['ScrollTrigger'], 'error');\n\n if (ScrollTrigger) {\n gsap.registerPlugin(ScrollTrigger);\n }\n\n // Initialize global scroll utilities (only run once)\n initScrollVelocityTracking();\n initScrollTriggerRefresh();\n\n const marquees = Array.from(document.querySelectorAll(SELECTORS.wrapper));\n const cleanup = {\n timelines: [] as GsapTimeline[],\n scrollTriggers: [] as any[],\n tickers: [] as Array<{ tickerFunc: () => void; gsap: GsapInstance }>,\n };\n\n marquees.forEach((marquee) => {\n const direction = marquee.getAttribute(ATTRIBUTES.direction);\n const children = Array.from(marquee.children);\n\n if (children.length === 0) {\n console.warn('[marquee] No children found in marquee wrapper:', marquee);\n return;\n }\n\n // Get duration - check attribute first, then use default\n const durationAttr = marquee.getAttribute(ATTRIBUTES.duration);\n const duration = durationAttr ? parseFloat(durationAttr) : DEFAULTS.duration;\n\n // Get scroll multiplier - check attribute first, then use default\n const scrollAttr = marquee.getAttribute(ATTRIBUTES.scroll);\n const scrollMultiplier = scrollAttr ? parseFloat(scrollAttr) : DEFAULTS.scrollMultiplier;\n\n // Get marquee type (reverse or default)\n const marqueeType = marquee.getAttribute(ATTRIBUTES.type);\n\n // Set attributes with defaults if not present (for visibility in DOM)\n if (!durationAttr) {\n marquee.setAttribute(ATTRIBUTES.duration, String(DEFAULTS.duration));\n }\n if (!scrollAttr) {\n marquee.setAttribute(ATTRIBUTES.scroll, String(DEFAULTS.scrollMultiplier));\n }\n\n // Add class to indicate GSAP is controlling animation\n marquee.classList.add(globalConfig.classes.gsap);\n\n // Create GSAP timeline\n const tl = gsap.timeline({ repeat: -1 });\n\n // Animate all children together at the same time\n children.forEach((child) => {\n if (direction === 'left') {\n // Left: 0% → -100%\n tl.to(\n child,\n {\n xPercent: -100,\n duration: duration,\n ease: 'none',\n },\n 0\n );\n } else if (direction === 'right') {\n // Right: -100% → 0%\n gsap.set(child, { xPercent: -100 }); // Start from -100%\n tl.to(\n child,\n {\n xPercent: 0,\n duration: duration,\n ease: 'none',\n },\n 0\n );\n }\n });\n\n cleanup.timelines.push(tl);\n\n // Add scroll-based speed boost if scroll multiplier is set\n if (scrollMultiplier > 0) {\n let lastTimeScale = 1;\n\n const tickerFunc = () => {\n // Get global scroll velocity and direction\n const scrollSpeed = getScrollVelocity();\n const scrollDir = getScrollDirection();\n let newTimeScale = 1;\n\n if (marqueeType === 'reverse') {\n // Reverse type: scroll down speeds up, scroll up reverses\n if (scrollDir === 1) {\n // Scrolling down: speed up in normal direction\n newTimeScale = 1 + scrollSpeed * scrollMultiplier;\n } else if (scrollDir === -1) {\n // Scrolling up: reverse the animation\n // Use absolute minimum to prevent getting stuck at 0\n const reverseScale = scrollSpeed * scrollMultiplier;\n newTimeScale = reverseScale > 0.5 ? -reverseScale : 1;\n } else {\n // Not scrolling: return to base speed\n newTimeScale = 1;\n }\n } else {\n // Default type: just speed up based on velocity (no direction)\n const speedBoost = scrollSpeed * scrollMultiplier;\n newTimeScale = 1 + speedBoost;\n }\n\n // Only update if changed (avoid unnecessary updates)\n if (Math.abs(newTimeScale - lastTimeScale) > 0.001) {\n tl.timeScale(newTimeScale);\n lastTimeScale = newTimeScale;\n }\n };\n\n // Add ticker function to GSAP's ticker\n gsap.ticker.add(tickerFunc);\n\n // Store ticker function and gsap reference for cleanup\n cleanup.tickers.push({ tickerFunc, gsap: gsap as GsapInstance });\n }\n });\n\n return {\n result: `marquee initialized (${marquees.length} instances)`,\n destroy: () => {\n // Kill all timelines\n cleanup.timelines.forEach((tl) => {\n if (tl) tl.kill();\n });\n\n // Kill all scroll triggers\n cleanup.scrollTriggers.forEach((st) => {\n if (st) (st as any).kill();\n });\n\n // Remove all ticker functions\n cleanup.tickers.forEach(({ tickerFunc, gsap: gsapInstance }) => {\n gsapInstance.ticker.remove(tickerFunc);\n });\n\n // Remove GSAP class from all marquees\n marquees.forEach((marquee) => {\n marquee.classList.remove(globalConfig.classes.gsap);\n });\n\n // Clear arrays\n cleanup.timelines.length = 0;\n cleanup.scrollTriggers.length = 0;\n cleanup.tickers.length = 0;\n },\n };\n}\n"],"names":["SELECTORS","ATTRIBUTES","DEFAULTS","async","init","prefersReducedMotion","result","gsapLib","getGsap","gsap","ScrollTrigger","warnMissingDependencies","registerPlugin","initScrollVelocityTracking","initScrollTriggerRefresh","marquees","Array","from","document","querySelectorAll","cleanup","timelines","scrollTriggers","tickers","forEach","marquee","direction","getAttribute","children","length","console","warn","durationAttr","duration","parseFloat","scrollAttr","scrollMultiplier","marqueeType","setAttribute","String","classList","add","globalConfig","classes","tl","timeline","repeat","child","to","xPercent","ease","set","push","lastTimeScale","tickerFunc","scrollSpeed","getScrollVelocity","scrollDir","getScrollDirection","newTimeScale","reverseScale","Math","abs","timeScale","ticker","destroy","kill","st","gsapInstance","remove"],"mappings":"0JA0CA,MAAMA,EACK,8BAGLC,EACO,4BADPA,EAEM,2BAFNA,EAGI,yBAHJA,EAIE,uBAGFC,EACM,GADNA,EAEc,EAGpBC,eAAsBC,IAEpB,GAAIC,IACF,MAAO,CAAEC,OAAQ,oDAGnB,MAAMC,EAAUC,EAAQ,WACxB,IAAKD,EACH,MAAO,CAAED,OAAQ,qCAGnB,MAAMG,KAAEA,EAAAC,cAAMA,GAAkBH,EAGhCI,EAAwB,UAAW,CAAC,iBAAkB,SAElDD,GACFD,EAAKG,eAAeF,GAItBG,IACAC,IAEA,MAAMC,EAAWC,MAAMC,KAAKC,SAASC,iBAAiBnB,IAChDoB,EAAU,CACdC,UAAW,GACXC,eAAgB,GAChBC,QAAS,IAgHX,OA7GAR,EAASS,QAASC,IAChB,MAAMC,EAAYD,EAAQE,aAAa1B,GACjC2B,EAAWZ,MAAMC,KAAKQ,EAAQG,UAEpC,GAAwB,IAApBA,EAASC,OAEX,YADAC,QAAQC,KAAK,kDAAmDN,GAKlE,MAAMO,EAAeP,EAAQE,aAAa1B,GACpCgC,EAAWD,EAAeE,WAAWF,GAAgB9B,EAGrDiC,EAAaV,EAAQE,aAAa1B,GAClCmC,EAAmBD,EAAaD,WAAWC,GAAcjC,EAGzDmC,EAAcZ,EAAQE,aAAa1B,GAGpC+B,GACHP,EAAQa,aAAarC,EAAqBsC,OAAOrC,IAE9CiC,GACHV,EAAQa,aAAarC,EAAmBsC,OAAOrC,IAIjDuB,EAAQe,UAAUC,IAAIC,EAAaC,QAAQlC,MAG3C,MAAMmC,EAAKnC,EAAKoC,SAAS,CAAEC,YAiC3B,GA9BAlB,EAASJ,QAASuB,IACE,SAAdrB,EAEFkB,EAAGI,GACDD,EACA,CACEE,UAAU,IACVhB,WACAiB,KAAM,QAER,GAEqB,UAAdxB,IAETjB,EAAK0C,IAAIJ,EAAO,CAAEE,gBAClBL,EAAGI,GACDD,EACA,CACEE,SAAU,EACVhB,WACAiB,KAAM,QAER,MAKN9B,EAAQC,UAAU+B,KAAKR,GAGnBR,EAAmB,EAAG,CACxB,IAAIiB,EAAgB,EAEpB,MAAMC,EAAa,KAEjB,MAAMC,EAAcC,IACdC,EAAYC,IAClB,IAAIC,EAAe,EAEnB,GAAoB,YAAhBtB,EAEF,GAAkB,IAAdoB,EAEFE,EAAe,EAAIJ,EAAcnB,OACnC,IAAyB,IAAdqB,EAAkB,CAG3B,MAAMG,EAAeL,EAAcnB,EACnCuB,EAAeC,EAAe,IAAOA,EAAe,CACtD,MAEED,EAAe,MAEZ,CAGLA,EAAe,EADIJ,EAAcnB,CAEnC,CAGIyB,KAAKC,IAAIH,EAAeN,GAAiB,OAC3CT,EAAGmB,UAAUJ,GACbN,EAAgBM,IAKpBlD,EAAKuD,OAAOvB,IAAIa,GAGhBlC,EAAQG,QAAQ6B,KAAK,CAAEE,aAAY7C,QACrC,IAGK,CACLH,OAAQ,wBAAwBS,EAASc,oBACzCoC,QAAS,KAEP7C,EAAQC,UAAUG,QAASoB,IACrBA,KAAOsB,SAIb9C,EAAQE,eAAeE,QAAS2C,IAC1BA,KAAgBD,SAItB9C,EAAQG,QAAQC,QAAQ,EAAG8B,aAAY7C,KAAM2D,MAC3CA,EAAaJ,OAAOK,OAAOf,KAI7BvC,EAASS,QAASC,IAChBA,EAAQe,UAAU6B,OAAO3B,EAAaC,QAAQlC,QAIhDW,EAAQC,UAAUQ,OAAS,EAC3BT,EAAQE,eAAeO,OAAS,EAChCT,EAAQG,QAAQM,OAAS,GAG/B"}
@@ -0,0 +1,2 @@
1
+ import{c as e}from"../main.js";let t=!1,n=0,o=0,r=!1,a=!1;function i(){if(r||!c())return;const e=window.gsap;let t=window.scrollY,a=performance.now(),i=0,l=0;window.ScrollTrigger.create({onUpdate:()=>{const e=window.scrollY,n=performance.now(),r=e-t,l=n-a;r>0?o=1:r<0&&(o=-1),l>0&&(i=Math.abs(r)/l*1e3),t=e,a=n}}),e.ticker.add(()=>{l+=.08*(i-l),i*=.95,Math.abs(l)<.1&&(l=0),Math.abs(i)<.1&&(i=0),n=l}),r=!0}function l(){return n}function s(){return o}function c(){return void 0!==window.ScrollTrigger}function u(e,n=!0){return void 0===window.gsap?(n&&!t?(console.warn("[gsap] GSAP library not detected. Some animations will be skipped. Add GSAP to your project: https://greensock.com/docs/v3/Installation"),t=!0):e&&!t&&(console.warn(`[${e}] GSAP not available, module will use fallback behavior`),t=!0),null):{gsap:window.gsap,ScrollTrigger:window.ScrollTrigger,Draggable:window.Draggable}}function g(e,t,n="warn"){const o=[];if(t.forEach(e=>{"ScrollTrigger"!==e||c()?"Draggable"===e&&void 0===window.Draggable&&o.push("Draggable"):o.push("ScrollTrigger")}),0===o.length)return;const r=o.join(", "),a="error"===n?`[${e}] Missing required GSAP plugin(s): ${r}. Module will not work correctly. Add to your project: https://greensock.com/docs/v3/Installation`:`[${e}] Missing optional GSAP plugin(s): ${r}. Some features will be disabled. Add for full functionality: https://greensock.com/docs/v3/Installation`;"error"===n?console.error(a):console.warn(a)}function d(){if(a||!c())return;let e=null;document.addEventListener("load",t=>{t.target instanceof HTMLImageElement&&(null!==e&&clearTimeout(e),e=setTimeout(()=>{window.ScrollTrigger.refresh(),e=null},50))},!0),a=!0}function f(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}const h=new class{#e=new Map;async animate(t,n,o={}){const r=u("heightAnimator");if(!r)return;const{gsap:a}=r,i=e._global.attributes.height,l=e._global.attributes.heightValue,s=e._global.attributes.heightDuration,c=e._global.attributes.heightEase,g=t.hasAttribute?.(i)&&t.getAttribute(i)===l?t:t.querySelector?.(`[${i}="${l}"]`)||t,d=this.#e.get(g);d&&(d.kill(),this.#e.delete(g));let h=g.getAttribute(s),p=g.getAttribute(c);!h&&g.parentElement&&(h=g.parentElement.getAttribute(s)),!p&&g.parentElement&&(p=g.parentElement.getAttribute(c));let w=h?parseInt(h,10)/1e3:(o.duration||300)/1e3;f()&&(w=0);const m=p||o.ease||"power2.inOut",b=a.to(g,{height:n?"auto":0,duration:w,ease:m});this.#e.set(g,b);try{await b.then()}finally{this.#e.delete(g)}}setHeight(t,n){const o=u("heightAnimator");if(!o)return;const{gsap:r}=o,a=e._global.attributes.height,i=e._global.attributes.heightValue,l=t.hasAttribute?.(a)&&t.getAttribute(a)===i?t:t.querySelector?.(`[${a}="${i}"]`)||t;r.set(l,{height:n?"auto":0})}cancelAll(){this.#e.forEach(e=>e.kill()),this.#e.clear()}},p=h.animate.bind(h),w=h.setHeight.bind(h);let m=0;const b=[],A=[];let y=!0,v=null;function M(){if(!y)return null;if(v)return v;const e=window;return e.lenis&&"function"==typeof e.lenis.stop&&"function"==typeof e.lenis.start?(v=e.lenis,e.lenis):null}function S(){if(m++,1===m){const n=e._global.classes.modalOpen,o=e._global.classes.overflowHidden;document.body.classList.add(o,n);const r=M();if(r)try{r.stop()}catch(t){console.error("[modalManager] Error stopping Lenis:",t)}b.forEach(e=>{try{e()}catch(t){console.error("[modalManager] Error in open callback:",t)}})}}function E(){if(m--,0===m){const n=e._global.classes.modalOpen,o=e._global.classes.overflowHidden;document.body.classList.remove(o,n);const r=M();if(r)try{r.start()}catch(t){console.error("[modalManager] Error starting Lenis:",t)}A.forEach(e=>{try{e()}catch(t){console.error("[modalManager] Error in close callback:",t)}})}m<0&&(console.warn("[modalManager] Modal count went negative, resetting to 0"),m=0)}if("undefined"!=typeof window){const e=window;e.HS=e.HS||{},e.HS.modal={open:S,close:E,getCount:function(){return m},isOpen:function(){return m>0},onOpen:function(e){return"function"!=typeof e?(console.warn("[modalManager] onModalOpen requires a function"),()=>{}):(b.push(e),()=>{const t=b.indexOf(e);t>-1&&b.splice(t,1)})},onClose:function(e){return"function"!=typeof e?(console.warn("[modalManager] onModalClose requires a function"),()=>{}):(A.push(e),()=>{const t=A.indexOf(e);t>-1&&A.splice(t,1)})},setLenisEnabled:function(e){y=e,e||(v=null)}}}export{p as a,d as b,E as c,s as d,l as e,u as g,i,S as o,f as p,w as s,g as w};
2
+ //# sourceMappingURL=hs-modalManager-H_YegPAO.js.map
@@ -0,0 +1,2 @@
1
+ import{c as e}from"../main.js";let t=!1,n=0,o=0,r=!1,a=!1;function i(){if(r||!c())return;const e=window.gsap;let t=window.scrollY,a=performance.now(),i=0,l=0;window.ScrollTrigger.create({onUpdate:()=>{const e=window.scrollY,n=performance.now(),r=e-t,l=n-a;r>0?o=1:r<0&&(o=-1),l>0&&(i=Math.abs(r)/l*1e3),t=e,a=n}}),e.ticker.add(()=>{l+=.08*(i-l),i*=.95,Math.abs(l)<.1&&(l=0),Math.abs(i)<.1&&(i=0),n=l}),r=!0}function l(){return n}function s(){return o}function c(){return void 0!==window.ScrollTrigger}function u(e,n=!0){return void 0===window.gsap?(n&&!t?(console.warn("[gsap] GSAP library not detected. Some animations will be skipped. Add GSAP to your project: https://greensock.com/docs/v3/Installation"),t=!0):e&&!t&&(console.warn(`[${e}] GSAP not available, module will use fallback behavior`),t=!0),null):{gsap:window.gsap,ScrollTrigger:window.ScrollTrigger,Draggable:window.Draggable}}function g(e,t,n="warn"){const o=[];if(t.forEach(e=>{"ScrollTrigger"!==e||c()?"Draggable"===e&&void 0===window.Draggable&&o.push("Draggable"):o.push("ScrollTrigger")}),0===o.length)return;const r=o.join(", "),a="error"===n?`[${e}] Missing required GSAP plugin(s): ${r}. Module will not work correctly. Add to your project: https://greensock.com/docs/v3/Installation`:`[${e}] Missing optional GSAP plugin(s): ${r}. Some features will be disabled. Add for full functionality: https://greensock.com/docs/v3/Installation`;"error"===n?console.error(a):console.warn(a)}function d(){if(a||!c())return;let e=null;document.addEventListener("load",t=>{t.target instanceof HTMLImageElement&&(null!==e&&clearTimeout(e),e=setTimeout(()=>{window.ScrollTrigger.refresh(),e=null},50))},!0),a=!0}function f(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}const h=new class{#e=new Map;async animate(t,n,o={}){const r=u("heightAnimator");if(!r)return;const{gsap:a}=r,i=e._global.attributes.height,l=e._global.attributes.heightValue,s=e._global.attributes.heightDuration,c=e._global.attributes.heightEase,g=t.hasAttribute?.(i)&&t.getAttribute(i)===l?t:t.querySelector?.(`[${i}="${l}"]`)||t,d=this.#e.get(g);d&&(d.kill(),this.#e.delete(g));let h=g.getAttribute(s),p=g.getAttribute(c);!h&&g.parentElement&&(h=g.parentElement.getAttribute(s)),!p&&g.parentElement&&(p=g.parentElement.getAttribute(c));let w=h?parseInt(h,10)/1e3:(o.duration||300)/1e3;f()&&(w=0);const m=p||o.ease||"power2.inOut",b=a.to(g,{height:n?"auto":0,duration:w,ease:m});this.#e.set(g,b);try{await b.then()}finally{this.#e.delete(g)}}setHeight(t,n){const o=u("heightAnimator");if(!o)return;const{gsap:r}=o,a=e._global.attributes.height,i=e._global.attributes.heightValue,l=t.hasAttribute?.(a)&&t.getAttribute(a)===i?t:t.querySelector?.(`[${a}="${i}"]`)||t;r.set(l,{height:n?"auto":0})}cancelAll(){this.#e.forEach(e=>e.kill()),this.#e.clear()}},p=h.animate.bind(h),w=h.setHeight.bind(h);let m=0;const b=[],A=[];let y=!0,v=null;function M(){if(!y)return null;if(v)return v;const e=window;return e.lenis&&"function"==typeof e.lenis.stop&&"function"==typeof e.lenis.start?(v=e.lenis,e.lenis):null}function S(){if(m++,1===m){const n=e._global.classes.modalOpen,o=e._global.classes.overflowHidden;document.body.classList.add(o,n);const r=M();if(r)try{r.stop()}catch(t){console.error("[modalManager] Error stopping Lenis:",t)}b.forEach(e=>{try{e()}catch(t){console.error("[modalManager] Error in open callback:",t)}})}}function E(){if(m--,0===m){const n=e._global.classes.modalOpen,o=e._global.classes.overflowHidden;document.body.classList.remove(o,n);const r=M();if(r)try{r.start()}catch(t){console.error("[modalManager] Error starting Lenis:",t)}A.forEach(e=>{try{e()}catch(t){console.error("[modalManager] Error in close callback:",t)}})}m<0&&(console.warn("[modalManager] Modal count went negative, resetting to 0"),m=0)}if("undefined"!=typeof window){const e=window;e.HS=e.HS||{},e.HS.modal={open:S,close:E,getCount:function(){return m},isOpen:function(){return m>0},onOpen:function(e){return"function"!=typeof e?(console.warn("[modalManager] onModalOpen requires a function"),()=>{}):(b.push(e),()=>{const t=b.indexOf(e);t>-1&&b.splice(t,1)})},onClose:function(e){return"function"!=typeof e?(console.warn("[modalManager] onModalClose requires a function"),()=>{}):(A.push(e),()=>{const t=A.indexOf(e);t>-1&&A.splice(t,1)})},setLenisEnabled:function(e){y=e,e||(v=null)}}}export{p as a,d as b,E as c,s as d,l as e,u as g,i,S as o,f as p,w as s,g as w};
2
+ //# sourceMappingURL=hs-modalManager-H_YegPAO.js.map