@hortonstudio/main 1.9.23 → 1.9.25

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 (61) hide show
  1. package/README.md +62 -64
  2. package/dist/assets/hs-animations-tvD4W7u0.js +3 -0
  3. package/dist/assets/hs-animations-tvD4W7u0.js.br +0 -0
  4. package/dist/assets/hs-animations-tvD4W7u0.js.gz +0 -0
  5. package/dist/assets/hs-animations-tvD4W7u0.js.map +1 -0
  6. package/dist/assets/hs-counter-DmspKHOV.js +2 -0
  7. package/dist/assets/hs-counter-DmspKHOV.js.br +0 -0
  8. package/dist/assets/hs-counter-DmspKHOV.js.gz +0 -0
  9. package/dist/assets/hs-counter-DmspKHOV.js.map +1 -0
  10. package/dist/assets/hs-default-Dxg7WNGx.js +2 -0
  11. package/dist/assets/hs-default-Dxg7WNGx.js.br +0 -0
  12. package/dist/assets/hs-default-Dxg7WNGx.js.gz +0 -0
  13. package/dist/assets/hs-default-Dxg7WNGx.js.map +1 -0
  14. package/dist/assets/hs-marquee-Dwenaw7L.js +2 -0
  15. package/dist/assets/hs-marquee-Dwenaw7L.js.br +0 -0
  16. package/dist/assets/hs-marquee-Dwenaw7L.js.gz +0 -0
  17. package/dist/assets/hs-marquee-Dwenaw7L.js.map +1 -0
  18. package/dist/assets/hs-normalize-iTnWVIjq.js +2 -0
  19. package/dist/assets/hs-normalize-iTnWVIjq.js.br +0 -0
  20. package/dist/assets/hs-normalize-iTnWVIjq.js.gz +0 -0
  21. package/dist/assets/hs-normalize-iTnWVIjq.js.map +1 -0
  22. package/dist/assets/hs-utils-CNwAFmmK.js +2 -0
  23. package/dist/assets/hs-utils-CNwAFmmK.js.br +0 -0
  24. package/dist/assets/hs-utils-CNwAFmmK.js.gz +0 -0
  25. package/dist/assets/hs-utils-CNwAFmmK.js.map +1 -0
  26. package/dist/main.js +2 -2
  27. package/dist/main.js.br +0 -0
  28. package/dist/main.js.gz +0 -0
  29. package/dist/main.js.map +1 -1
  30. package/package.json +2 -2
  31. package/dist/assets/animations-igIF6V0K.js +0 -3
  32. package/dist/assets/animations-igIF6V0K.js. +0 -3
  33. package/dist/assets/animations-igIF6V0K.js.gz +0 -0
  34. package/dist/assets/animations-igIF6V0K.js.map +0 -1
  35. package/dist/assets/counter-B9xmgh8V.js +0 -2
  36. package/dist/assets/counter-B9xmgh8V.js. +0 -2
  37. package/dist/assets/counter-B9xmgh8V.js.gz +0 -0
  38. package/dist/assets/counter-B9xmgh8V.js.map +0 -1
  39. package/dist/assets/cssVariables-n9wQSSYb.js +0 -2
  40. package/dist/assets/cssVariables-n9wQSSYb.js.map +0 -1
  41. package/dist/assets/default-CZ6vle49.js +0 -2
  42. package/dist/assets/default-CZ6vle49.js. +0 -2
  43. package/dist/assets/default-CZ6vle49.js.gz +0 -0
  44. package/dist/assets/default-CZ6vle49.js.map +0 -1
  45. package/dist/assets/modalManager-LtDi9OJz.js +0 -2
  46. package/dist/assets/modalManager-LtDi9OJz.js. +0 -2
  47. package/dist/assets/modalManager-LtDi9OJz.js.gz +0 -0
  48. package/dist/assets/modalManager-LtDi9OJz.js.map +0 -1
  49. package/dist/assets/normalize-DWI4olFS.js +0 -2
  50. package/dist/assets/normalize-DWI4olFS.js. +0 -2
  51. package/dist/assets/normalize-DWI4olFS.js.gz +0 -0
  52. package/dist/assets/normalize-DWI4olFS.js.map +0 -1
  53. package/dist/assets/structure--7b3v7AH.js +0 -2
  54. package/dist/assets/structure--7b3v7AH.js. +0 -2
  55. package/dist/assets/structure--7b3v7AH.js.gz +0 -0
  56. package/dist/assets/structure--7b3v7AH.js.map +0 -1
  57. package/dist/assets/utils-DA-PANmk.js +0 -2
  58. package/dist/assets/utils-DA-PANmk.js.map +0 -1
  59. package/dist/bootstrap.js +0 -2
  60. package/dist/bootstrap.js.map +0 -1
  61. package/dist/main.js. +0 -3
@@ -1 +0,0 @@
1
- {"version":3,"file":"cssVariables-n9wQSSYb.js","sources":["../../src/utils/cssVariables.ts"],"sourcesContent":["/**\n * CSS Variables Utility\n *\n * Provides the CSS variable prefix for constructing variable names.\n * Uses config from @config for prefix.\n *\n * Usage:\n * import cssVariables from '@utils/cssVariables';\n * const varName = cssVariables.prefix + 'state';\n * const value = getComputedStyle(el).getPropertyValue(varName);\n * // Returns: \"--_hs---state\"\n *\n * @version 2.0.0\n */\n\nimport config from '@config';\n\nconst cssVariables = {\n prefix: config._global.cssVars.prefix,\n state: config._global.cssVars.prefix + config._global.cssVars.state.name,\n clip: config._global.cssVars.prefix + config._global.cssVars.clip.name,\n};\n\nexport default cssVariables;\n"],"names":["cssVariables","state","config","_global","cssVars","prefix","name","clip"],"mappings":"+BAiBA,MAAMA,EAAe,CAEnBC,MAAOC,EAAOC,QAAQC,QAAQC,OAASH,EAAOC,QAAQC,QAAQH,MAAMK,KACpEC,KAAML,EAAOC,QAAQC,QAAQC,OAASH,EAAOC,QAAQC,QAAQG,KAAKD"}
@@ -1,2 +0,0 @@
1
- import{c as e}from"../main.js";import{g as t,p as n,q as r,b as s,a as o,s as i,d as a,o as l,c,i as u,e as d,f}from"./modalManager-LtDi9OJz.js";import{g as p}from"./utils-DA-PANmk.js";import{c as m}from"./cssVariables-n9wQSSYb.js";async function h(){let e=null,r=null;function s(e){const r=e.target.closest('a[href^="#"]');if(!r)return;const s=r.getAttribute("href");if(!s||"#"===s)return;const o=s.substring(1),i=document.getElementById(o);if(i){e.preventDefault(),history.replaceState&&history.replaceState(null,null,`#${i.id}`);!function(e,r=0){if(!e)return;const s=t("smooth-scroll",!1);if(n()||!s){const t=e.getBoundingClientRect().top+window.scrollY-r;return window.scrollTo(0,t),e.setAttribute("tabindex","-1"),void e.focus({preventScroll:!0})}s.gsap.to(window,{duration:1,scrollTo:{y:e,offsetY:r},ease:"power2.out",onComplete:function(){e.setAttribute("tabindex","-1"),e.focus({preventScroll:!0})}})}(i,function(){const e=getComputedStyle(document.documentElement).getPropertyValue("--misc--scroll-offset").trim();return parseInt(e)||0}())}}"undefined"!=typeof $&&$(document).off("click.wf-scroll"),document.documentElement.style.scrollBehavior="auto",document.body.style.scrollBehavior="auto",e=s,r=function(e){"Enter"!==e.key&&" "!==e.key||s(e)},document.addEventListener("click",e),document.addEventListener("keydown",r);const o=t("smooth-scroll",!1);return o&&document.body.scrollHeight>window.innerHeight&&(o.gsap.set(window,{scrollTo:1}),o.gsap.set(window,{scrollTo:0})),{result:"autoInit-smooth-scroll initialized",destroy:()=>{e&&(document.removeEventListener("click",e),e=null),r&&(document.removeEventListener("keydown",r),r=null),document.documentElement.style.scrollBehavior="",document.body.style.scrollBehavior=""}}}let v=null;function g(e){v=e;const t={observers:[],handlers:[]};return function(e,t){const n=r(v,"wrapper"),l=[];n.forEach(n=>{const r=s(p.clickable,"button"),c=n.querySelector(r),u=o(v,"list",n);if(!c||!u)return void console.warn("[dropdown] Dropdown wrapper missing required elements:",n);const d=n.getAttribute("data-hs-nav-dropdown-type")||"hover",f=n.querySelector('[data-hs-height="element"]'),m=f?f.parentElement:null,h=c.textContent?.trim()||"dropdown",g=h.toLowerCase().replace(/[^a-z0-9\s]/g,"").replace(/\s+/g,"-").replace(/^-+|-+$/g,"").substring(0,50);const y=`navbar-dropdown-${g}-toggle`,b=`navbar-dropdown-${g}-list`;c.id=y,c.setAttribute("aria-haspopup","menu"),c.setAttribute("aria-expanded","false"),c.setAttribute("aria-controls",b),u.id=b,u.setAttribute("role","menu"),u.inert=!0;const w=Array.from(u.querySelectorAll(r));w.forEach((e,t)=>{if(e.setAttribute("role","menuitem"),e.setAttribute("tabindex","-1"),0===t){const t=c.textContent?.trim()||"menu";e.getAttribute("aria-label")||e.setAttribute("aria-label",`${e.textContent?.trim()}, ${t} submenu`)}});let A=-1;function E(){return n.classList.contains(p.classes.active)}function k(){const e=E();"true"===c.getAttribute("aria-expanded")&&!e&&u.contains(document.activeElement)&&c.focus(),c.setAttribute("aria-expanded",e?"true":"false"),u.inert=!e,w.forEach(t=>{t.setAttribute("tabindex",e?"0":"-1")}),e||(A=-1),a(m,e,{duration:"hover"===d?200:300,ease:"power2.inOut"})}i(m,E()),k();const L=new MutationObserver(()=>{k()});if(L.observe(n,{attributes:!0,attributeFilter:["class"]}),e(L),"hover"===d){l.push(n);const e=()=>{n.classList.add("is-active")},r=()=>{n.classList.remove("is-active")};t(n,"mouseenter",e),t(n,"mouseleave",r);t(c,"keydown",function(e){"ArrowDown"===e.key?(e.preventDefault(),E()||(n.classList.add(p.classes.active),w.length>0&&setTimeout(()=>{A=0,w[0].focus()},100))):" "===e.key||"Enter"===e.key?(e.preventDefault(),E()?n.classList.remove(p.classes.active):(n.classList.add(p.classes.active),w.length>0&&setTimeout(()=>{A=0,w[0].focus()},100))):"ArrowUp"===e.key?(e.preventDefault(),E()||(n.classList.add(p.classes.active),w.length>0&&setTimeout(()=>{A=w.length-1,w[A].focus()},100))):"Escape"===e.key&&(e.preventDefault(),E()&&n.classList.remove(p.classes.active))});t(document,"keydown",function(e){E()&&n.contains(document.activeElement)&&("ArrowDown"===e.key?(e.preventDefault(),A<w.length-1&&(A++,w[A].focus())):"ArrowUp"===e.key?(e.preventDefault(),0===A?(n.classList.remove(p.classes.active),c.focus(),A=-1):A>0?(A--,w[A].focus()):(c.focus(),A=-1)):"Escape"===e.key&&(e.preventDefault(),n.classList.remove("is-active")))})}else if("click"===d){t(c,"click",function(e){e.preventDefault(),n.classList.toggle(p.classes.active)});t(c,"keydown",function(e){" "===e.key||"Enter"===e.key?(e.preventDefault(),n.classList.toggle(p.classes.active)):"Escape"===e.key&&(e.preventDefault(),E()&&n.classList.remove(p.classes.active))})}});const c=function(e){l.forEach(t=>{t.classList.contains("is-active")&&!t.contains(e.target)&&t.classList.remove("is-active")})};l.length>0&&t(document,"focusin",c)}(e=>t.observers.push(e),(e,n,r,s)=>{e.addEventListener(n,r,s),t.handlers.push({element:e,event:n,handler:r,options:s})}),{result:"dropdown initialized",destroy:()=>{t.observers.forEach(e=>e.disconnect()),t.observers.length=0,t.handlers.forEach(({element:e,event:t,handler:n,options:r})=>{e.removeEventListener(t,n,r)}),t.handlers.length=0,v=null}}}function y(e,t){const n={observers:[],handlers:[],state:{focusTrapHandler:null}},u=e=>n.observers.push(e);return function(u,d){const f=r(e,"button"),m=o(e,"wrapper");if(!f.length||!m)return;const h=o(t,"wrapper"),v=`menu-${Date.now()}`;m.id=v,m.setAttribute("role","dialog"),m.setAttribute("aria-modal","true"),m.inert=!0;const g=m.querySelector('[data-hs-height="element"]'),y=g?g.parentElement:null;f.forEach(e=>{e.setAttribute("aria-expanded","false"),e.setAttribute("aria-controls",v),e.setAttribute("aria-label","Open navigation menu");let t=null,r=!1;function o(){return e.classList.contains(p.classes.active)}function g(){const n=o(),i="true"===e.getAttribute("aria-expanded");n&&!i?(l(),m.classList.add(p.classes.active),m.inert=!1,h&&h.classList.add("hs-menu-open"),f.forEach(e=>{e.setAttribute("aria-expanded","true"),e.setAttribute("aria-label","Close navigation menu")}),y&&a(y,!0,{duration:300,ease:"power2.inOut"}),t=function(){const e=document.querySelector('[data-hs-nav="wrapper"]');if(!e)return;const t=t=>{if("Tab"===t.key){const n=s(p.clickable,"button"),r=Array.from(e.querySelectorAll(n)),o=e.querySelectorAll('input, select, textarea, [tabindex]:not([tabindex="-1"])'),i=[...r,...Array.from(o)],a=i[0],l=i[i.length-1];t.shiftKey?document.activeElement===a&&(t.preventDefault(),l.focus()):document.activeElement===l&&(t.preventDefault(),a.focus())}};return document.addEventListener("keydown",t),t}(),r&&(setTimeout(()=>{const e=s(p.clickable,"button"),t=Array.from(m.querySelectorAll(e));if("last"===r){const e=t[t.length-1];e&&e.focus()}else{const e=t[0];e&&e.focus()}},100),r=!1)):!n&&i&&(m.contains(document.activeElement)&&e.focus(),c(),m.classList.remove(p.classes.active),m.inert=!0,h&&h.classList.remove("hs-menu-open"),f.forEach(e=>{e.setAttribute("aria-expanded","false"),e.setAttribute("aria-label","Open navigation menu")}),y&&a(y,!1,{duration:300,ease:"power2.inOut"}),function(e){e&&document.removeEventListener("keydown",e)}(t),t=null)}y&&i(y,o()),g();const b=new MutationObserver(()=>{g()});b.observe(e,{attributes:!0,attributeFilter:["class"]}),u(b);d(e,"click",function(t){t.preventDefault(),e.classList.toggle("is-active")});d(e,"keydown",function(t){" "===t.key||"Enter"===t.key?(t.preventDefault(),r=!0,e.classList.toggle(p.classes.active)):"ArrowDown"===t.key?(t.preventDefault(),o()||(r=!0,e.classList.add(p.classes.active))):"ArrowUp"===t.key?(t.preventDefault(),o()||(r="last",e.classList.add(p.classes.active))):"Escape"===t.key&&(t.preventDefault(),o()&&e.classList.remove(p.classes.active))}),n.state.focusTrapHandler=t})}(u,(e,t,r,s)=>{e.addEventListener(t,r,s),n.handlers.push({element:e,event:t,handler:r,options:s})}),function(t){const n=o(e,"wrapper");if(!n)return;let r=null;function s(){const e=window.getComputedStyle(n).getPropertyValue(m.state).trim();if(r===p.cssVars.state.values.active&&e===p.cssVars.state.values.inactive){const e=document.querySelector('[data-hs-nav-menu="button"]');e&&"true"===e.getAttribute("aria-expanded")&&e&&e.classList.remove("is-active")}r=e}const i=new ResizeObserver(s);i.observe(n),t(i),s()}(u),{result:"menu initialized",destroy:()=>{n.state.focusTrapHandler&&(document.removeEventListener("keydown",n.state.focusTrapHandler),n.state.focusTrapHandler=null),n.observers.forEach(e=>e.disconnect()),n.observers.length=0,n.handlers.forEach(({element:e,event:t,handler:n,options:r})=>{e.removeEventListener(t,n,r)}),n.handlers.length=0,document.body.classList.remove("u-overflow-hidden")}}}function b(e){const t={handlers:[]},n=(e,n,r,s)=>{e.addEventListener(n,r,s),t.handlers.push({element:e,event:n,handler:r,options:s})};return n(document,"keydown",function(e){if("ArrowLeft"!==e.key&&"ArrowRight"!==e.key)return;const t=document.querySelector('[data-hs-nav-menu="wrapper"]');if(t&&t.contains(document.activeElement))return;const n=document.querySelector('[data-hs-nav="wrapper"]');if(!n||!n.contains(document.activeElement))return;const r=n.querySelector(`.${p.classes.active}[data-hs-nav-dropdown]`);if(r&&r.contains(document.activeElement))return;e.preventDefault();const o=s(p.clickable,"button"),i=Array.from(n.querySelectorAll(o)),a=Array.from(i).filter(e=>{if("-1"===e.getAttribute("tabindex"))return!1;if(e.closest('[role="menu"]'))return!1;if(e.closest('[data-hs-nav-menu="wrapper"]'))return!1;if(e.closest('[data-hs-nav="skip-link"]'))return!1;const t=window.getComputedStyle(e);if("none"===t.display||"hidden"===t.visibility||"0"===t.opacity||0===e.offsetWidth||0===e.offsetHeight)return!1;let r=e.parentElement;for(;r&&r!==n;){const e=window.getComputedStyle(r);if("none"===e.display||"hidden"===e.visibility||0===r.offsetWidth||0===r.offsetHeight)return!1;r=r.parentElement}return!0}),l=a.indexOf(document.activeElement);-1!==l&&("ArrowRight"===e.key?l<a.length-1&&a[l+1].focus():l>0&&a[l-1].focus())}),function(e){const t=document.querySelector('[data-hs-nav-menu="wrapper"]');if(!t)return;let n=-1;e(t,"keydown",function(e){const r=function(){const e=s(p.clickable,"button"),n=Array.from(t.querySelectorAll(e));return Array.from(n).filter(e=>{let n=e;for(;n&&n!==t;){if(n.inert)return!1;n=n.parentElement}return!0})}();if(0===r.length)return;const o=document.activeElement;if(n=r.indexOf(o),"ArrowDown"===e.key)e.preventDefault(),n<r.length-1&&(n+=1,r[n].focus());else if("ArrowUp"===e.key)e.preventDefault(),n>0&&(n-=1,r[n].focus());else if("ArrowRight"===e.key){if(e.preventDefault(),"BUTTON"===o.tagName&&o.hasAttribute("aria-controls")){return void("true"===o.getAttribute("aria-expanded")||o.click())}}else if("ArrowLeft"===e.key){if(e.preventDefault(),"BUTTON"===o.tagName&&o.hasAttribute("aria-controls")){return void("true"===o.getAttribute("aria-expanded")&&o.click())}}else if("Home"===e.key)e.preventDefault(),n=0,r[0].focus();else if("End"===e.key)e.preventDefault(),n=r.length-1,r[r.length-1].focus();else if(" "===e.key&&"A"===o.tagName)e.preventDefault();else if("Escape"===e.key){const e=document.querySelector('[data-hs-nav-menu="button"]');e&&(e.click(),e.focus())}})}(n),{result:"arrow-navigation initialized",destroy:()=>{t.handlers.forEach(({element:e,event:t,handler:n,options:r})=>{e.removeEventListener(t,n,r)}),t.handlers.length=0}}}async function w(e){const t={destroyFunctions:[]},n=await Promise.allSettled([g(e.dropdown),y(e.menu,e),b(e["arrow-navigation"])]);n.forEach(e=>{"fulfilled"===e.status&&e.value?.destroy&&t.destroyFunctions.push(e.value.destroy)});const r=n.filter(e=>"fulfilled"===e.status).length,s=n.length-r;return s>0&&console.warn(`[navbar] ${r}/${n.length} functions loaded successfully. ${s} failed but won't affect other functions.`),{result:"navbar initialized",destroy:()=>{t.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[navbar] Error during cleanup:",t)}}),t.destroyFunctions.length=0}}}async function A(){const e={modules:{},destroyFunctions:[]},t={},n=Object.keys(t).map(n=>(async n=>{try{const{init:r}=await t[n](),s=await r();return e.modules[n]=s,s&&s.destroy&&e.destroyFunctions.push(s.destroy),s}catch(r){return console.error(`[accessibility] Failed to load function: ${n}`,r),null}})(n)),r=await Promise.allSettled(n),s=r.filter(e=>"fulfilled"===e.status&&e.value).length,o=r.length-s;return o>0&&console.warn(`[accessibility] ${s}/${r.length} functions loaded successfully. ${o} failed but won't affect other functions.`),{result:"accessibility initialized (no functions loaded)",destroy:()=>{e.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("Error during accessibility cleanup:",t)}}),e.destroyFunctions.length=0,e.modules={}}}}function E(e){const t={observers:[],handlers:[],liveRegions:[]};return function(n,l){const c=r(e,"wrapper");if(0===c.length)return 0;let u=0;c.forEach((r,c)=>{const d=o(e,"toggle",r),f=o(e,"content",r);if(!d||!f)return;u++;const m=r.querySelector('[data-hs-height="element"]'),h=m?m.parentElement:f,v=`hs-accordion-btn-${c}`,g=`hs-accordion-content-${c}`,y=document.createElement("div");y.className="sr-only",y.setAttribute("aria-live","polite"),y.setAttribute("aria-atomic","true"),y.style.cssText="position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden;",r.appendChild(y),t.liveRegions.push(y);const b=r.getAttribute(e.attributes.properties.open),w=r.getAttribute(e.attributes.properties.closed),A=b&&w;let E=[];if(A){const t=s(e,"state");E=Array.from(d.querySelectorAll(t))}function k(){return r.classList.contains(p.classes.active)}function L(){const e=k(),t="true"===d.getAttribute("aria-expanded");if(t&&!e&&f.contains(document.activeElement)){d.focus()}d.setAttribute("aria-expanded",e?"true":"false");var n;f.inert=!e,e!==t&&function(e){const t=d.textContent?.trim()||"Section";y.textContent=`${t} ${e?"expanded":"collapsed"}`,setTimeout(()=>y.textContent="",1e3)}(e),A&&E.length>0&&(n=e?b:w,A&&E.forEach(e=>{e.textContent=n})),a(h,e,{duration:300,ease:"power2.inOut"})}d.setAttribute("id",v),f.setAttribute("id",g),f.setAttribute("role","region"),f.setAttribute("aria-labelledby",v),d.setAttribute("aria-controls",g);const x=r.getAttribute(e.attributes.properties.default);x&&"open"===x.toLowerCase()&&r.classList.add(p.classes.active),i(h,k()),L();l(d,"click",e=>{e.preventDefault(),r.classList.toggle(p.classes.active)});const S=new MutationObserver(()=>{L()});S.observe(r,{attributes:!0,attributeFilter:["class"]}),n(S)})}(e=>t.observers.push(e),(e,n,r,s)=>{e.addEventListener(n,r,s),t.handlers.push({element:e,event:n,handler:r,options:s})}),{result:"accordion initialized",destroy:()=>{t.liveRegions.forEach(e=>{e.parentNode&&e.parentNode.removeChild(e)}),t.liveRegions.length=0,t.observers.forEach(e=>e.disconnect()),t.observers.length=0,t.handlers.forEach(({element:e,event:t,handler:n,options:r})=>{e.removeEventListener(t,n,r)}),t.handlers.length=0}}}async function k(e){const n=t("comparison");if(!n)return{result:"comparison skipped - GSAP not loaded"};const{gsap:i,Draggable:a}=n;a||console.warn("[comparison] GSAP Draggable plugin not loaded, drag functionality disabled");const l=r(e,"wrapper"),c={draggables:[],handlers:[]},u=s(e,"template-name"),d=s(e,"template-description"),f=s(e,"template-before-image"),h=s(e,"template-after-image");function v(e,t){e.style.setProperty(m.clip,`${t}%`)}function g(t,n){const r=t.templateItems[n];if(!r)return;const s=r.querySelector(u);t.nameElement&&s&&(t.nameElement.textContent=s.textContent);const i=r.querySelector(d);t.descElement&&i&&(t.descElement.textContent=i.textContent);const a=r.querySelector(f);t.beforeImage&&a&&(t.beforeImage.src=a.src,t.beforeImage.alt=a.alt||"");const l=r.querySelector(h);t.afterImage&&l&&(t.afterImage.src=l.src,t.afterImage.alt=l.alt||"",y(t)),t.currentIndex=n,function(t,n){const r=o(e,"pagination",t);if(!r)return;const s=p.classes.active;Array.from(r.children).forEach((e,t)=>{t===n?e.classList.add(s):e.classList.remove(s)})}(t.wrapper,n)}function y(e){const t=e.slider,n=e.wrapper;switch(e.mode){case"before":n.style.setProperty(m.clip,"100%"),t.style.display="none";break;case"after":n.style.setProperty(m.clip,"0%"),t.style.display="none";break;case"split":v(n,e.sliderPosition),t.style.display="flex"}}function b(e,t){const n=e.currentIndex+t,r=e.templateItems.length-1;let s;s=n>r?0:n<0?r:n,g(e,s)}return l.forEach(t=>{const n=o(e,"template-list",t);if(!n)return void console.warn("[comparison] No template list found in wrapper");const r=s(e,"template-item"),l=Array.from(n.querySelectorAll(r));if(0===l.length)return void console.warn("[comparison] No template items found");t.setAttribute("aria-live","polite"),t.setAttribute("aria-label","Before and after image comparison");const u=o(e,"image-wrapper",t),d=o(e,"slider",t),f=o(e,"before-image",t),m=o(e,"after-image",t),h=o(e,"name",t),w=o(e,"description",t);if(!u||!d||!m){const e=[];return u||e.push('image-wrapper (data-hs-comparison="image-wrapper")'),d||e.push('slider (data-hs-comparison="slider")'),m||e.push('after-image (data-hs-comparison-image="after")'),void console.warn(`[comparison] Missing required elements: ${e.join(", ")}`)}const A={wrapper:t,templateItems:l,currentIndex:0,mode:"split",sliderPosition:50,slider:d,beforeImage:f?.querySelector("img"),afterImage:m?.querySelector("img"),nameElement:h,descElement:w,draggable:null};if(g(A,0),v(t,50),a){const e=a.create(d,{type:"x",bounds:u,onDrag:function(){const e=u.getBoundingClientRect(),n=d.getBoundingClientRect().left-e.left,r=Math.max(0,Math.min(100,n/e.width*100));v(t,r),A.sliderPosition=r}});c.draggables.push(e),A.draggable=e[0];const n=e=>{if("split"!==A.mode)return;const n=u.getBoundingClientRect(),r=e.clientX-n.left,s=Math.max(0,Math.min(100,r/n.width*100)),o=r-n.width/2;A.draggable&&(i.set(d,{x:o}),A.draggable.update()),v(t,s),A.sliderPosition=s};u.addEventListener("click",n),c.handlers.push({element:u,event:"click",handler:n})}t.querySelectorAll(`[${e.attributes.properties.modeType}]`).forEach(t=>{const n=t.getAttribute(e.attributes.properties.modeType),r=s(p.clickable,"button"),o=t.querySelector(r)||t;n===A.mode&&t.classList.add(p.classes.active);const i=t=>{t.preventDefault(),function(t,n){const r=t.wrapper.querySelectorAll(`[${e.attributes.properties.modeType}]`),s=p.classes.active;r.forEach(t=>{t.getAttribute(e.attributes.properties.modeType)===n?t.classList.add(s):t.classList.remove(s)}),t.mode=n,y(t)}(A,n)};o.addEventListener("click",i),c.handlers.push({element:o,event:"click",handler:i})}),function(t,n){const r=n.querySelector(`[${e.attributes.properties.navType}="previous"]`),o=n.querySelector(`[${e.attributes.properties.navType}="next"]`);if(r){const e=s(p.clickable,"button"),n=r.querySelector(e)||r;n.setAttribute("aria-label","Previous image");const o=e=>{e.preventDefault(),b(t,-1)};n.addEventListener("click",o),c.handlers.push({element:n,event:"click",handler:o})}if(o){const e=s(p.clickable,"button"),n=o.querySelector(e)||o;n.setAttribute("aria-label","Next image");const r=e=>{e.preventDefault(),b(t,1)};n.addEventListener("click",r),c.handlers.push({element:n,event:"click",handler:r})}}(A,t);const E=o(e,"pagination",t);E&&l.length>1&&function(e,t){const n=t.children[0];if(!n)return;const r=p.classes.active;t.innerHTML="",e.templateItems.forEach((s,o)=>{const i=n.cloneNode(!0);i.classList.remove(r),0===o&&i.classList.add(r);const a=()=>{g(e,o)};i.addEventListener("click",a),c.handlers.push({element:i,event:"click",handler:a}),t.appendChild(i)})}(A,E),function(e){const t=t=>{"ArrowLeft"===t.key||"ArrowUp"===t.key?(t.preventDefault(),b(e,-1)):"ArrowRight"!==t.key&&"ArrowDown"!==t.key||(t.preventDefault(),b(e,1))};e.wrapper.addEventListener("keydown",t),e.wrapper.setAttribute("tabindex","0"),c.handlers.push({element:e.wrapper,event:"keydown",handler:t})}(A)}),{result:`comparison initialized (${l.length} instances)`,destroy:()=>{c.draggables.forEach(e=>{e&&e[0]&&e[0].kill&&e[0].kill()}),c.handlers.forEach(({element:e,event:t,handler:n})=>{e.removeEventListener(t,n)}),c.draggables.length=0,c.handlers.length=0}}}async function L(e){if(n())return{result:"marquee skipped - prefers-reduced-motion enabled"};const s=t("marquee");if(!s)return{result:"marquee skipped - GSAP not loaded"};const{gsap:o,ScrollTrigger:i}=s;i&&o.registerPlugin(i),u();const a=r(e,"wrapper"),l={timelines:[],scrollTriggers:[],tickers:[]};return a.forEach(t=>{const n=t.getAttribute(e.attributes.properties.direction),r=Array.from(t.children);if(0===r.length)return void console.warn("[marquee] No children found in marquee wrapper:",t);const s=t.getAttribute(e.attributes.properties.duration),i=s?parseFloat(s):parseFloat(e.defaults.duration),a=t.getAttribute(e.attributes.properties.scrollMultiplier),c=a?parseFloat(a):parseFloat(e.defaults.scrollMultiplier),u=t.getAttribute(e.attributes.properties.type);s||t.setAttribute(e.attributes.properties.duration,e.defaults.duration),a||t.setAttribute(e.attributes.properties.scrollMultiplier,e.defaults.scrollMultiplier),t.classList.add(p.classes.gsap);const m=o.timeline({repeat:-1});if(r.forEach(e=>{"left"===n?m.to(e,{xPercent:-100,duration:i,ease:"none"},0):"right"===n&&(o.set(e,{xPercent:-100}),m.to(e,{xPercent:0,duration:i,ease:"none"},0))}),l.timelines.push(m),c>0){let e=1;const t=()=>{const t=f(),n=d();let r=1;if("reverse"===u)if(1===n)r=1+t*c;else if(-1===n){const e=t*c;r=e>.5?-e:1}else r=1;else{r=1+t*c}Math.abs(r-e)>.001&&(m.timeScale(r),e=r)};o.ticker.add(t),l.tickers.push({tickerFunc:t,gsap:o})}}),{result:`marquee initialized (${a.length} instances)`,destroy:()=>{l.timelines.forEach(e=>{e&&e.kill()}),l.scrollTriggers.forEach(e=>{e&&e.kill()}),l.tickers.forEach(({tickerFunc:e,gsap:t})=>{t.ticker.remove(e)}),a.forEach(e=>{e.classList.remove(p.classes.gsap)}),l.timelines.length=0,l.scrollTriggers.length=0,l.tickers.length=0}}}const x=p.apiName;async function S(){const t={destroyFunctions:[]},n=e.default,s=[h(),w(n.navbar),A(),E(n.accordion),k(n.comparison),L(n.marquee)],i=(async()=>(await new Promise(e=>setTimeout(e,50)),async function(t){const n=t||e.default?.transition,s=o(n,"element");if(!s)return console.log("[transition] No transition element found, skipping initialization"),{result:"transition skipped - no element found",destroy:()=>{}};const i=n.attributes.elements.namespace.primary,a=s.getAttribute(i)||null,l=window[x]?.settings?.isSPA||!1,c=new Map;let u=null;const d=(e,t)=>{const s=r(n,"exit"===e?"exitTrigger":"enterTrigger");if(s.length>0){if(t){const e=Array.from(s).find(e=>e.getAttribute(i)===t);if(e)return e}return Array.from(s).find(e=>!e.hasAttribute(i))||s[0]}const o=document.querySelectorAll('[data-hs-transition="trigger"]');if(o.length>0){if(t){const e=Array.from(o).find(e=>e.getAttribute(i)===t);if(e)return e}return o[0]}return null},f=(e,t,r)=>{if(!e)return 0;const o="exit"===r?"time"===t?n.attributes.elements.exitTime.primary:n.attributes.elements.exitDelay.primary:"time"===t?n.attributes.elements.enterTime.primary:n.attributes.elements.enterDelay.primary;let i=e.getAttribute(o);return i||"exit"===r&&"time"===t&&(i=s.getAttribute("data-hs-exit-time"),i)||"enter"===r&&"delay"===t&&(i=s.getAttribute("data-hs-delay"),i)?1e3*parseFloat(i):0},p=(e=a)=>new Promise(t=>{const n=d("exit",e);if(!n)return void t();const r=f(n,"time","exit"),s=f(n,"delay","exit"),o=()=>{"undefined"!=typeof Webflow?Webflow.push(()=>{n.click()}):n.click(),setTimeout(t,r)};s>0?setTimeout(o,s):o()}),m=(e=a)=>new Promise(t=>{const n=d("enter",e);if(!n)return void t();const r=f(n,"time","enter"),s=f(n,"delay","enter"),o=!sessionStorage.getItem("transition-loaded"),i=()=>{"undefined"!=typeof Webflow?Webflow.push(()=>{n.click()}):n.click(),o&&sessionStorage.setItem("transition-loaded","true"),setTimeout(t,r)};o&&s>0?u=setTimeout(i,s):i()}),h=()=>p(),v=()=>m();if(c.set("hsmain:transition-exit",h),c.set("hsmain:transition-enter",v),window.addEventListener("hsmain:transition-exit",h),window.addEventListener("hsmain:transition-enter",v),!l){const e=e=>{const t=e.target.closest("a[href]");if(t&&t.hostname===window.location.hostname&&t.getAttribute("href")&&-1===t.getAttribute("href").indexOf("#")&&"_blank"!==t.getAttribute("target")){e.preventDefault();const n=t.href;p().then(()=>{window.location.href=n})}};c.set("click",e),document.addEventListener("click",e);const t=e=>{e.persisted&&window.location.reload()};c.set("pageshow",t),window.addEventListener("pageshow",t)}const g=()=>{s&&(s.style.display="none")};c.set("resize",g),window.addEventListener("resize",g);const y=()=>{m()};return c.set(`${x}:dom-ready`,y),window.addEventListener(`${x}:dom-ready`,y,{once:!0}),{result:"transition initialized",destroy:()=>{u&&clearTimeout(u),c.forEach((e,t)=>{"click"===t||"pageshow"===t||"resize"===t?("click"===t?document:window).removeEventListener(t,e):window.removeEventListener(t,e)}),c.clear()}}}(n.transition)))(),a=await Promise.allSettled([...s,i]);a.forEach(e=>{"fulfilled"===e.status&&e.value?.destroy&&t.destroyFunctions.push(e.value.destroy)});const l=a.filter(e=>"fulfilled"===e.status).length,c=a.length-l;return c>0&&console.warn(`[default] ${l}/${a.length} functions loaded successfully. ${c} failed but won't affect other functions.`),{result:"default initialized",destroy:()=>{t.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[default] Error during cleanup:",t)}}),t.destroyFunctions.length=0}}}export{S as init};
2
- //# sourceMappingURL=default-CZ6vle49.js.map
@@ -1,2 +0,0 @@
1
- import{c as e}from"../main.js";import{g as t,p as n,q as r,b as s,a as o,s as i,d as a,o as l,c,i as u,e as d,f}from"./modalManager-LtDi9OJz.js";import{g as p}from"./utils-DA-PANmk.js";import{c as m}from"./cssVariables-n9wQSSYb.js";async function h(){let e=null,r=null;function s(e){const r=e.target.closest('a[href^="#"]');if(!r)return;const s=r.getAttribute("href");if(!s||"#"===s)return;const o=s.substring(1),i=document.getElementById(o);if(i){e.preventDefault(),history.replaceState&&history.replaceState(null,null,`#${i.id}`);!function(e,r=0){if(!e)return;const s=t("smooth-scroll",!1);if(n()||!s){const t=e.getBoundingClientRect().top+window.scrollY-r;return window.scrollTo(0,t),e.setAttribute("tabindex","-1"),void e.focus({preventScroll:!0})}s.gsap.to(window,{duration:1,scrollTo:{y:e,offsetY:r},ease:"power2.out",onComplete:function(){e.setAttribute("tabindex","-1"),e.focus({preventScroll:!0})}})}(i,function(){const e=getComputedStyle(document.documentElement).getPropertyValue("--misc--scroll-offset").trim();return parseInt(e)||0}())}}"undefined"!=typeof $&&$(document).off("click.wf-scroll"),document.documentElement.style.scrollBehavior="auto",document.body.style.scrollBehavior="auto",e=s,r=function(e){"Enter"!==e.key&&" "!==e.key||s(e)},document.addEventListener("click",e),document.addEventListener("keydown",r);const o=t("smooth-scroll",!1);return o&&document.body.scrollHeight>window.innerHeight&&(o.gsap.set(window,{scrollTo:1}),o.gsap.set(window,{scrollTo:0})),{result:"autoInit-smooth-scroll initialized",destroy:()=>{e&&(document.removeEventListener("click",e),e=null),r&&(document.removeEventListener("keydown",r),r=null),document.documentElement.style.scrollBehavior="",document.body.style.scrollBehavior=""}}}let v=null;function g(e){v=e;const t={observers:[],handlers:[]};return function(e,t){const n=r(v,"wrapper"),l=[];n.forEach(n=>{const r=s(p.clickable,"button"),c=n.querySelector(r),u=o(v,"list",n);if(!c||!u)return void console.warn("[dropdown] Dropdown wrapper missing required elements:",n);const d=n.getAttribute("data-hs-nav-dropdown-type")||"hover",f=n.querySelector('[data-hs-height="element"]'),m=f?f.parentElement:null,h=c.textContent?.trim()||"dropdown",g=h.toLowerCase().replace(/[^a-z0-9\s]/g,"").replace(/\s+/g,"-").replace(/^-+|-+$/g,"").substring(0,50);const y=`navbar-dropdown-${g}-toggle`,b=`navbar-dropdown-${g}-list`;c.id=y,c.setAttribute("aria-haspopup","menu"),c.setAttribute("aria-expanded","false"),c.setAttribute("aria-controls",b),u.id=b,u.setAttribute("role","menu"),u.inert=!0;const w=Array.from(u.querySelectorAll(r));w.forEach((e,t)=>{if(e.setAttribute("role","menuitem"),e.setAttribute("tabindex","-1"),0===t){const t=c.textContent?.trim()||"menu";e.getAttribute("aria-label")||e.setAttribute("aria-label",`${e.textContent?.trim()}, ${t} submenu`)}});let A=-1;function E(){return n.classList.contains(p.classes.active)}function k(){const e=E();"true"===c.getAttribute("aria-expanded")&&!e&&u.contains(document.activeElement)&&c.focus(),c.setAttribute("aria-expanded",e?"true":"false"),u.inert=!e,w.forEach(t=>{t.setAttribute("tabindex",e?"0":"-1")}),e||(A=-1),a(m,e,{duration:"hover"===d?200:300,ease:"power2.inOut"})}i(m,E()),k();const L=new MutationObserver(()=>{k()});if(L.observe(n,{attributes:!0,attributeFilter:["class"]}),e(L),"hover"===d){l.push(n);const e=()=>{n.classList.add("is-active")},r=()=>{n.classList.remove("is-active")};t(n,"mouseenter",e),t(n,"mouseleave",r);t(c,"keydown",function(e){"ArrowDown"===e.key?(e.preventDefault(),E()||(n.classList.add(p.classes.active),w.length>0&&setTimeout(()=>{A=0,w[0].focus()},100))):" "===e.key||"Enter"===e.key?(e.preventDefault(),E()?n.classList.remove(p.classes.active):(n.classList.add(p.classes.active),w.length>0&&setTimeout(()=>{A=0,w[0].focus()},100))):"ArrowUp"===e.key?(e.preventDefault(),E()||(n.classList.add(p.classes.active),w.length>0&&setTimeout(()=>{A=w.length-1,w[A].focus()},100))):"Escape"===e.key&&(e.preventDefault(),E()&&n.classList.remove(p.classes.active))});t(document,"keydown",function(e){E()&&n.contains(document.activeElement)&&("ArrowDown"===e.key?(e.preventDefault(),A<w.length-1&&(A++,w[A].focus())):"ArrowUp"===e.key?(e.preventDefault(),0===A?(n.classList.remove(p.classes.active),c.focus(),A=-1):A>0?(A--,w[A].focus()):(c.focus(),A=-1)):"Escape"===e.key&&(e.preventDefault(),n.classList.remove("is-active")))})}else if("click"===d){t(c,"click",function(e){e.preventDefault(),n.classList.toggle(p.classes.active)});t(c,"keydown",function(e){" "===e.key||"Enter"===e.key?(e.preventDefault(),n.classList.toggle(p.classes.active)):"Escape"===e.key&&(e.preventDefault(),E()&&n.classList.remove(p.classes.active))})}});const c=function(e){l.forEach(t=>{t.classList.contains("is-active")&&!t.contains(e.target)&&t.classList.remove("is-active")})};l.length>0&&t(document,"focusin",c)}(e=>t.observers.push(e),(e,n,r,s)=>{e.addEventListener(n,r,s),t.handlers.push({element:e,event:n,handler:r,options:s})}),{result:"dropdown initialized",destroy:()=>{t.observers.forEach(e=>e.disconnect()),t.observers.length=0,t.handlers.forEach(({element:e,event:t,handler:n,options:r})=>{e.removeEventListener(t,n,r)}),t.handlers.length=0,v=null}}}function y(e,t){const n={observers:[],handlers:[],state:{focusTrapHandler:null}},u=e=>n.observers.push(e);return function(u,d){const f=r(e,"button"),m=o(e,"wrapper");if(!f.length||!m)return;const h=o(t,"wrapper"),v=`menu-${Date.now()}`;m.id=v,m.setAttribute("role","dialog"),m.setAttribute("aria-modal","true"),m.inert=!0;const g=m.querySelector('[data-hs-height="element"]'),y=g?g.parentElement:null;f.forEach(e=>{e.setAttribute("aria-expanded","false"),e.setAttribute("aria-controls",v),e.setAttribute("aria-label","Open navigation menu");let t=null,r=!1;function o(){return e.classList.contains(p.classes.active)}function g(){const n=o(),i="true"===e.getAttribute("aria-expanded");n&&!i?(l(),m.classList.add(p.classes.active),m.inert=!1,h&&h.classList.add("hs-menu-open"),f.forEach(e=>{e.setAttribute("aria-expanded","true"),e.setAttribute("aria-label","Close navigation menu")}),y&&a(y,!0,{duration:300,ease:"power2.inOut"}),t=function(){const e=document.querySelector('[data-hs-nav="wrapper"]');if(!e)return;const t=t=>{if("Tab"===t.key){const n=s(p.clickable,"button"),r=Array.from(e.querySelectorAll(n)),o=e.querySelectorAll('input, select, textarea, [tabindex]:not([tabindex="-1"])'),i=[...r,...Array.from(o)],a=i[0],l=i[i.length-1];t.shiftKey?document.activeElement===a&&(t.preventDefault(),l.focus()):document.activeElement===l&&(t.preventDefault(),a.focus())}};return document.addEventListener("keydown",t),t}(),r&&(setTimeout(()=>{const e=s(p.clickable,"button"),t=Array.from(m.querySelectorAll(e));if("last"===r){const e=t[t.length-1];e&&e.focus()}else{const e=t[0];e&&e.focus()}},100),r=!1)):!n&&i&&(m.contains(document.activeElement)&&e.focus(),c(),m.classList.remove(p.classes.active),m.inert=!0,h&&h.classList.remove("hs-menu-open"),f.forEach(e=>{e.setAttribute("aria-expanded","false"),e.setAttribute("aria-label","Open navigation menu")}),y&&a(y,!1,{duration:300,ease:"power2.inOut"}),function(e){e&&document.removeEventListener("keydown",e)}(t),t=null)}y&&i(y,o()),g();const b=new MutationObserver(()=>{g()});b.observe(e,{attributes:!0,attributeFilter:["class"]}),u(b);d(e,"click",function(t){t.preventDefault(),e.classList.toggle("is-active")});d(e,"keydown",function(t){" "===t.key||"Enter"===t.key?(t.preventDefault(),r=!0,e.classList.toggle(p.classes.active)):"ArrowDown"===t.key?(t.preventDefault(),o()||(r=!0,e.classList.add(p.classes.active))):"ArrowUp"===t.key?(t.preventDefault(),o()||(r="last",e.classList.add(p.classes.active))):"Escape"===t.key&&(t.preventDefault(),o()&&e.classList.remove(p.classes.active))}),n.state.focusTrapHandler=t})}(u,(e,t,r,s)=>{e.addEventListener(t,r,s),n.handlers.push({element:e,event:t,handler:r,options:s})}),function(t){const n=o(e,"wrapper");if(!n)return;let r=null;function s(){const e=window.getComputedStyle(n).getPropertyValue(m.state).trim();if(r===p.cssVars.state.values.active&&e===p.cssVars.state.values.inactive){const e=document.querySelector('[data-hs-nav-menu="button"]');e&&"true"===e.getAttribute("aria-expanded")&&e&&e.classList.remove("is-active")}r=e}const i=new ResizeObserver(s);i.observe(n),t(i),s()}(u),{result:"menu initialized",destroy:()=>{n.state.focusTrapHandler&&(document.removeEventListener("keydown",n.state.focusTrapHandler),n.state.focusTrapHandler=null),n.observers.forEach(e=>e.disconnect()),n.observers.length=0,n.handlers.forEach(({element:e,event:t,handler:n,options:r})=>{e.removeEventListener(t,n,r)}),n.handlers.length=0,document.body.classList.remove("u-overflow-hidden")}}}function b(e){const t={handlers:[]},n=(e,n,r,s)=>{e.addEventListener(n,r,s),t.handlers.push({element:e,event:n,handler:r,options:s})};return n(document,"keydown",function(e){if("ArrowLeft"!==e.key&&"ArrowRight"!==e.key)return;const t=document.querySelector('[data-hs-nav-menu="wrapper"]');if(t&&t.contains(document.activeElement))return;const n=document.querySelector('[data-hs-nav="wrapper"]');if(!n||!n.contains(document.activeElement))return;const r=n.querySelector(`.${p.classes.active}[data-hs-nav-dropdown]`);if(r&&r.contains(document.activeElement))return;e.preventDefault();const o=s(p.clickable,"button"),i=Array.from(n.querySelectorAll(o)),a=Array.from(i).filter(e=>{if("-1"===e.getAttribute("tabindex"))return!1;if(e.closest('[role="menu"]'))return!1;if(e.closest('[data-hs-nav-menu="wrapper"]'))return!1;if(e.closest('[data-hs-nav="skip-link"]'))return!1;const t=window.getComputedStyle(e);if("none"===t.display||"hidden"===t.visibility||"0"===t.opacity||0===e.offsetWidth||0===e.offsetHeight)return!1;let r=e.parentElement;for(;r&&r!==n;){const e=window.getComputedStyle(r);if("none"===e.display||"hidden"===e.visibility||0===r.offsetWidth||0===r.offsetHeight)return!1;r=r.parentElement}return!0}),l=a.indexOf(document.activeElement);-1!==l&&("ArrowRight"===e.key?l<a.length-1&&a[l+1].focus():l>0&&a[l-1].focus())}),function(e){const t=document.querySelector('[data-hs-nav-menu="wrapper"]');if(!t)return;let n=-1;e(t,"keydown",function(e){const r=function(){const e=s(p.clickable,"button"),n=Array.from(t.querySelectorAll(e));return Array.from(n).filter(e=>{let n=e;for(;n&&n!==t;){if(n.inert)return!1;n=n.parentElement}return!0})}();if(0===r.length)return;const o=document.activeElement;if(n=r.indexOf(o),"ArrowDown"===e.key)e.preventDefault(),n<r.length-1&&(n+=1,r[n].focus());else if("ArrowUp"===e.key)e.preventDefault(),n>0&&(n-=1,r[n].focus());else if("ArrowRight"===e.key){if(e.preventDefault(),"BUTTON"===o.tagName&&o.hasAttribute("aria-controls")){return void("true"===o.getAttribute("aria-expanded")||o.click())}}else if("ArrowLeft"===e.key){if(e.preventDefault(),"BUTTON"===o.tagName&&o.hasAttribute("aria-controls")){return void("true"===o.getAttribute("aria-expanded")&&o.click())}}else if("Home"===e.key)e.preventDefault(),n=0,r[0].focus();else if("End"===e.key)e.preventDefault(),n=r.length-1,r[r.length-1].focus();else if(" "===e.key&&"A"===o.tagName)e.preventDefault();else if("Escape"===e.key){const e=document.querySelector('[data-hs-nav-menu="button"]');e&&(e.click(),e.focus())}})}(n),{result:"arrow-navigation initialized",destroy:()=>{t.handlers.forEach(({element:e,event:t,handler:n,options:r})=>{e.removeEventListener(t,n,r)}),t.handlers.length=0}}}async function w(e){const t={destroyFunctions:[]},n=await Promise.allSettled([g(e.dropdown),y(e.menu,e),b(e["arrow-navigation"])]);n.forEach(e=>{"fulfilled"===e.status&&e.value?.destroy&&t.destroyFunctions.push(e.value.destroy)});const r=n.filter(e=>"fulfilled"===e.status).length,s=n.length-r;return s>0&&console.warn(`[navbar] ${r}/${n.length} functions loaded successfully. ${s} failed but won't affect other functions.`),{result:"navbar initialized",destroy:()=>{t.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[navbar] Error during cleanup:",t)}}),t.destroyFunctions.length=0}}}async function A(){const e={modules:{},destroyFunctions:[]},t={},n=Object.keys(t).map(n=>(async n=>{try{const{init:r}=await t[n](),s=await r();return e.modules[n]=s,s&&s.destroy&&e.destroyFunctions.push(s.destroy),s}catch(r){return console.error(`[accessibility] Failed to load function: ${n}`,r),null}})(n)),r=await Promise.allSettled(n),s=r.filter(e=>"fulfilled"===e.status&&e.value).length,o=r.length-s;return o>0&&console.warn(`[accessibility] ${s}/${r.length} functions loaded successfully. ${o} failed but won't affect other functions.`),{result:"accessibility initialized (no functions loaded)",destroy:()=>{e.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("Error during accessibility cleanup:",t)}}),e.destroyFunctions.length=0,e.modules={}}}}function E(e){const t={observers:[],handlers:[],liveRegions:[]};return function(n,l){const c=r(e,"wrapper");if(0===c.length)return 0;let u=0;c.forEach((r,c)=>{const d=o(e,"toggle",r),f=o(e,"content",r);if(!d||!f)return;u++;const m=r.querySelector('[data-hs-height="element"]'),h=m?m.parentElement:f,v=`hs-accordion-btn-${c}`,g=`hs-accordion-content-${c}`,y=document.createElement("div");y.className="sr-only",y.setAttribute("aria-live","polite"),y.setAttribute("aria-atomic","true"),y.style.cssText="position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden;",r.appendChild(y),t.liveRegions.push(y);const b=r.getAttribute(e.attributes.properties.open),w=r.getAttribute(e.attributes.properties.closed),A=b&&w;let E=[];if(A){const t=s(e,"state");E=Array.from(d.querySelectorAll(t))}function k(){return r.classList.contains(p.classes.active)}function L(){const e=k(),t="true"===d.getAttribute("aria-expanded");if(t&&!e&&f.contains(document.activeElement)){d.focus()}d.setAttribute("aria-expanded",e?"true":"false");var n;f.inert=!e,e!==t&&function(e){const t=d.textContent?.trim()||"Section";y.textContent=`${t} ${e?"expanded":"collapsed"}`,setTimeout(()=>y.textContent="",1e3)}(e),A&&E.length>0&&(n=e?b:w,A&&E.forEach(e=>{e.textContent=n})),a(h,e,{duration:300,ease:"power2.inOut"})}d.setAttribute("id",v),f.setAttribute("id",g),f.setAttribute("role","region"),f.setAttribute("aria-labelledby",v),d.setAttribute("aria-controls",g);const x=r.getAttribute(e.attributes.properties.default);x&&"open"===x.toLowerCase()&&r.classList.add(p.classes.active),i(h,k()),L();l(d,"click",e=>{e.preventDefault(),r.classList.toggle(p.classes.active)});const S=new MutationObserver(()=>{L()});S.observe(r,{attributes:!0,attributeFilter:["class"]}),n(S)})}(e=>t.observers.push(e),(e,n,r,s)=>{e.addEventListener(n,r,s),t.handlers.push({element:e,event:n,handler:r,options:s})}),{result:"accordion initialized",destroy:()=>{t.liveRegions.forEach(e=>{e.parentNode&&e.parentNode.removeChild(e)}),t.liveRegions.length=0,t.observers.forEach(e=>e.disconnect()),t.observers.length=0,t.handlers.forEach(({element:e,event:t,handler:n,options:r})=>{e.removeEventListener(t,n,r)}),t.handlers.length=0}}}async function k(e){const n=t("comparison");if(!n)return{result:"comparison skipped - GSAP not loaded"};const{gsap:i,Draggable:a}=n;a||console.warn("[comparison] GSAP Draggable plugin not loaded, drag functionality disabled");const l=r(e,"wrapper"),c={draggables:[],handlers:[]},u=s(e,"template-name"),d=s(e,"template-description"),f=s(e,"template-before-image"),h=s(e,"template-after-image");function v(e,t){e.style.setProperty(m.clip,`${t}%`)}function g(t,n){const r=t.templateItems[n];if(!r)return;const s=r.querySelector(u);t.nameElement&&s&&(t.nameElement.textContent=s.textContent);const i=r.querySelector(d);t.descElement&&i&&(t.descElement.textContent=i.textContent);const a=r.querySelector(f);t.beforeImage&&a&&(t.beforeImage.src=a.src,t.beforeImage.alt=a.alt||"");const l=r.querySelector(h);t.afterImage&&l&&(t.afterImage.src=l.src,t.afterImage.alt=l.alt||"",y(t)),t.currentIndex=n,function(t,n){const r=o(e,"pagination",t);if(!r)return;const s=p.classes.active;Array.from(r.children).forEach((e,t)=>{t===n?e.classList.add(s):e.classList.remove(s)})}(t.wrapper,n)}function y(e){const t=e.slider,n=e.wrapper;switch(e.mode){case"before":n.style.setProperty(m.clip,"100%"),t.style.display="none";break;case"after":n.style.setProperty(m.clip,"0%"),t.style.display="none";break;case"split":v(n,e.sliderPosition),t.style.display="flex"}}function b(e,t){const n=e.currentIndex+t,r=e.templateItems.length-1;let s;s=n>r?0:n<0?r:n,g(e,s)}return l.forEach(t=>{const n=o(e,"template-list",t);if(!n)return void console.warn("[comparison] No template list found in wrapper");const r=s(e,"template-item"),l=Array.from(n.querySelectorAll(r));if(0===l.length)return void console.warn("[comparison] No template items found");t.setAttribute("aria-live","polite"),t.setAttribute("aria-label","Before and after image comparison");const u=o(e,"image-wrapper",t),d=o(e,"slider",t),f=o(e,"before-image",t),m=o(e,"after-image",t),h=o(e,"name",t),w=o(e,"description",t);if(!u||!d||!m){const e=[];return u||e.push('image-wrapper (data-hs-comparison="image-wrapper")'),d||e.push('slider (data-hs-comparison="slider")'),m||e.push('after-image (data-hs-comparison-image="after")'),void console.warn(`[comparison] Missing required elements: ${e.join(", ")}`)}const A={wrapper:t,templateItems:l,currentIndex:0,mode:"split",sliderPosition:50,slider:d,beforeImage:f?.querySelector("img"),afterImage:m?.querySelector("img"),nameElement:h,descElement:w,draggable:null};if(g(A,0),v(t,50),a){const e=a.create(d,{type:"x",bounds:u,onDrag:function(){const e=u.getBoundingClientRect(),n=d.getBoundingClientRect().left-e.left,r=Math.max(0,Math.min(100,n/e.width*100));v(t,r),A.sliderPosition=r}});c.draggables.push(e),A.draggable=e[0];const n=e=>{if("split"!==A.mode)return;const n=u.getBoundingClientRect(),r=e.clientX-n.left,s=Math.max(0,Math.min(100,r/n.width*100)),o=r-n.width/2;A.draggable&&(i.set(d,{x:o}),A.draggable.update()),v(t,s),A.sliderPosition=s};u.addEventListener("click",n),c.handlers.push({element:u,event:"click",handler:n})}t.querySelectorAll(`[${e.attributes.properties.modeType}]`).forEach(t=>{const n=t.getAttribute(e.attributes.properties.modeType),r=s(p.clickable,"button"),o=t.querySelector(r)||t;n===A.mode&&t.classList.add(p.classes.active);const i=t=>{t.preventDefault(),function(t,n){const r=t.wrapper.querySelectorAll(`[${e.attributes.properties.modeType}]`),s=p.classes.active;r.forEach(t=>{t.getAttribute(e.attributes.properties.modeType)===n?t.classList.add(s):t.classList.remove(s)}),t.mode=n,y(t)}(A,n)};o.addEventListener("click",i),c.handlers.push({element:o,event:"click",handler:i})}),function(t,n){const r=n.querySelector(`[${e.attributes.properties.navType}="previous"]`),o=n.querySelector(`[${e.attributes.properties.navType}="next"]`);if(r){const e=s(p.clickable,"button"),n=r.querySelector(e)||r;n.setAttribute("aria-label","Previous image");const o=e=>{e.preventDefault(),b(t,-1)};n.addEventListener("click",o),c.handlers.push({element:n,event:"click",handler:o})}if(o){const e=s(p.clickable,"button"),n=o.querySelector(e)||o;n.setAttribute("aria-label","Next image");const r=e=>{e.preventDefault(),b(t,1)};n.addEventListener("click",r),c.handlers.push({element:n,event:"click",handler:r})}}(A,t);const E=o(e,"pagination",t);E&&l.length>1&&function(e,t){const n=t.children[0];if(!n)return;const r=p.classes.active;t.innerHTML="",e.templateItems.forEach((s,o)=>{const i=n.cloneNode(!0);i.classList.remove(r),0===o&&i.classList.add(r);const a=()=>{g(e,o)};i.addEventListener("click",a),c.handlers.push({element:i,event:"click",handler:a}),t.appendChild(i)})}(A,E),function(e){const t=t=>{"ArrowLeft"===t.key||"ArrowUp"===t.key?(t.preventDefault(),b(e,-1)):"ArrowRight"!==t.key&&"ArrowDown"!==t.key||(t.preventDefault(),b(e,1))};e.wrapper.addEventListener("keydown",t),e.wrapper.setAttribute("tabindex","0"),c.handlers.push({element:e.wrapper,event:"keydown",handler:t})}(A)}),{result:`comparison initialized (${l.length} instances)`,destroy:()=>{c.draggables.forEach(e=>{e&&e[0]&&e[0].kill&&e[0].kill()}),c.handlers.forEach(({element:e,event:t,handler:n})=>{e.removeEventListener(t,n)}),c.draggables.length=0,c.handlers.length=0}}}async function L(e){if(n())return{result:"marquee skipped - prefers-reduced-motion enabled"};const s=t("marquee");if(!s)return{result:"marquee skipped - GSAP not loaded"};const{gsap:o,ScrollTrigger:i}=s;i&&o.registerPlugin(i),u();const a=r(e,"wrapper"),l={timelines:[],scrollTriggers:[],tickers:[]};return a.forEach(t=>{const n=t.getAttribute(e.attributes.properties.direction),r=Array.from(t.children);if(0===r.length)return void console.warn("[marquee] No children found in marquee wrapper:",t);const s=t.getAttribute(e.attributes.properties.duration),i=s?parseFloat(s):parseFloat(e.defaults.duration),a=t.getAttribute(e.attributes.properties.scrollMultiplier),c=a?parseFloat(a):parseFloat(e.defaults.scrollMultiplier),u=t.getAttribute(e.attributes.properties.type);s||t.setAttribute(e.attributes.properties.duration,e.defaults.duration),a||t.setAttribute(e.attributes.properties.scrollMultiplier,e.defaults.scrollMultiplier),t.classList.add(p.classes.gsap);const m=o.timeline({repeat:-1});if(r.forEach(e=>{"left"===n?m.to(e,{xPercent:-100,duration:i,ease:"none"},0):"right"===n&&(o.set(e,{xPercent:-100}),m.to(e,{xPercent:0,duration:i,ease:"none"},0))}),l.timelines.push(m),c>0){let e=1;const t=()=>{const t=f(),n=d();let r=1;if("reverse"===u)if(1===n)r=1+t*c;else if(-1===n){const e=t*c;r=e>.5?-e:1}else r=1;else{r=1+t*c}Math.abs(r-e)>.001&&(m.timeScale(r),e=r)};o.ticker.add(t),l.tickers.push({tickerFunc:t,gsap:o})}}),{result:`marquee initialized (${a.length} instances)`,destroy:()=>{l.timelines.forEach(e=>{e&&e.kill()}),l.scrollTriggers.forEach(e=>{e&&e.kill()}),l.tickers.forEach(({tickerFunc:e,gsap:t})=>{t.ticker.remove(e)}),a.forEach(e=>{e.classList.remove(p.classes.gsap)}),l.timelines.length=0,l.scrollTriggers.length=0,l.tickers.length=0}}}const x=p.apiName;async function S(){const t={destroyFunctions:[]},n=e.default,s=[h(),w(n.navbar),A(),E(n.accordion),k(n.comparison),L(n.marquee)],i=(async()=>(await new Promise(e=>setTimeout(e,50)),async function(t){const n=t||e.default?.transition,s=o(n,"element");if(!s)return console.log("[transition] No transition element found, skipping initialization"),{result:"transition skipped - no element found",destroy:()=>{}};const i=n.attributes.elements.namespace.primary,a=s.getAttribute(i)||null,l=window[x]?.settings?.isSPA||!1,c=new Map;let u=null;const d=(e,t)=>{const s=r(n,"exit"===e?"exitTrigger":"enterTrigger");if(s.length>0){if(t){const e=Array.from(s).find(e=>e.getAttribute(i)===t);if(e)return e}return Array.from(s).find(e=>!e.hasAttribute(i))||s[0]}const o=document.querySelectorAll('[data-hs-transition="trigger"]');if(o.length>0){if(t){const e=Array.from(o).find(e=>e.getAttribute(i)===t);if(e)return e}return o[0]}return null},f=(e,t,r)=>{if(!e)return 0;const o="exit"===r?"time"===t?n.attributes.elements.exitTime.primary:n.attributes.elements.exitDelay.primary:"time"===t?n.attributes.elements.enterTime.primary:n.attributes.elements.enterDelay.primary;let i=e.getAttribute(o);return i||"exit"===r&&"time"===t&&(i=s.getAttribute("data-hs-exit-time"),i)||"enter"===r&&"delay"===t&&(i=s.getAttribute("data-hs-delay"),i)?1e3*parseFloat(i):0},p=(e=a)=>new Promise(t=>{const n=d("exit",e);if(!n)return void t();const r=f(n,"time","exit"),s=f(n,"delay","exit"),o=()=>{"undefined"!=typeof Webflow?Webflow.push(()=>{n.click()}):n.click(),setTimeout(t,r)};s>0?setTimeout(o,s):o()}),m=(e=a)=>new Promise(t=>{const n=d("enter",e);if(!n)return void t();const r=f(n,"time","enter"),s=f(n,"delay","enter"),o=!sessionStorage.getItem("transition-loaded"),i=()=>{"undefined"!=typeof Webflow?Webflow.push(()=>{n.click()}):n.click(),o&&sessionStorage.setItem("transition-loaded","true"),setTimeout(t,r)};o&&s>0?u=setTimeout(i,s):i()}),h=()=>p(),v=()=>m();if(c.set("hsmain:transition-exit",h),c.set("hsmain:transition-enter",v),window.addEventListener("hsmain:transition-exit",h),window.addEventListener("hsmain:transition-enter",v),!l){const e=e=>{const t=e.target.closest("a[href]");if(t&&t.hostname===window.location.hostname&&t.getAttribute("href")&&-1===t.getAttribute("href").indexOf("#")&&"_blank"!==t.getAttribute("target")){e.preventDefault();const n=t.href;p().then(()=>{window.location.href=n})}};c.set("click",e),document.addEventListener("click",e);const t=e=>{e.persisted&&window.location.reload()};c.set("pageshow",t),window.addEventListener("pageshow",t)}const g=()=>{s&&(s.style.display="none")};c.set("resize",g),window.addEventListener("resize",g);const y=()=>{m()};return c.set(`${x}:dom-ready`,y),window.addEventListener(`${x}:dom-ready`,y,{once:!0}),{result:"transition initialized",destroy:()=>{u&&clearTimeout(u),c.forEach((e,t)=>{"click"===t||"pageshow"===t||"resize"===t?("click"===t?document:window).removeEventListener(t,e):window.removeEventListener(t,e)}),c.clear()}}}(n.transition)))(),a=await Promise.allSettled([...s,i]);a.forEach(e=>{"fulfilled"===e.status&&e.value?.destroy&&t.destroyFunctions.push(e.value.destroy)});const l=a.filter(e=>"fulfilled"===e.status).length,c=a.length-l;return c>0&&console.warn(`[default] ${l}/${a.length} functions loaded successfully. ${c} failed but won't affect other functions.`),{result:"default initialized",destroy:()=>{t.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[default] Error during cleanup:",t)}}),t.destroyFunctions.length=0}}}export{S as init};
2
- //# sourceMappingURL=default-CZ6vle49.js.map
Binary file
@@ -1 +0,0 @@
1
- {"version":3,"file":"default-CZ6vle49.js","sources":["../../src/modules/default/functions/smooth-scroll/smooth-scroll.ts","../../src/modules/default/functions/navbar/functions/dropdown/dropdown.ts","../../src/modules/default/functions/navbar/functions/menu/menu.ts","../../src/modules/default/functions/navbar/functions/arrow-navigation/arrow-navigation.ts","../../src/modules/default/functions/navbar/navbar.ts","../../src/modules/default/functions/accessibility/accessibility.ts","../../src/modules/default/functions/accordion/accordion.ts","../../src/modules/default/functions/comparison/comparison.ts","../../src/modules/default/functions/marquee/marquee.ts","../../src/modules/default/functions/transition/transition.ts","../../src/modules/default/default.ts"],"sourcesContent":["import { getGsap, prefersReducedMotion } from '@utils';\n\nexport async function init() {\n // Store event handlers for cleanup\n let clickHandler = null;\n let keydownHandler = 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() {\n const offsetValue = getComputedStyle(document.documentElement)\n .getPropertyValue('--misc--scroll-offset')\n .trim();\n return parseInt(offsetValue) || 0;\n }\n\n // Smooth scroll to element with offset\n function scrollToElement(target, offset = 0) {\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) {\n const link = e.target.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() {\n clickHandler = handleAnchorActivation;\n keydownHandler = function (e) {\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","import {\n querySelectorAll,\n querySelector,\n getSelector,\n globalConfig,\n animateHeight,\n setHeight,\n} from '@utils';\n\n// Module-scoped config (set during init)\nlet moduleConfig = null;\n\nexport function init(config) {\n // Store config at module scope for helper functions\n moduleConfig = config;\n\n const cleanup = {\n observers: [],\n handlers: [],\n };\n\n const addObserver = (observer) => cleanup.observers.push(observer);\n const addHandler = (element, event, handler, options) => {\n element.addEventListener(event, handler, options);\n cleanup.handlers.push({ element, event, handler, options });\n };\n\n function sanitizeForID(text) {\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(addObserver, addHandler) {\n const dropdownWrappers = querySelectorAll(moduleConfig, 'wrapper');\n const hoverDropdowns = []; // Track hover-type dropdowns for focus-loss handling\n\n dropdownWrappers.forEach((wrapper) => {\n const clickableSelector = getSelector(globalConfig.clickable, 'button');\n const toggle = wrapper.querySelector(clickableSelector);\n const dropdownList = querySelector(moduleConfig, '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.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.focus();\n }\n\n toggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false');\n dropdownList.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 = function (e) {\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].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].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].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 = function (e) {\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].focus();\n }\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (currentMenuItemIndex === 0) {\n wrapper.classList.remove(globalConfig.classes.active);\n toggle.focus();\n currentMenuItemIndex = -1;\n } else if (currentMenuItemIndex > 0) {\n currentMenuItemIndex--;\n menuItems[currentMenuItemIndex].focus();\n } else {\n toggle.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(document, '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 = function (e) {\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 = function (e) {\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 = function (e) {\n hoverDropdowns.forEach((wrapper) => {\n if (wrapper.classList.contains('is-active') && !wrapper.contains(e.target)) {\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, '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","import {\n querySelectorAll,\n querySelector,\n getSelector,\n globalConfig,\n cssVariables,\n animateHeight,\n setHeight,\n openModal,\n closeModal,\n} from '@utils';\n\nexport function init(config, navbarConfig) {\n const cleanup = {\n observers: [],\n handlers: [],\n state: {\n focusTrapHandler: null,\n },\n };\n\n const addObserver = (observer) => cleanup.observers.push(observer);\n const addHandler = (element, event, handler, options) => {\n element.addEventListener(event, handler, options);\n cleanup.handlers.push({ element, event, handler, options });\n };\n\n function createFocusTrap(menuButton) {\n const navbarWrapper = document.querySelector('[data-hs-nav=\"wrapper\"]');\n\n if (!navbarWrapper) return;\n\n const focusTrapHandler = (e) => {\n if (e.key === 'Tab') {\n const clickableSelector = getSelector(globalConfig.clickable, '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.focus();\n }\n } else {\n // Tab: moving forwards\n if (document.activeElement === lastElement) {\n e.preventDefault();\n firstElement.focus();\n }\n }\n }\n };\n\n document.addEventListener('keydown', focusTrapHandler);\n return focusTrapHandler;\n }\n\n function removeFocusTrap(focusTrapHandler) {\n if (focusTrapHandler) {\n document.removeEventListener('keydown', focusTrapHandler);\n }\n }\n\n function setupMenu(addObserver, addHandler) {\n const menuButtons = querySelectorAll(config, 'button');\n const menu = querySelector(config, 'wrapper');\n\n if (!menuButtons.length || !menu) return;\n\n // Get navbar wrapper for styling (e.g., backdrop blur)\n const navbarWrapper = querySelector(navbarConfig, 'wrapper');\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.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 = null;\n let shouldAutoFocus = 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.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, '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.focus();\n }\n } else {\n // Focus first item (Space/Enter/ArrowDown)\n const firstElement = allElements[0];\n if (firstElement) {\n firstElement.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.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.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","import { getSelector, globalConfig } from '@utils';\n\nexport function init(config) {\n const cleanup = {\n handlers: [],\n };\n\n const addHandler = (element, event, handler, options) => {\n element.addEventListener(event, handler, options);\n cleanup.handlers.push({ element, event, handler, options });\n };\n\n function setupDesktopArrowNavigation(addHandler) {\n const keydownHandler = function (e) {\n if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return;\n\n const menu = document.querySelector('[data-hs-nav-menu=\"wrapper\"]');\n if (menu && menu.contains(document.activeElement)) return;\n\n const navbar = 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, '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 isInMenu = el.closest('[data-hs-nav-menu=\"wrapper\"]');\n if (isInMenu) return false;\n\n const isInSkipLink = el.closest('[data-hs-nav=\"skip-link\"]');\n if (isInSkipLink) return false;\n\n const computedStyle = window.getComputedStyle(el);\n const isHidden =\n computedStyle.display === 'none' ||\n computedStyle.visibility === 'hidden' ||\n computedStyle.opacity === '0' ||\n el.offsetWidth === 0 ||\n el.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 parentHidden =\n parentStyle.display === 'none' ||\n parentStyle.visibility === 'hidden' ||\n parent.offsetWidth === 0 ||\n parent.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);\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].focus();\n }\n } else {\n if (currentIndex > 0) {\n const nextIndex = currentIndex - 1;\n focusableElements[nextIndex].focus();\n }\n }\n };\n\n addHandler(document, 'keydown', keydownHandler);\n }\n\n function setupMenuArrowNavigation(addHandler) {\n const menuContainer = document.querySelector('[data-hs-nav-menu=\"wrapper\"]');\n if (!menuContainer) return;\n\n function getFocusableElements() {\n const menuClickableSelector = getSelector(globalConfig.clickable, '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 = el;\n while (current && current !== menuContainer) {\n if (current.inert) {\n return false;\n }\n current = current.parentElement;\n }\n return true;\n });\n }\n\n let currentFocusIndex = -1;\n\n const keydownHandler = function (e) {\n const focusableElements = getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const activeElement = document.activeElement;\n currentFocusIndex = focusableElements.indexOf(activeElement);\n\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (currentFocusIndex < focusableElements.length - 1) {\n currentFocusIndex = currentFocusIndex + 1;\n focusableElements[currentFocusIndex].focus();\n }\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (currentFocusIndex > 0) {\n currentFocusIndex = currentFocusIndex - 1;\n focusableElements[currentFocusIndex].focus();\n }\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n if (activeElement.tagName === 'BUTTON' && activeElement.hasAttribute('aria-controls')) {\n const isExpanded = activeElement.getAttribute('aria-expanded') === 'true';\n if (!isExpanded) {\n activeElement.click();\n }\n return;\n }\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault();\n if (activeElement.tagName === 'BUTTON' && activeElement.hasAttribute('aria-controls')) {\n const isExpanded = activeElement.getAttribute('aria-expanded') === 'true';\n if (isExpanded) {\n activeElement.click();\n }\n return;\n }\n } else if (e.key === 'Home') {\n e.preventDefault();\n currentFocusIndex = 0;\n focusableElements[0].focus();\n } else if (e.key === 'End') {\n e.preventDefault();\n currentFocusIndex = focusableElements.length - 1;\n focusableElements[focusableElements.length - 1].focus();\n } else if (e.key === ' ' && activeElement.tagName === 'A') {\n e.preventDefault();\n } else if (e.key === 'Escape') {\n const menuButton = document.querySelector('[data-hs-nav-menu=\"button\"]');\n if (menuButton) {\n menuButton.click();\n menuButton.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 * @version 2.0.0\n */\nimport { init as dropdownInit } from './functions/dropdown/dropdown.ts';\nimport { init as menuInit } from './functions/menu/menu.ts';\nimport { init as arrowNavigationInit } from './functions/arrow-navigation/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']),\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","export async function init() {\n // Centralized cleanup tracking\n const cleanup = {\n modules: {},\n destroyFunctions: [],\n };\n\n // Empty function map - reserved for future accessibility functions\n const functionMap = {};\n\n const loadFunction = async (functionName) => {\n try {\n const { init } = await functionMap[functionName]();\n const result = await init();\n cleanup.modules[functionName] = result;\n if (result && result.destroy) {\n cleanup.destroyFunctions.push(result.destroy);\n }\n return result;\n } catch (error) {\n console.error(`[accessibility] Failed to load function: ${functionName}`, error);\n return null; // Return null instead of throwing - allows other functions to continue\n }\n };\n\n // Load all functions - use allSettled for resilient loading\n const functionPromises = Object.keys(functionMap).map((name) => loadFunction(name));\n const results = await Promise.allSettled(functionPromises);\n\n // Log summary of loaded functions\n const succeeded = results.filter((r) => r.status === 'fulfilled' && r.value).length;\n const failed = results.length - succeeded;\n if (failed > 0) {\n console.warn(\n `[accessibility] ${succeeded}/${results.length} functions loaded successfully. ${failed} failed but won't affect other functions.`\n );\n }\n\n return {\n result: 'accessibility initialized (no functions loaded)',\n destroy: () => {\n // Call all destroy functions\n cleanup.destroyFunctions.forEach((destroyFn) => {\n try {\n destroyFn();\n } catch (error) {\n console.error('Error during accessibility cleanup:', error);\n }\n });\n cleanup.destroyFunctions.length = 0;\n cleanup.modules = {};\n },\n };\n}\n","import {\n querySelectorAll,\n querySelector,\n getSelector,\n globalConfig,\n animateHeight,\n setHeight,\n} from '@utils';\n\nexport function init(config) {\n const cleanup = {\n observers: [],\n handlers: [],\n liveRegions: [],\n };\n\n const addObserver = (observer) => cleanup.observers.push(observer);\n const addHandler = (element, event, handler, options) => {\n element.addEventListener(event, handler, options);\n cleanup.handlers.push({ element, event, handler, options });\n };\n\n function setupAccordionAccessibility(addObserver, addHandler) {\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 heightWrapper = wrapper.querySelector('[data-hs-height=\"element\"]');\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 // Create live region for announcements\n const liveRegion = document.createElement('div');\n liveRegion.className = 'sr-only';\n liveRegion.setAttribute('aria-live', 'polite');\n liveRegion.setAttribute('aria-atomic', 'true');\n liveRegion.style.cssText =\n 'position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden;';\n wrapper.appendChild(liveRegion);\n cleanup.liveRegions.push(liveRegion);\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) {\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 // Announce state change to screen readers\n function announceStateChange(isOpen: boolean) {\n const buttonText = button.textContent?.trim() || 'Section';\n liveRegion.textContent = `${buttonText} ${isOpen ? 'expanded' : 'collapsed'}`;\n setTimeout(() => (liveRegion.textContent = ''), 1000);\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 // Announce state change if it actually changed\n if (isOpen !== wasOpen) {\n announceStateChange(isOpen);\n }\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 // Remove all live regions\n cleanup.liveRegions.forEach((liveRegion) => {\n if (liveRegion.parentNode) {\n liveRegion.parentNode.removeChild(liveRegion);\n }\n });\n cleanup.liveRegions.length = 0;\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 };\n}\n","/**\n * Comparison Module\n *\n * Before/after image comparison slider with GSAP Draggable.\n * Uses template list to manage multiple slides with a single persistent slider.\n *\n * Structure:\n * <!-- Template list (hidden, inside wrapper) -->\n * <div data-hs-comparison=\"wrapper\">\n * <div data-hs-comparison-template=\"list\" class=\"u-display-none\">\n * <div data-hs-comparison-template=\"item\">\n * <h3 data-hs-comparison-template=\"name\">Project 1</h3>\n * <div data-hs-comparison-template=\"description\">Description 1</div>\n * <img data-hs-comparison-template=\"before\" src=\"before1.jpg\" alt=\"Before\">\n * <img data-hs-comparison-template=\"after\" src=\"after1.jpg\" alt=\"After\">\n * </div>\n * </div>\n *\n * <!-- Visible slider elements -->\n * <div data-hs-comparison=\"image-wrapper\">\n * <div data-hs-comparison-image=\"before\">\n * <img src=\"placeholder.jpg\">\n * </div>\n * <div data-hs-comparison-image=\"after\">\n * <img src=\"placeholder.jpg\">\n * </div>\n * </div>\n * <div data-hs-comparison=\"slider\"></div>\n * <span data-hs-comparison=\"name\">Placeholder</span>\n * <span data-hs-comparison=\"description\">Placeholder</span>\n * </div>\n */\n\nimport {\n querySelector,\n querySelectorAll,\n getSelector,\n globalConfig,\n getGsap,\n cssVariables,\n} from '@utils';\n\nexport async function init(config: any) {\n const gsapLib = getGsap('comparison');\n if (!gsapLib) {\n return { result: 'comparison skipped - GSAP not loaded' };\n }\n\n const { gsap, Draggable } = gsapLib;\n\n if (!Draggable) {\n console.warn('[comparison] GSAP Draggable plugin not loaded, drag functionality disabled');\n }\n\n const wrappers = querySelectorAll(config, 'wrapper');\n const cleanup = {\n draggables: [] as any[],\n handlers: [] as Array<{ element: Element; event: string; handler: EventListener }>,\n };\n\n // Cache template selectors once (they never change)\n const templateNameSelector = getSelector(config, 'template-name');\n const templateDescSelector = getSelector(config, 'template-description');\n const templateBeforeImageSelector = getSelector(config, 'template-before-image');\n const templateAfterImageSelector = getSelector(config, 'template-after-image');\n\n // Helper functions with access to config and gsap via closure\n function updateClipPath(wrapper: HTMLElement, percentage: number) {\n // Set CSS variable on wrapper, CSS handles the actual clip-path\n wrapper.style.setProperty(cssVariables.clip, `${percentage}%`);\n }\n\n function loadSlide(instance: any, index: number) {\n const templateItem = instance.templateItems[index];\n if (!templateItem) return;\n\n // Update name\n const templateName = templateItem.querySelector(templateNameSelector);\n if (instance.nameElement && templateName) {\n instance.nameElement.textContent = templateName.textContent;\n }\n\n // Update description\n const templateDesc = templateItem.querySelector(templateDescSelector);\n if (instance.descElement && templateDesc) {\n instance.descElement.textContent = templateDesc.textContent;\n }\n\n // Update before image\n const templateBeforeImage = templateItem.querySelector(\n templateBeforeImageSelector\n ) as HTMLImageElement;\n\n if (instance.beforeImage && templateBeforeImage) {\n instance.beforeImage.src = templateBeforeImage.src;\n instance.beforeImage.alt = templateBeforeImage.alt || '';\n }\n\n // Update after image\n const templateAfterImage = templateItem.querySelector(\n templateAfterImageSelector\n ) as HTMLImageElement;\n\n if (instance.afterImage && templateAfterImage) {\n instance.afterImage.src = templateAfterImage.src;\n instance.afterImage.alt = templateAfterImage.alt || '';\n\n // Apply current mode to maintain slider state\n applyMode(instance);\n }\n\n instance.currentIndex = index;\n\n // Update pagination\n updatePagination(instance.wrapper, index);\n }\n\n function applyMode(instance: any) {\n const slider = instance.slider;\n const wrapper = instance.wrapper;\n\n switch (instance.mode) {\n case 'before':\n // Set variable to 100% (hide after image completely)\n wrapper.style.setProperty(cssVariables.clip, '100%');\n slider.style.display = 'none';\n break;\n case 'after':\n // Set variable to 0% (show after image completely)\n wrapper.style.setProperty(cssVariables.clip, '0%');\n slider.style.display = 'none';\n break;\n case 'split':\n // Restore slider position without resetting\n updateClipPath(wrapper, instance.sliderPosition);\n slider.style.display = 'flex';\n break;\n }\n }\n\n function setMode(instance: any, mode: string) {\n const wrapper = instance.wrapper;\n const modeButtons = wrapper.querySelectorAll(`[${config.attributes.properties.modeType}]`);\n const activeClass = globalConfig.classes.active;\n\n // Update button states\n modeButtons.forEach((btn: Element) => {\n const btnMode = btn.getAttribute(config.attributes.properties.modeType);\n if (btnMode === mode) {\n btn.classList.add(activeClass);\n } else {\n btn.classList.remove(activeClass);\n }\n });\n\n instance.mode = mode;\n applyMode(instance);\n }\n\n function updatePagination(wrapper: HTMLElement, index: number) {\n const paginationContainer = querySelector(config, 'pagination', wrapper);\n if (!paginationContainer) return;\n\n const activeClass = globalConfig.classes.active;\n const dots = Array.from(paginationContainer.children);\n dots.forEach((dot, dotIndex) => {\n if (dotIndex === index) {\n dot.classList.add(activeClass);\n } else {\n dot.classList.remove(activeClass);\n }\n });\n }\n\n function navigateSlide(instance: any, direction: number) {\n const newIndex = instance.currentIndex + direction;\n const maxIndex = instance.templateItems.length - 1;\n\n let targetIndex: number;\n if (newIndex > maxIndex) {\n targetIndex = 0;\n } else if (newIndex < 0) {\n targetIndex = maxIndex;\n } else {\n targetIndex = newIndex;\n }\n\n loadSlide(instance, targetIndex);\n }\n\n function setupNavigation(instance: any, wrapper: HTMLElement) {\n const leftArrow = wrapper.querySelector(`[${config.attributes.properties.navType}=\"previous\"]`);\n const rightArrow = wrapper.querySelector(`[${config.attributes.properties.navType}=\"next\"]`);\n\n if (leftArrow) {\n const clickableSelector = getSelector(globalConfig.clickable, 'button');\n const button = (leftArrow.querySelector(clickableSelector) || leftArrow) as HTMLElement;\n button.setAttribute('aria-label', 'Previous image');\n\n const handler = (e: Event) => {\n e.preventDefault();\n navigateSlide(instance, -1);\n };\n\n button.addEventListener('click', handler);\n cleanup.handlers.push({ element: button, event: 'click', handler });\n }\n\n if (rightArrow) {\n const clickableSelector = getSelector(globalConfig.clickable, 'button');\n const button = (rightArrow.querySelector(clickableSelector) || rightArrow) as HTMLElement;\n button.setAttribute('aria-label', 'Next image');\n\n const handler = (e: Event) => {\n e.preventDefault();\n navigateSlide(instance, 1);\n };\n\n button.addEventListener('click', handler);\n cleanup.handlers.push({ element: button, event: 'click', handler });\n }\n }\n\n function setupPagination(instance: any, paginationContainer: HTMLElement) {\n const templateDot = paginationContainer.children[0];\n if (!templateDot) return;\n\n const activeClass = globalConfig.classes.active;\n paginationContainer.innerHTML = '';\n\n instance.templateItems.forEach((_: any, index: number) => {\n const dot = templateDot.cloneNode(true) as HTMLElement;\n\n // Remove active class from all dots, then add only to first\n dot.classList.remove(activeClass);\n if (index === 0) {\n dot.classList.add(activeClass);\n }\n\n const clickHandler = () => {\n loadSlide(instance, index);\n };\n\n dot.addEventListener('click', clickHandler);\n cleanup.handlers.push({ element: dot, event: 'click', handler: clickHandler });\n\n paginationContainer.appendChild(dot);\n });\n }\n\n function setupKeyboardNav(instance: any) {\n const keydownHandler = (e: KeyboardEvent) => {\n if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {\n e.preventDefault();\n navigateSlide(instance, -1);\n } else if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {\n e.preventDefault();\n navigateSlide(instance, 1);\n }\n };\n\n instance.wrapper.addEventListener('keydown', keydownHandler);\n instance.wrapper.setAttribute('tabindex', '0');\n cleanup.handlers.push({ element: instance.wrapper, event: 'keydown', handler: keydownHandler });\n }\n\n // Main initialization loop\n wrappers.forEach((wrapper) => {\n // Find template list inside wrapper\n const templateList = querySelector(config, 'template-list', wrapper);\n if (!templateList) {\n console.warn('[comparison] No template list found in wrapper');\n return;\n }\n\n const templateItemsSelector = getSelector(config, 'template-item');\n const templateItems = Array.from(templateList.querySelectorAll(templateItemsSelector));\n\n if (templateItems.length === 0) {\n console.warn('[comparison] No template items found');\n return;\n }\n\n // Add simple aria-live for screen reader announcements\n wrapper.setAttribute('aria-live', 'polite');\n wrapper.setAttribute('aria-label', 'Before and after image comparison');\n\n // Get references to visible elements and cache them\n const imageWrapper = querySelector(config, 'image-wrapper', wrapper) as HTMLElement;\n const slider = querySelector(config, 'slider', wrapper) as HTMLElement;\n const beforeImageWrapper = querySelector(config, 'before-image', wrapper) as HTMLElement;\n const afterImageWrapper = querySelector(config, 'after-image', wrapper) as HTMLElement;\n const nameElement = querySelector(config, 'name', wrapper) as HTMLElement;\n const descElement = querySelector(config, 'description', wrapper) as HTMLElement;\n\n if (!imageWrapper || !slider || !afterImageWrapper) {\n const missing = [];\n if (!imageWrapper) missing.push('image-wrapper (data-hs-comparison=\"image-wrapper\")');\n if (!slider) missing.push('slider (data-hs-comparison=\"slider\")');\n if (!afterImageWrapper) missing.push('after-image (data-hs-comparison-image=\"after\")');\n console.warn(`[comparison] Missing required elements: ${missing.join(', ')}`);\n return;\n }\n\n const instance = {\n wrapper: wrapper as HTMLElement,\n templateItems,\n currentIndex: 0,\n mode: 'split',\n sliderPosition: 50,\n imageWrapper,\n slider,\n beforeImage: beforeImageWrapper?.querySelector('img') as HTMLImageElement,\n afterImage: afterImageWrapper?.querySelector('img') as HTMLImageElement,\n nameElement,\n descElement,\n draggable: null as any,\n };\n\n // Load first slide\n loadSlide(instance, 0);\n\n // Set initial clip path to 50%\n updateClipPath(wrapper as HTMLElement, 50);\n\n // Setup GSAP Draggable for slider\n if (Draggable) {\n const draggableInstance = Draggable.create(slider, {\n type: 'x',\n bounds: imageWrapper,\n onDrag: function () {\n const rect = imageWrapper.getBoundingClientRect();\n const sliderRect = slider.getBoundingClientRect();\n const x = sliderRect.left - rect.left;\n const percentage = Math.max(0, Math.min(100, (x / rect.width) * 100));\n\n updateClipPath(wrapper as HTMLElement, percentage);\n instance.sliderPosition = percentage;\n },\n });\n\n cleanup.draggables.push(draggableInstance);\n instance.draggable = draggableInstance[0]; // Store reference to draggable\n\n // Click on image wrapper to jump slider\n const clickHandler = (e: MouseEvent) => {\n if (instance.mode !== 'split') return;\n\n const rect = imageWrapper.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n const percentage = Math.max(0, Math.min(100, (clickX / rect.width) * 100));\n\n // Calculate target position accounting for slider's center point\n // Draggable starts from slider's initial position (50% = center)\n const centerX = rect.width / 2;\n const offsetX = clickX - centerX;\n\n // Update Draggable's x position from center\n if (instance.draggable) {\n gsap.set(slider, { x: offsetX });\n instance.draggable.update();\n }\n\n updateClipPath(wrapper as HTMLElement, percentage);\n instance.sliderPosition = percentage;\n };\n\n imageWrapper.addEventListener('click', clickHandler);\n cleanup.handlers.push({ element: imageWrapper, event: 'click', handler: clickHandler });\n }\n\n // Setup mode buttons\n const modeButtons = wrapper.querySelectorAll(`[${config.attributes.properties.modeType}]`);\n modeButtons.forEach((modeWrapper) => {\n const mode = modeWrapper.getAttribute(config.attributes.properties.modeType);\n const clickableSelector = getSelector(globalConfig.clickable, 'button');\n const button = (modeWrapper.querySelector(clickableSelector) || modeWrapper) as HTMLElement;\n\n // Set initial state\n if (mode === instance.mode) {\n modeWrapper.classList.add(globalConfig.classes.active);\n }\n\n const clickHandler = (e: Event) => {\n e.preventDefault();\n setMode(instance, mode!);\n };\n\n button.addEventListener('click', clickHandler);\n cleanup.handlers.push({ element: button, event: 'click', handler: clickHandler });\n });\n\n // Setup navigation\n setupNavigation(instance, wrapper as HTMLElement);\n\n // Setup pagination\n const paginationContainer = querySelector(config, 'pagination', wrapper);\n if (paginationContainer && templateItems.length > 1) {\n setupPagination(instance, paginationContainer as HTMLElement);\n }\n\n // Setup keyboard navigation\n setupKeyboardNav(instance);\n });\n\n return {\n result: `comparison initialized (${wrappers.length} instances)`,\n destroy: () => {\n // Kill all draggables\n cleanup.draggables.forEach((d) => {\n if (d && d[0] && d[0].kill) d[0].kill();\n });\n\n // Remove all event listeners\n cleanup.handlers.forEach(({ element, event, handler }) => {\n element.removeEventListener(event, handler);\n });\n\n // Clear arrays\n cleanup.draggables.length = 0;\n cleanup.handlers.length = 0;\n },\n };\n}\n","/**\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 * Attributes:\n * data-hs-marquee-direction: \"left\" | \"right\" (required)\n * data-hs-marquee-duration: Number in seconds (default: \"25\")\n * data-hs-marquee-scroll: Scroll speed multiplier, 0-1 range (default: \"0\", disabled)\n * data-hs-marquee-type: \"reverse\" (optional, enables scroll-direction reversal)\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 querySelectorAll,\n globalConfig,\n getGsap,\n prefersReducedMotion,\n initScrollVelocityTracking,\n getScrollVelocity,\n getScrollDirection,\n} from '@utils';\n\nexport async function init(config) {\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 if (ScrollTrigger) {\n gsap.registerPlugin(ScrollTrigger);\n }\n\n // Initialize global scroll velocity tracking (only runs once)\n initScrollVelocityTracking();\n\n const marquees = querySelectorAll(config, 'wrapper');\n const cleanup = {\n timelines: [],\n scrollTriggers: [],\n tickers: [],\n };\n\n marquees.forEach((marquee) => {\n const direction = marquee.getAttribute(config.attributes.properties.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 config default\n const durationAttr = marquee.getAttribute(config.attributes.properties.duration);\n const duration = durationAttr ? parseFloat(durationAttr) : parseFloat(config.defaults.duration);\n\n // Get scroll multiplier - check attribute first, then use config default\n const scrollAttr = marquee.getAttribute(config.attributes.properties.scrollMultiplier);\n const scrollMultiplier = scrollAttr\n ? parseFloat(scrollAttr)\n : parseFloat(config.defaults.scrollMultiplier);\n\n // Get marquee type (reverse or default)\n const marqueeType = marquee.getAttribute(config.attributes.properties.type);\n\n // Set attributes with defaults if not present (for visibility in DOM)\n if (!durationAttr) {\n marquee.setAttribute(config.attributes.properties.duration, config.defaults.duration);\n }\n if (!scrollAttr) {\n marquee.setAttribute(\n config.attributes.properties.scrollMultiplier,\n config.defaults.scrollMultiplier\n );\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 as any).timeScale(newTimeScale);\n lastTimeScale = newTimeScale;\n }\n };\n\n // Add ticker function to GSAP's ticker\n (gsap as any).ticker.add(tickerFunc);\n\n // Store ticker function and gsap reference for cleanup\n cleanup.tickers.push({ tickerFunc, gsap });\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 as any).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 as any).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","/**\n * Page Transition Module\n * Enhanced with namespace support and SPA/MPA compatibility\n *\n * Features:\n * - Backward compatible with old single-trigger system\n * - Namespace-specific transitions (data-hs-transition-namespace)\n * - Separate exit/enter triggers with custom timing (optional)\n * - MPA: Auto link interception (default)\n * - SPA: Event-based integration (set data-hs-spa=\"true\" on script tag)\n *\n * @version 2.0.0\n */\nimport fullConfig from '@config';\nimport { querySelector, querySelectorAll, globalConfig } from '@utils';\n\nconst API_NAME = globalConfig.apiName;\n\nexport async function init(transitionConfig) {\n const config = transitionConfig || fullConfig.default?.transition;\n\n // Check if transition element exists - skip if not found\n const transitionElement = querySelector(config, 'element');\n if (!transitionElement) {\n console.log('[transition] No transition element found, skipping initialization');\n return {\n result: 'transition skipped - no element found',\n destroy: () => {},\n };\n }\n\n // Get current namespace (if any)\n const namespaceAttr = config.attributes.elements.namespace.primary;\n const currentNamespace = transitionElement.getAttribute(namespaceAttr) || null;\n\n // Check if running in SPA mode\n const isSPA = window[API_NAME]?.settings?.isSPA || false;\n\n // Store event handlers and timeouts for cleanup\n const eventHandlers = new Map();\n let delayTimeout = null;\n let navTimeout = null;\n\n const cleanup = () => {\n // Clear any pending timeouts\n if (delayTimeout) clearTimeout(delayTimeout);\n if (navTimeout) clearTimeout(navTimeout);\n\n // Remove all event listeners\n eventHandlers.forEach((handler, event) => {\n if (event === 'click' || event === 'pageshow' || event === 'resize') {\n const target = event === 'click' ? document : window;\n target.removeEventListener(event, handler);\n } else {\n window.removeEventListener(event, handler);\n }\n });\n eventHandlers.clear();\n };\n\n /**\n * Find trigger element for specific namespace and type (exit or enter)\n * Falls back to default trigger (no namespace) if namespace-specific not found\n * Also supports legacy single-trigger system for backward compatibility\n */\n const findTrigger = (type: 'exit' | 'enter', namespace: string | null) => {\n // Try new system: separate exit/enter triggers\n const allTriggers = querySelectorAll(config, type === 'exit' ? 'exitTrigger' : 'enterTrigger');\n\n if (allTriggers.length > 0) {\n // If namespace specified, try to find namespace-specific trigger first\n if (namespace) {\n const namespaceTrigger = Array.from(allTriggers).find(\n (trigger) => trigger.getAttribute(namespaceAttr) === namespace\n );\n if (namespaceTrigger) return namespaceTrigger;\n }\n\n // Fall back to default trigger (no namespace attribute)\n const defaultTrigger = Array.from(allTriggers).find(\n (trigger) => !trigger.hasAttribute(namespaceAttr)\n );\n\n if (defaultTrigger) return defaultTrigger;\n return allTriggers[0];\n }\n\n // Legacy fallback: look for old single trigger system\n // This maintains backward compatibility with existing sites\n const legacyTriggers = document.querySelectorAll('[data-hs-transition=\"trigger\"]');\n if (legacyTriggers.length > 0) {\n // If namespace specified, try to find namespace-specific trigger\n if (namespace) {\n const namespaceTrigger = Array.from(legacyTriggers).find(\n (trigger) => trigger.getAttribute(namespaceAttr) === namespace\n );\n if (namespaceTrigger) return namespaceTrigger;\n }\n\n // Fall back to first legacy trigger\n return legacyTriggers[0];\n }\n\n return null;\n };\n\n /**\n * Get timing value from trigger element or transition element (legacy)\n */\n const getTiming = (\n trigger: Element | null,\n type: 'time' | 'delay',\n direction: 'exit' | 'enter'\n ): number => {\n if (!trigger) return 0;\n\n // Try new system: timing attributes on trigger element\n const attrName =\n direction === 'exit'\n ? type === 'time'\n ? config.attributes.elements.exitTime.primary\n : config.attributes.elements.exitDelay.primary\n : type === 'time'\n ? config.attributes.elements.enterTime.primary\n : config.attributes.elements.enterDelay.primary;\n\n let value = trigger.getAttribute(attrName);\n if (value) return parseFloat(value) * 1000;\n\n // Legacy fallback: timing on transition element\n if (direction === 'exit' && type === 'time') {\n value = transitionElement.getAttribute('data-hs-exit-time');\n if (value) return parseFloat(value) * 1000;\n }\n\n if (direction === 'enter' && type === 'delay') {\n value = transitionElement.getAttribute('data-hs-delay');\n if (value) return parseFloat(value) * 1000;\n }\n\n return 0;\n };\n\n /**\n * Play exit animation (when leaving page)\n */\n const playExitAnimation = (namespace: string | null = currentNamespace): Promise<void> => {\n return new Promise((resolve) => {\n const exitTrigger = findTrigger('exit', namespace);\n if (!exitTrigger) {\n resolve();\n return;\n }\n\n const exitTime = getTiming(exitTrigger, 'time', 'exit');\n const exitDelay = getTiming(exitTrigger, 'delay', 'exit');\n\n const triggerAnimation = () => {\n if (typeof Webflow !== 'undefined') {\n Webflow.push(() => {\n (exitTrigger as HTMLElement).click();\n });\n } else {\n (exitTrigger as HTMLElement).click();\n }\n\n // Resolve after animation completes\n setTimeout(resolve, exitTime);\n };\n\n if (exitDelay > 0) {\n setTimeout(triggerAnimation, exitDelay);\n } else {\n triggerAnimation();\n }\n });\n };\n\n /**\n * Play enter animation (when arriving on page)\n */\n const playEnterAnimation = (namespace: string | null = currentNamespace): Promise<void> => {\n return new Promise((resolve) => {\n const enterTrigger = findTrigger('enter', namespace);\n if (!enterTrigger) {\n resolve();\n return;\n }\n\n const enterTime = getTiming(enterTrigger, 'time', 'enter');\n const enterDelay = getTiming(enterTrigger, 'delay', 'enter');\n\n // Check if first load (legacy behavior)\n const isFirstLoad = !sessionStorage.getItem('transition-loaded');\n\n const triggerAnimation = () => {\n if (typeof Webflow !== 'undefined') {\n Webflow.push(() => {\n (enterTrigger as HTMLElement).click();\n });\n } else {\n (enterTrigger as HTMLElement).click();\n }\n\n // Mark as loaded for session\n if (isFirstLoad) {\n sessionStorage.setItem('transition-loaded', 'true');\n }\n\n // Resolve after animation completes\n setTimeout(resolve, enterTime);\n };\n\n // Only apply delay on first load (legacy behavior)\n if (isFirstLoad && enterDelay > 0) {\n delayTimeout = setTimeout(triggerAnimation, enterDelay);\n } else {\n triggerAnimation();\n }\n });\n };\n\n // Always listen for custom events (works for both MPA and SPA)\n const handleExitEvent = () => playExitAnimation();\n const handleEnterEvent = () => playEnterAnimation();\n\n eventHandlers.set('hsmain:transition-exit', handleExitEvent);\n eventHandlers.set('hsmain:transition-enter', handleEnterEvent);\n window.addEventListener('hsmain:transition-exit', handleExitEvent);\n window.addEventListener('hsmain:transition-enter', handleEnterEvent);\n\n // MPA Mode: Intercept link clicks\n if (!isSPA) {\n const linkClickHandler = (e: MouseEvent) => {\n const link = (e.target as Element).closest('a[href]') as HTMLAnchorElement;\n\n if (\n link &&\n link.hostname === window.location.hostname &&\n link.getAttribute('href') &&\n link.getAttribute('href')!.indexOf('#') === -1 &&\n link.getAttribute('target') !== '_blank'\n ) {\n e.preventDefault();\n const href = link.href;\n\n // Play exit animation, then navigate\n playExitAnimation().then(() => {\n window.location.href = href;\n });\n }\n };\n\n eventHandlers.set('click', linkClickHandler);\n document.addEventListener('click', linkClickHandler);\n\n // Handle back button navigation\n const pageShowHandler = (event: PageTransitionEvent) => {\n if (event.persisted) {\n window.location.reload();\n }\n };\n\n eventHandlers.set('pageshow', pageShowHandler);\n window.addEventListener('pageshow', pageShowHandler);\n }\n\n // Hide transition on window resize (prevents visual glitches)\n const resizeHandler = () => {\n if (transitionElement) {\n (transitionElement as HTMLElement).style.display = 'none';\n }\n };\n\n eventHandlers.set('resize', resizeHandler);\n window.addEventListener('resize', resizeHandler);\n\n // On DOM ready, play enter animation\n const domReadyHandler = () => {\n playEnterAnimation();\n };\n\n eventHandlers.set(`${API_NAME}:dom-ready`, domReadyHandler);\n window.addEventListener(`${API_NAME}:dom-ready`, domReadyHandler, { once: true });\n\n return {\n result: 'transition initialized',\n destroy: cleanup,\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 * Transition module included with 50ms delay for initialization order\n * @version 2.0.0\n */\nimport config from '@config';\nimport { init as smoothScrollInit } from './functions/smooth-scroll/smooth-scroll.ts';\nimport { init as navbarInit } from './functions/navbar/navbar.ts';\nimport { init as accessibilityInit } from './functions/accessibility/accessibility.ts';\nimport { init as accordionInit } from './functions/accordion/accordion.ts';\nimport { init as comparisonInit } from './functions/comparison/comparison.ts';\nimport { init as marqueeInit } from './functions/marquee/marquee.ts';\nimport { init as transitionInit } from './functions/transition/transition.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']),\n navbarInit(moduleConfig.navbar),\n accessibilityInit(), // No config needed for accessibility\n accordionInit(moduleConfig.accordion),\n comparisonInit(moduleConfig.comparison),\n marqueeInit(moduleConfig.marquee),\n ];\n\n // Add transition with 50ms delay to let other modules initialize first\n const transitionPromise = (async () => {\n await new Promise((resolve) => setTimeout(resolve, 50));\n return transitionInit(moduleConfig.transition);\n })();\n\n const results = await Promise.allSettled([...modulePromises, transitionPromise]);\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","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","offsetValue","getComputedStyle","documentElement","getPropertyValue","trim","parseInt","getScrollOffset","$","off","style","scrollBehavior","body","key","addEventListener","scrollHeight","innerHeight","set","result","destroy","removeEventListener","moduleConfig","config","cleanup","observers","handlers","addObserver","addHandler","dropdownWrappers","querySelectorAll","hoverDropdowns","forEach","wrapper","clickableSelector","getSelector","globalConfig","clickable","toggle","querySelector","dropdownList","console","warn","type","heightWrapper","animationTarget","parentElement","toggleText","textContent","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","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","cssVariables","cssVars","values","inactive","stateObserver","ResizeObserver","setupMenuDisplayObserver","navbar","openDropdown","allNavbarElements","focusableElements","filter","el","computedStyle","display","visibility","opacity","offsetWidth","offsetHeight","parent","parentStyle","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","modules","functionMap","functionPromises","Object","keys","map","name","functionName","loadFunction","liveRegions","accordionWrappers","initializedCount","button","content","buttonId","contentId","liveRegion","createElement","className","cssText","appendChild","openText","properties","open","closedText","closed","hasTextSwap","stateElements","stateSelector","isAccordionOpen","text","buttonText","announceStateChange","defaultState","default","setupAccordionAccessibility","parentNode","removeChild","Draggable","wrappers","draggables","templateNameSelector","templateDescSelector","templateBeforeImageSelector","templateAfterImageSelector","updateClipPath","percentage","setProperty","clip","loadSlide","instance","templateItem","templateItems","templateName","nameElement","templateDesc","descElement","templateBeforeImage","beforeImage","src","alt","templateAfterImage","afterImage","applyMode","paginationContainer","activeClass","children","dot","dotIndex","updatePagination","slider","mode","sliderPosition","navigateSlide","direction","newIndex","maxIndex","targetIndex","templateList","templateItemsSelector","imageWrapper","beforeImageWrapper","afterImageWrapper","missing","join","draggable","draggableInstance","create","bounds","onDrag","rect","x","left","Math","max","min","width","clickX","clientX","offsetX","update","modeType","modeWrapper","modeButtons","setMode","leftArrow","navType","rightArrow","setupNavigation","templateDot","innerHTML","_","cloneNode","setupPagination","setupKeyboardNav","d","kill","ScrollTrigger","registerPlugin","initScrollVelocityTracking","marquees","timelines","scrollTriggers","tickers","marquee","durationAttr","parseFloat","defaults","scrollAttr","scrollMultiplier","marqueeType","tl","timeline","repeat","child","xPercent","lastTimeScale","tickerFunc","scrollSpeed","getScrollVelocity","scrollDir","getScrollDirection","newTimeScale","reverseScale","abs","timeScale","ticker","st","gsapInstance","API_NAME","apiName","modulePromises","smoothScrollInit","navbarInit","accessibilityInit","accordionInit","accordion","comparisonInit","comparison","marqueeInit","transitionPromise","resolve","transitionConfig","fullConfig","transition","transitionElement","log","namespaceAttr","elements","namespace","primary","currentNamespace","isSPA","settings","eventHandlers","Map","delayTimeout","findTrigger","allTriggers","namespaceTrigger","find","trigger","legacyTriggers","getTiming","attrName","exitTime","exitDelay","enterTime","enterDelay","playExitAnimation","exitTrigger","triggerAnimation","Webflow","playEnterAnimation","enterTrigger","isFirstLoad","sessionStorage","getItem","setItem","handleExitEvent","handleEnterEvent","linkClickHandler","hostname","location","then","pageShowHandler","persisted","reload","resizeHandler","domReadyHandler","once","clear","transitionInit"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{c as e}from"../main.js";function t(e,t){const n=e.attributes.elements[t];if(!n)return console.warn(`[attributeSelector] No config for element: ${t}`),"";return[`[${n.primary}]`,...(n.aliases||[]).map(e=>`[${e}]`)].join(", ")}function n(e,n,o=document){const a=t(e,n);return o.querySelectorAll(a)}function o(e,n,o=document){const a=t(e,n);return o.querySelector(a)}let a=!1,i=0,r=0,s=!1;function l(){if(s||void 0===window.ScrollTrigger)return;const e=window.gsap;let t=window.scrollY,n=performance.now(),o=0,a=0;window.ScrollTrigger.create({onUpdate:()=>{const e=window.scrollY,a=performance.now(),i=e-t,s=a-n;i>0?r=1:i<0&&(r=-1),s>0&&(o=Math.abs(i)/s*1e3),t=e,n=a}}),e.ticker.add(()=>{a+=.08*(o-a),o*=.95,Math.abs(a)<.1&&(a=0),Math.abs(o)<.1&&(o=0),i=a}),s=!0}function c(){return i}function u(){return r}function d(e,t=!0){return void 0===window.gsap?(t&&!a?(console.warn("[gsap] GSAP library not detected. Some animations will be skipped. Add GSAP to your project: https://greensock.com/docs/v3/Installation"),a=!0):e&&!a&&(console.warn(`[${e}] GSAP not available, module will use fallback behavior`),a=!0),null):{gsap:window.gsap,ScrollTrigger:window.ScrollTrigger,Draggable:window.Draggable}}function g(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}const h=new class{#e=new Map;async animate(t,n,o={}){const a=d("heightAnimator");if(!a)return;const{gsap:i}=a,r=e._global.attributes.height,s=e._global.attributes.heightValue,l=e._global.attributes.heightDuration,c=e._global.attributes.heightEase,u=t.hasAttribute?.(r)&&t.getAttribute(r)===s?t:t.querySelector?.(`[${r}="${s}"]`)||t,h=this.#e.get(u);h&&(h.kill(),this.#e.delete(u));let w=u.getAttribute(l),f=u.getAttribute(c);!w&&u.parentElement&&(w=u.parentElement.getAttribute(l)),!f&&u.parentElement&&(f=u.parentElement.getAttribute(c));let m=w?parseInt(w,10)/1e3:(o.duration||300)/1e3;g()&&(m=0);const b=f||o.ease||"power2.inOut",p=i.to(u,{height:n?"auto":0,duration:m,ease:b});this.#e.set(u,p);try{await p.then()}finally{this.#e.delete(u)}}setHeight(t,n){const o=d("heightAnimator");if(!o)return;const{gsap:a}=o,i=e._global.attributes.height,r=e._global.attributes.heightValue,s=t.hasAttribute?.(i)&&t.getAttribute(i)===r?t:t.querySelector?.(`[${i}="${r}"]`)||t;a.set(s,{height:n?"auto":0})}cancelAll(){this.#e.forEach(e=>e.kill()),this.#e.clear()}},w=h.animate.bind(h),f=h.setHeight.bind(h);let m=0;const b=[],p=[];function A(){if(m++,1===m){const t=e._global.classes.modalOpen,n=e._global.classes.overflowHidden;document.body.classList.add(n,t),b.forEach(e=>{try{e()}catch(t){console.error("[modalManager] Error in open callback:",t)}})}}function y(){if(m--,0===m){const t=e._global.classes.modalOpen,n=e._global.classes.overflowHidden;document.body.classList.remove(n,t),p.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)}"undefined"!=typeof window&&(window.HS=window.HS||{},window.HS.modal={open:A,close:y,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"),()=>{}):(p.push(e),()=>{const t=p.indexOf(e);t>-1&&p.splice(t,1)})}});export{o as a,t as b,y as c,w as d,u as e,c as f,d as g,l as i,A as o,g as p,n as q,f as s};
2
- //# sourceMappingURL=modalManager-LtDi9OJz.js.map
@@ -1,2 +0,0 @@
1
- import{c as e}from"../main.js";function t(e,t){const n=e.attributes.elements[t];if(!n)return console.warn(`[attributeSelector] No config for element: ${t}`),"";return[`[${n.primary}]`,...(n.aliases||[]).map(e=>`[${e}]`)].join(", ")}function n(e,n,o=document){const a=t(e,n);return o.querySelectorAll(a)}function o(e,n,o=document){const a=t(e,n);return o.querySelector(a)}let a=!1,i=0,r=0,s=!1;function l(){if(s||void 0===window.ScrollTrigger)return;const e=window.gsap;let t=window.scrollY,n=performance.now(),o=0,a=0;window.ScrollTrigger.create({onUpdate:()=>{const e=window.scrollY,a=performance.now(),i=e-t,s=a-n;i>0?r=1:i<0&&(r=-1),s>0&&(o=Math.abs(i)/s*1e3),t=e,n=a}}),e.ticker.add(()=>{a+=.08*(o-a),o*=.95,Math.abs(a)<.1&&(a=0),Math.abs(o)<.1&&(o=0),i=a}),s=!0}function c(){return i}function u(){return r}function d(e,t=!0){return void 0===window.gsap?(t&&!a?(console.warn("[gsap] GSAP library not detected. Some animations will be skipped. Add GSAP to your project: https://greensock.com/docs/v3/Installation"),a=!0):e&&!a&&(console.warn(`[${e}] GSAP not available, module will use fallback behavior`),a=!0),null):{gsap:window.gsap,ScrollTrigger:window.ScrollTrigger,Draggable:window.Draggable}}function g(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}const h=new class{#e=new Map;async animate(t,n,o={}){const a=d("heightAnimator");if(!a)return;const{gsap:i}=a,r=e._global.attributes.height,s=e._global.attributes.heightValue,l=e._global.attributes.heightDuration,c=e._global.attributes.heightEase,u=t.hasAttribute?.(r)&&t.getAttribute(r)===s?t:t.querySelector?.(`[${r}="${s}"]`)||t,h=this.#e.get(u);h&&(h.kill(),this.#e.delete(u));let w=u.getAttribute(l),f=u.getAttribute(c);!w&&u.parentElement&&(w=u.parentElement.getAttribute(l)),!f&&u.parentElement&&(f=u.parentElement.getAttribute(c));let m=w?parseInt(w,10)/1e3:(o.duration||300)/1e3;g()&&(m=0);const b=f||o.ease||"power2.inOut",p=i.to(u,{height:n?"auto":0,duration:m,ease:b});this.#e.set(u,p);try{await p.then()}finally{this.#e.delete(u)}}setHeight(t,n){const o=d("heightAnimator");if(!o)return;const{gsap:a}=o,i=e._global.attributes.height,r=e._global.attributes.heightValue,s=t.hasAttribute?.(i)&&t.getAttribute(i)===r?t:t.querySelector?.(`[${i}="${r}"]`)||t;a.set(s,{height:n?"auto":0})}cancelAll(){this.#e.forEach(e=>e.kill()),this.#e.clear()}},w=h.animate.bind(h),f=h.setHeight.bind(h);let m=0;const b=[],p=[];function A(){if(m++,1===m){const t=e._global.classes.modalOpen,n=e._global.classes.overflowHidden;document.body.classList.add(n,t),b.forEach(e=>{try{e()}catch(t){console.error("[modalManager] Error in open callback:",t)}})}}function y(){if(m--,0===m){const t=e._global.classes.modalOpen,n=e._global.classes.overflowHidden;document.body.classList.remove(n,t),p.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)}"undefined"!=typeof window&&(window.HS=window.HS||{},window.HS.modal={open:A,close:y,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"),()=>{}):(p.push(e),()=>{const t=p.indexOf(e);t>-1&&p.splice(t,1)})}});export{o as a,t as b,y as c,w as d,u as e,c as f,d as g,l as i,A as o,g as p,n as q,f as s};
2
- //# sourceMappingURL=modalManager-LtDi9OJz.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"modalManager-LtDi9OJz.js","sources":["../../src/utils/attributeSelector.ts","../../src/utils/gsap.ts","../../src/utils/heightAnimator.ts","../../src/utils/modalManager.ts"],"sourcesContent":["/**\n * Attribute Selector Utility\n *\n * Builds CSS selectors from module config.json files to support\n * multiple attribute patterns (primary + aliases) for easy rebranding\n * and backward compatibility.\n *\n * @version 2.0.0\n */\n\n/**\n * Builds a CSS selector from config attribute patterns\n * @param {Object} config - Module config.json\n * @param {string} elementKey - Key from config.attributes.elements\n * @returns {string} Combined CSS selector\n */\nexport function getSelector(config, elementKey) {\n const element = config.attributes.elements[elementKey];\n if (!element) {\n console.warn(`[attributeSelector] No config for element: ${elementKey}`);\n return '';\n }\n\n const selectors = [\n `[${element.primary}]`,\n ...(element.aliases || []).map((alias) => `[${alias}]`),\n ];\n\n return selectors.join(', ');\n}\n\n/**\n * Gets all matching elements for a given element type\n * @param {Object} config - Module config.json\n * @param {string} elementKey - Key from config.attributes.elements\n * @param {Element} root - Root element to search within (default: document)\n * @returns {NodeList} All matching elements\n */\nexport function querySelectorAll(config, elementKey, root: Document | Element = document) {\n const selector = getSelector(config, elementKey);\n return root.querySelectorAll(selector);\n}\n\n/**\n * Gets first matching element for a given element type\n * @param {Object} config - Module config.json\n * @param {string} elementKey - Key from config.attributes.elements\n * @param {Element} root - Root element to search within (default: document)\n * @returns {Element|null} First matching element or null\n */\nexport function querySelector(config, elementKey, root: Document | Element = document) {\n const selector = getSelector(config, elementKey);\n return root.querySelector(selector);\n}\n\n/**\n * Logs deprecation warning if using non-primary attributes\n * @param {Element} element - Element to check\n * @param {Object} config - Module config.json\n * @param {string} elementKey - Key from config.attributes.elements\n */\nexport function checkDeprecated(element, config, elementKey) {\n if (!element) return;\n\n const elementConfig = config.attributes.elements[elementKey];\n const elementAttrs = element.getAttributeNames();\n\n elementConfig.aliases?.forEach((alias) => {\n const attrName = alias.split('=')[0].replace(/[\\[\\]']/g, '');\n if (elementAttrs.includes(attrName)) {\n console.warn(\n `[${config.module}] Using deprecated attribute \"${alias}\". ` +\n `Please use \"${elementConfig.primary}\" instead. ` +\n `Support for deprecated attributes will be removed in v3.0.0`\n );\n }\n });\n}\n","/**\n * GSAP Global Handler\n *\n * Centralized GSAP detection and error handling.\n * Provides type-safe access to GSAP and ScrollTrigger.\n *\n * Usage:\n * import { getGsap, hasGsap } from '@utils';\n *\n * if (hasGsap()) {\n * const { gsap, ScrollTrigger } = getGsap();\n * gsap.to(element, { opacity: 1 });\n * }\n *\n * @version 2.0.0\n */\n\n// Type definitions for externally loaded GSAP\ninterface GsapPlugin {\n create: (config: unknown) => void;\n getAll: () => unknown[];\n refresh: () => void;\n}\n\ninterface GsapDraggable {\n create: (target: unknown, vars?: Record<string, unknown>) => unknown[];\n}\n\ninterface GsapInstance {\n to: (target: unknown, vars: Record<string, unknown>) => unknown;\n from: (target: unknown, vars: Record<string, unknown>) => unknown;\n set: (target: unknown, vars: Record<string, unknown>) => unknown;\n timeline: (vars?: Record<string, unknown>) => unknown;\n registerPlugin: (...plugins: unknown[]) => void;\n}\n\n// Declare global types for GSAP (loaded externally)\ndeclare global {\n interface Window {\n gsap?: GsapInstance;\n ScrollTrigger?: GsapPlugin;\n Draggable?: GsapDraggable;\n }\n}\n\nlet hasWarned = false;\nlet globalScrollVelocity = 0;\nlet globalScrollDirection = 0; // 1 = down, -1 = up, 0 = not scrolling\nlet scrollVelocityInitialized = false;\n\n/**\n * Initialize global scroll velocity tracking\n * Call this once to start tracking scroll velocity across the entire page\n */\nexport function initScrollVelocityTracking() {\n if (scrollVelocityInitialized || !hasScrollTrigger()) {\n return;\n }\n\n const gsap = window.gsap!;\n\n // Track scroll position and smooth velocity\n let lastScrollY = window.scrollY;\n let lastTime = performance.now();\n let targetVelocity = 0;\n let currentVelocity = 0;\n\n // Update target velocity and direction on scroll\n window.ScrollTrigger!.create({\n onUpdate: () => {\n const currentScrollY = window.scrollY;\n const currentTime = performance.now();\n const deltaY = currentScrollY - lastScrollY;\n const deltaTime = currentTime - lastTime;\n\n // Update scroll direction\n if (deltaY > 0) {\n globalScrollDirection = 1; // Scrolling down\n } else if (deltaY < 0) {\n globalScrollDirection = -1; // Scrolling up\n }\n\n // Calculate velocity in pixels per second (framerate-independent)\n // Avoid division by zero\n if (deltaTime > 0) {\n targetVelocity = (Math.abs(deltaY) / deltaTime) * 1000; // Convert to pixels/second\n }\n\n lastScrollY = currentScrollY;\n lastTime = currentTime;\n },\n });\n\n // Smoothly lerp current velocity to target velocity every frame\n gsap.ticker.add(() => {\n // Lerp factor: lower = smoother (0.08 for buttery smooth)\n const lerpFactor = 0.08;\n\n // Interpolate current velocity towards target\n currentVelocity += (targetVelocity - currentVelocity) * lerpFactor;\n\n // Decay target velocity (simulates friction) - slower decay for smoothness\n targetVelocity *= 0.95;\n\n // Snap to zero when very small\n if (Math.abs(currentVelocity) < 0.1) {\n currentVelocity = 0;\n }\n if (Math.abs(targetVelocity) < 0.1) {\n targetVelocity = 0;\n }\n\n // Update global velocity\n globalScrollVelocity = currentVelocity;\n });\n\n scrollVelocityInitialized = true;\n}\n\n/**\n * Get current scroll velocity\n * @returns Current scroll velocity (pixels per second)\n */\nexport function getScrollVelocity(): number {\n return globalScrollVelocity;\n}\n\n/**\n * Get current scroll direction\n * @returns 1 for down, -1 for up, 0 for not scrolling\n */\nexport function getScrollDirection(): number {\n return globalScrollDirection;\n}\n\n/**\n * Check if GSAP is available\n */\nexport function hasGsap(): boolean {\n return typeof window.gsap !== 'undefined';\n}\n\n/**\n * Check if ScrollTrigger is available\n */\nexport function hasScrollTrigger(): boolean {\n return typeof window.ScrollTrigger !== 'undefined';\n}\n\n/**\n * Check if Draggable is available\n */\nexport function hasDraggable(): boolean {\n return typeof window.Draggable !== 'undefined';\n}\n\n/**\n * Get GSAP instance with type safety\n * @param moduleName - Name of the module requesting GSAP (for logging)\n * @param required - Whether GSAP is required (default: true)\n * @returns GSAP instance or null if not available\n */\nexport function getGsap(moduleName?: string, required: boolean = true) {\n if (!hasGsap()) {\n if (required && !hasWarned) {\n console.warn(\n '[gsap] GSAP library not detected. Some animations will be skipped. ' +\n 'Add GSAP to your project: https://greensock.com/docs/v3/Installation'\n );\n hasWarned = true;\n } else if (moduleName && !hasWarned) {\n console.warn(`[${moduleName}] GSAP not available, module will use fallback behavior`);\n hasWarned = true;\n }\n return null;\n }\n\n return {\n gsap: window.gsap!,\n ScrollTrigger: window.ScrollTrigger,\n Draggable: window.Draggable,\n };\n}\n\n/**\n * Reset warning state (useful for testing)\n */\nexport function resetGsapWarning() {\n hasWarned = false;\n}\n\n/**\n * Check if user prefers reduced motion\n * @returns true if user prefers reduced motion\n */\nexport function prefersReducedMotion(): boolean {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n","/**\n * Global height animation utility with singleton pattern\n * Handles GSAP height animations with customizable duration and easing\n *\n * Uses config from @config for all attribute names\n * Supports per-element customization via attributes\n *\n * @version 2.0.0\n */\nimport config from '@config';\nimport { getGsap, prefersReducedMotion } from './gsap.ts';\n\nclass HeightAnimator {\n #activeAnimations = new Map();\n\n /**\n * Animate element height to open or closed state\n * @param {HTMLElement} element - Container element (may contain height target)\n * @param {boolean} isOpen - True to open (height: auto), false to close (height: 0)\n * @param {Object} options - Animation options\n * @param {number} options.duration - Duration in milliseconds (default: 300)\n * @param {string} options.ease - GSAP easing function (default: 'power2.inOut')\n */\n async animate(element, isOpen, options = {}) {\n const gsapLib = getGsap('heightAnimator');\n if (!gsapLib) return;\n\n const { gsap } = gsapLib;\n\n const heightAttr = config._global.attributes.height;\n const heightValue = config._global.attributes.heightValue;\n const durationAttr = config._global.attributes.heightDuration;\n const easeAttr = config._global.attributes.heightEase;\n\n // Check for custom height target element\n const heightTarget =\n element.hasAttribute?.(heightAttr) && element.getAttribute(heightAttr) === heightValue\n ? element\n : element.querySelector?.(`[${heightAttr}=\"${heightValue}\"]`) || element;\n\n // Cancel existing animation on this element\n const existingAnim = this.#activeAnimations.get(heightTarget);\n if (existingAnim) {\n existingAnim.kill();\n this.#activeAnimations.delete(heightTarget);\n }\n\n // Get attributes - check both the target AND its parent wrapper\n let durationValue = heightTarget.getAttribute(durationAttr);\n let easeValue = heightTarget.getAttribute(easeAttr);\n\n // If not found on target, check parent wrapper\n if (!durationValue && heightTarget.parentElement) {\n durationValue = heightTarget.parentElement.getAttribute(durationAttr);\n }\n if (!easeValue && heightTarget.parentElement) {\n easeValue = heightTarget.parentElement.getAttribute(easeAttr);\n }\n\n // Fallback chain: attribute > options > default\n let duration = durationValue\n ? parseInt(durationValue, 10) / 1000\n : (options.duration || 300) / 1000;\n\n // Force instant updates if user prefers reduced motion\n if (prefersReducedMotion()) {\n duration = 0;\n }\n\n const ease = easeValue || options.ease || 'power2.inOut';\n\n // Create animation\n const animation = gsap.to(heightTarget, {\n height: isOpen ? 'auto' : 0,\n duration: duration,\n ease: ease,\n });\n\n // Track active animation\n this.#activeAnimations.set(heightTarget, animation);\n\n // Wait for animation to complete\n try {\n await animation.then();\n } finally {\n this.#activeAnimations.delete(heightTarget);\n }\n }\n\n /**\n * Set element height immediately without animation (for initial state)\n * @param {HTMLElement} element - Container element (may contain height target)\n * @param {boolean} isOpen - True for auto height, false for 0\n */\n setHeight(element, isOpen) {\n const gsapLib = getGsap('heightAnimator');\n if (!gsapLib) return;\n\n const { gsap } = gsapLib;\n\n const heightAttr = config._global.attributes.height;\n const heightValue = config._global.attributes.heightValue;\n\n // Check for custom height target element\n const heightTarget =\n element.hasAttribute?.(heightAttr) && element.getAttribute(heightAttr) === heightValue\n ? element\n : element.querySelector?.(`[${heightAttr}=\"${heightValue}\"]`) || element;\n\n // Set immediately without animation\n gsap.set(heightTarget, {\n height: isOpen ? 'auto' : 0,\n });\n }\n\n /**\n * Cancel all active animations (for cleanup)\n */\n cancelAll() {\n this.#activeAnimations.forEach((anim) => anim.kill());\n this.#activeAnimations.clear();\n }\n}\n\n// Export singleton instance\nexport const heightAnimator = new HeightAnimator();\n\n// Export bound methods for convenience\nexport const animateHeight = heightAnimator.animate.bind(heightAnimator);\nexport const setHeight = heightAnimator.setHeight.bind(heightAnimator);\n","/**\n * Global modal manager with extensible hooks\n * Handles body classes and allows custom callbacks for modal open/close\n * Uses reference counting to support multiple modals open simultaneously\n *\n * Class names configured via @config for easy customization\n *\n * Usage (internal):\n * import { openModal, closeModal } from '@utils/modalManager.js';\n * openModal(); // Register modal as open\n * closeModal(); // Register modal as closed\n *\n * Usage (external):\n * window.HS.modal.open();\n * window.HS.modal.close();\n * window.HS.modal.onOpen(() => window.lenis?.stop());\n * window.HS.modal.onClose(() => window.lenis?.start());\n *\n * @version 2.0.0\n */\nimport config from '@config';\n\nlet activeModalCount = 0;\nconst openCallbacks = [];\nconst closeCallbacks = [];\n\n/**\n * Register a callback to run when first modal opens\n * @param {Function} callback - Function to run on modal open\n * @returns {Function} Unregister function\n */\nexport function onModalOpen(callback) {\n if (typeof callback !== 'function') {\n console.warn('[modalManager] onModalOpen requires a function');\n return () => {};\n }\n\n openCallbacks.push(callback);\n\n // Return unregister function\n return () => {\n const index = openCallbacks.indexOf(callback);\n if (index > -1) openCallbacks.splice(index, 1);\n };\n}\n\n/**\n * Register a callback to run when last modal closes\n * @param {Function} callback - Function to run on modal close\n * @returns {Function} Unregister function\n */\nexport function onModalClose(callback) {\n if (typeof callback !== 'function') {\n console.warn('[modalManager] onModalClose requires a function');\n return () => {};\n }\n\n closeCallbacks.push(callback);\n\n // Return unregister function\n return () => {\n const index = closeCallbacks.indexOf(callback);\n if (index > -1) closeCallbacks.splice(index, 1);\n };\n}\n\n/**\n * Register a modal as open\n * Increments modal count and applies body classes when first modal opens\n */\nexport function openModal() {\n activeModalCount++;\n\n // Only apply effects when first modal opens\n if (activeModalCount === 1) {\n const modalOpenClass = config._global.classes.modalOpen;\n const overflowHiddenClass = config._global.classes.overflowHidden;\n\n document.body.classList.add(overflowHiddenClass, modalOpenClass);\n\n // Run all registered open callbacks\n openCallbacks.forEach((callback) => {\n try {\n callback();\n } catch (error) {\n console.error('[modalManager] Error in open callback:', error);\n }\n });\n }\n}\n\n/**\n * Register a modal as closed\n * Decrements modal count and removes body classes when last modal closes\n */\nexport function closeModal() {\n activeModalCount--;\n\n // Only remove effects when last modal closes\n if (activeModalCount === 0) {\n const modalOpenClass = config._global.classes.modalOpen;\n const overflowHiddenClass = config._global.classes.overflowHidden;\n\n document.body.classList.remove(overflowHiddenClass, modalOpenClass);\n\n // Run all registered close callbacks\n closeCallbacks.forEach((callback) => {\n try {\n callback();\n } catch (error) {\n console.error('[modalManager] Error in close callback:', error);\n }\n });\n }\n\n // Safety: prevent negative count\n if (activeModalCount < 0) {\n console.warn('[modalManager] Modal count went negative, resetting to 0');\n activeModalCount = 0;\n }\n}\n\n/**\n * Get current modal count (for debugging)\n * @returns {number} Number of active modals\n */\nexport function getActiveModalCount() {\n return activeModalCount;\n}\n\n/**\n * Check if any modals are currently open\n * @returns {boolean} True if at least one modal is open\n */\nexport function isModalOpen() {\n return activeModalCount > 0;\n}\n\n// Expose globally for external scripts\nif (typeof window !== 'undefined') {\n window.HS = window.HS || {};\n window.HS.modal = {\n open: openModal,\n close: closeModal,\n getCount: getActiveModalCount,\n isOpen: isModalOpen,\n onOpen: onModalOpen,\n onClose: onModalClose,\n };\n}\n"],"names":["getSelector","config","elementKey","element","attributes","elements","console","warn","primary","aliases","map","alias","join","querySelectorAll","root","document","selector","querySelector","hasWarned","globalScrollVelocity","globalScrollDirection","scrollVelocityInitialized","initScrollVelocityTracking","window","ScrollTrigger","gsap","lastScrollY","scrollY","lastTime","performance","now","targetVelocity","currentVelocity","create","onUpdate","currentScrollY","currentTime","deltaY","deltaTime","Math","abs","ticker","add","getScrollVelocity","getScrollDirection","getGsap","moduleName","required","Draggable","prefersReducedMotion","matchMedia","matches","heightAnimator","activeAnimations","Map","animate","isOpen","options","gsapLib","heightAttr","_global","height","heightValue","durationAttr","heightDuration","easeAttr","heightEase","heightTarget","hasAttribute","getAttribute","existingAnim","this","get","kill","delete","durationValue","easeValue","parentElement","duration","parseInt","ease","animation","to","set","then","setHeight","cancelAll","forEach","anim","clear","animateHeight","bind","activeModalCount","openCallbacks","closeCallbacks","openModal","modalOpenClass","classes","modalOpen","overflowHiddenClass","overflowHidden","body","classList","callback","error","closeModal","remove","HS","modal","open","close","getCount","onOpen","push","index","indexOf","splice","onClose"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{c as e}from"../main.js";import{q as t,a as r}from"./modalManager-LtDi9OJz.js";import{g as n}from"./utils-DA-PANmk.js";function o(e){const t=[],r=document.createTreeWalker(e,NodeFilter.SHOW_TEXT,null);let n;for(;n=r.nextNode();)n.nodeValue.trim()&&t.push(n);return t}function s(e){const t=[];return e.hasAttribute("href")&&t.push(e),t.push(...Array.from(e.querySelectorAll("[href]"))),t}function i(e){if(e.hasAttribute("src")){if(e.getAttribute("src"))return e}const t=e.querySelector("[src]");if(t){if(t.getAttribute("src"))return t}return null}function c(e,t,r){if(function(e,t){const r=t.attributes.properties.syncField;return null!==e.querySelector(`[${r}]`)}(t,r))return void function(e,t,r){const n=r.attributes.properties.syncField;e.querySelectorAll(`[${n}]`).forEach(e=>{const r=e.getAttribute(n),s=t.querySelector(`[${n}="${r}"]`);if(!s)return;const c=i(e),a=i(s);if(c&&a){const e=c.getAttribute("src");e&&a.setAttribute("src",e)}else if(e.hasAttribute("href")&&s.hasAttribute("href")){const t=e.getAttribute("href");t&&s.setAttribute("href",t)}else{const t=o(e),r=t.length>0?t[0].nodeValue:e.textContent.trim();if(r){const e=o(s);e.length>0?e[0].nodeValue=r:s.textContent=r}}})}(e,t,r);const n=o(e),c=n.length>0?n[0].nodeValue:"",a=s(e),l=a.length>0?a[0].getAttribute("href"):"";if(c){o(t).forEach(e=>{e.nodeValue=c})}if(l){s(t).forEach(e=>{e.setAttribute("href",l)})}}async function a(e){const r={destroyFunctions:[]};try{const o=await async function(){const e={processedWrappers:[]};return t(n.clickable,"wrapper").forEach(t=>{const r=t.querySelector(":scope > button"),n=t.querySelector(":scope > a");if(!r||!n)return;const o=n.getAttribute("href");let s,i;o&&""!==o&&"#"!==o?(s=n,i=r):(s=r,i=n);const c="button"===s.getAttribute("data-hs-clickable");c||s.setAttribute("data-hs-clickable","button"),i.remove(),e.processedWrappers.push({wrapper:t,keptElement:s,wasLink:s===n,addedAttribute:!c})}),{result:`normalize processed ${e.processedWrappers.length} wrappers`,destroy:()=>{e.processedWrappers.forEach(({keptElement:e,addedAttribute:t})=>{t&&e.removeAttribute("data-hs-clickable")}),e.processedWrappers.length=0}}}(e.normalize);return o?.destroy&&r.destroyFunctions.push(o.destroy),{result:"clickable initialized",destroy:()=>{r.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[clickable] Error during cleanup:",t)}}),r.destroyFunctions.length=0}}}catch(o){throw console.error("[clickable] Initialization failed:",o),r.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[clickable] Error during error cleanup:",t)}}),o}}const l="hs-dupe-no-transition";let u=!1;async function d(e){!function(){if(u)return;const e=document.createElement("style");e.textContent=`\n .${l},\n .${l} * {\n transition: none !important;\n animation: none !important;\n }\n `,document.head.appendChild(e),u=!0}();const r={processedElements:[]};return t(e,"wrapper").forEach(e=>{const t=e.getAttribute("data-hs-dupe");if(!t||"child"!==t&&"self"!==t)return void console.warn('[dupe] Invalid mode. Use "child" or "self":',e);const n=e.getAttribute("data-hs-dupe-count");let o=n?parseInt(n,10):1;(isNaN(o)||o<1)&&(console.warn("[dupe] Invalid count, using default of 1:",e),o=1),o>20&&(console.warn(`[dupe] Count of ${o} exceeds maximum of 20. Capping at 20.`),o=20);const s={hidden:e.hasAttribute("data-hs-dupe-hidden"),noSelect:e.hasAttribute("data-hs-dupe-no-select")};"child"===t?function(e,t,r,n){const o=e.children[0];if(!o)return;const s=[];for(let i=0;i<t;i++){const t=o.cloneNode(!0);t.classList.add(l),p(t,r),e.appendChild(t),s.push(t),t.offsetHeight,requestAnimationFrame(()=>{t.classList.remove(l)})}n.processedElements.push({element:e,mode:"child",clones:s})}(e,o,s,r):"self"===t&&function(e,t,r,n){const o=e.parentNode;if(!o)return void console.warn("[dupe] Element has no parent, cannot duplicate self:",e);const s=[];let i=e;for(let c=0;c<t;c++){const t=e.cloneNode(!0);t.classList.add(l),t.removeAttribute("data-hs-dupe"),t.removeAttribute("data-hs-dupe-count"),t.removeAttribute("data-hs-dupe-hidden"),t.removeAttribute("data-hs-dupe-no-select"),p(t,r),i.nextSibling?o.insertBefore(t,i.nextSibling):o.appendChild(t),s.push(t),i=t,t.offsetHeight,requestAnimationFrame(()=>{t.classList.remove(l)})}n.processedElements.push({element:e,mode:"self",clones:s})}(e,o,s,r)}),{result:`dupe processed ${r.processedElements.length} elements`,destroy:()=>{r.processedElements.forEach(({clones:e})=>{e.forEach(e=>{e.parentNode&&e.parentNode.removeChild(e)})}),r.processedElements.length=0}}}function p(e,t){t.hidden&&e.setAttribute("aria-hidden","true"),t.noSelect&&(e.style.userSelect="none",e.style.webkitUserSelect="none",e.style.msUserSelect="none")}async function h(){const n={destroyFunctions:[]},o=e.normalize;try{const e=await async function(e){const n=t(e,"source"),o=new Map;n.forEach(t=>{const r=t.getAttribute(e.attributes.properties.syncId);r&&o.set(r,t)});const s=t(e,"target");let i=0,a=0;return s.forEach(n=>{const s=n.getAttribute(e.attributes.properties.syncId);if(!s||!o.has(s))return void a++;const l=o.get(s),u=r(e,"item",n);if(!u)return void console.warn(`[sync] Target list "${s}" missing item template`);const d="child"===u.getAttribute(e.attributes.properties.syncMode),p=r(e,"ignore",n),h=t(e,"item",l);if(0===h.length)return void console.warn(`[sync] Source list "${s}" has no items`);let f;if(d){const e=u.firstElementChild;if(!e)return void console.warn(`[sync] Target list "${s}" has sync-mode="child" but item wrapper has no children`);f=e.cloneNode(!0)}else f=u.cloneNode(!0),f.removeAttribute(e.attributes.elements.item.primary.split("=")[0]);let m=!1;if(p){let e=p.nextElementSibling;for(;e;){if(e===u){m=!0;break}e=e.nextElementSibling}}if(d){for(;u.firstChild;)u.removeChild(u.firstChild);h.forEach(t=>{const r=f.cloneNode(!0);c(t,r,e),u.appendChild(r)}),u.removeAttribute(e.attributes.elements.item.primary.split("=")[0])}else{Array.from(n.children).forEach(e=>{e!==p&&e.remove()});const t=Array.from(h).map(t=>{const r=f.cloneNode(!0);return c(t,r,e),r});p?m?t.forEach(e=>{n.appendChild(e)}):t.forEach(e=>{n.insertBefore(e,p)}):t.forEach(e=>{n.appendChild(e)})}i++}),{result:`sync initialized (${i} synced, ${a} skipped)`}}(o.sync);e?.destroy&&n.destroyFunctions.push(e.destroy);const s=await a(o.clickable);s?.destroy&&n.destroyFunctions.push(s.destroy);const i=await d(o.dupe);return i?.destroy&&n.destroyFunctions.push(i.destroy),{result:"normalize initialized",destroy:()=>{n.destroyFunctions.reverse().forEach(e=>{try{e()}catch(t){console.error("[normalize] Error during cleanup:",t)}}),n.destroyFunctions.length=0}}}catch(s){throw console.error("[normalize] Initialization failed:",s),n.destroyFunctions.reverse().forEach(e=>{try{e()}catch(t){console.error("[normalize] Error during error cleanup:",t)}}),s}}export{h as init};
2
- //# sourceMappingURL=normalize-DWI4olFS.js.map
@@ -1,2 +0,0 @@
1
- import{c as e}from"../main.js";import{q as t,a as r}from"./modalManager-LtDi9OJz.js";import{g as n}from"./utils-DA-PANmk.js";function o(e){const t=[],r=document.createTreeWalker(e,NodeFilter.SHOW_TEXT,null);let n;for(;n=r.nextNode();)n.nodeValue.trim()&&t.push(n);return t}function s(e){const t=[];return e.hasAttribute("href")&&t.push(e),t.push(...Array.from(e.querySelectorAll("[href]"))),t}function i(e){if(e.hasAttribute("src")){if(e.getAttribute("src"))return e}const t=e.querySelector("[src]");if(t){if(t.getAttribute("src"))return t}return null}function c(e,t,r){if(function(e,t){const r=t.attributes.properties.syncField;return null!==e.querySelector(`[${r}]`)}(t,r))return void function(e,t,r){const n=r.attributes.properties.syncField;e.querySelectorAll(`[${n}]`).forEach(e=>{const r=e.getAttribute(n),s=t.querySelector(`[${n}="${r}"]`);if(!s)return;const c=i(e),a=i(s);if(c&&a){const e=c.getAttribute("src");e&&a.setAttribute("src",e)}else if(e.hasAttribute("href")&&s.hasAttribute("href")){const t=e.getAttribute("href");t&&s.setAttribute("href",t)}else{const t=o(e),r=t.length>0?t[0].nodeValue:e.textContent.trim();if(r){const e=o(s);e.length>0?e[0].nodeValue=r:s.textContent=r}}})}(e,t,r);const n=o(e),c=n.length>0?n[0].nodeValue:"",a=s(e),l=a.length>0?a[0].getAttribute("href"):"";if(c){o(t).forEach(e=>{e.nodeValue=c})}if(l){s(t).forEach(e=>{e.setAttribute("href",l)})}}async function a(e){const r={destroyFunctions:[]};try{const o=await async function(){const e={processedWrappers:[]};return t(n.clickable,"wrapper").forEach(t=>{const r=t.querySelector(":scope > button"),n=t.querySelector(":scope > a");if(!r||!n)return;const o=n.getAttribute("href");let s,i;o&&""!==o&&"#"!==o?(s=n,i=r):(s=r,i=n);const c="button"===s.getAttribute("data-hs-clickable");c||s.setAttribute("data-hs-clickable","button"),i.remove(),e.processedWrappers.push({wrapper:t,keptElement:s,wasLink:s===n,addedAttribute:!c})}),{result:`normalize processed ${e.processedWrappers.length} wrappers`,destroy:()=>{e.processedWrappers.forEach(({keptElement:e,addedAttribute:t})=>{t&&e.removeAttribute("data-hs-clickable")}),e.processedWrappers.length=0}}}(e.normalize);return o?.destroy&&r.destroyFunctions.push(o.destroy),{result:"clickable initialized",destroy:()=>{r.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[clickable] Error during cleanup:",t)}}),r.destroyFunctions.length=0}}}catch(o){throw console.error("[clickable] Initialization failed:",o),r.destroyFunctions.forEach(e=>{try{e()}catch(t){console.error("[clickable] Error during error cleanup:",t)}}),o}}const l="hs-dupe-no-transition";let u=!1;async function d(e){!function(){if(u)return;const e=document.createElement("style");e.textContent=`\n .${l},\n .${l} * {\n transition: none !important;\n animation: none !important;\n }\n `,document.head.appendChild(e),u=!0}();const r={processedElements:[]};return t(e,"wrapper").forEach(e=>{const t=e.getAttribute("data-hs-dupe");if(!t||"child"!==t&&"self"!==t)return void console.warn('[dupe] Invalid mode. Use "child" or "self":',e);const n=e.getAttribute("data-hs-dupe-count");let o=n?parseInt(n,10):1;(isNaN(o)||o<1)&&(console.warn("[dupe] Invalid count, using default of 1:",e),o=1),o>20&&(console.warn(`[dupe] Count of ${o} exceeds maximum of 20. Capping at 20.`),o=20);const s={hidden:e.hasAttribute("data-hs-dupe-hidden"),noSelect:e.hasAttribute("data-hs-dupe-no-select")};"child"===t?function(e,t,r,n){const o=e.children[0];if(!o)return;const s=[];for(let i=0;i<t;i++){const t=o.cloneNode(!0);t.classList.add(l),p(t,r),e.appendChild(t),s.push(t),t.offsetHeight,requestAnimationFrame(()=>{t.classList.remove(l)})}n.processedElements.push({element:e,mode:"child",clones:s})}(e,o,s,r):"self"===t&&function(e,t,r,n){const o=e.parentNode;if(!o)return void console.warn("[dupe] Element has no parent, cannot duplicate self:",e);const s=[];let i=e;for(let c=0;c<t;c++){const t=e.cloneNode(!0);t.classList.add(l),t.removeAttribute("data-hs-dupe"),t.removeAttribute("data-hs-dupe-count"),t.removeAttribute("data-hs-dupe-hidden"),t.removeAttribute("data-hs-dupe-no-select"),p(t,r),i.nextSibling?o.insertBefore(t,i.nextSibling):o.appendChild(t),s.push(t),i=t,t.offsetHeight,requestAnimationFrame(()=>{t.classList.remove(l)})}n.processedElements.push({element:e,mode:"self",clones:s})}(e,o,s,r)}),{result:`dupe processed ${r.processedElements.length} elements`,destroy:()=>{r.processedElements.forEach(({clones:e})=>{e.forEach(e=>{e.parentNode&&e.parentNode.removeChild(e)})}),r.processedElements.length=0}}}function p(e,t){t.hidden&&e.setAttribute("aria-hidden","true"),t.noSelect&&(e.style.userSelect="none",e.style.webkitUserSelect="none",e.style.msUserSelect="none")}async function h(){const n={destroyFunctions:[]},o=e.normalize;try{const e=await async function(e){const n=t(e,"source"),o=new Map;n.forEach(t=>{const r=t.getAttribute(e.attributes.properties.syncId);r&&o.set(r,t)});const s=t(e,"target");let i=0,a=0;return s.forEach(n=>{const s=n.getAttribute(e.attributes.properties.syncId);if(!s||!o.has(s))return void a++;const l=o.get(s),u=r(e,"item",n);if(!u)return void console.warn(`[sync] Target list "${s}" missing item template`);const d="child"===u.getAttribute(e.attributes.properties.syncMode),p=r(e,"ignore",n),h=t(e,"item",l);if(0===h.length)return void console.warn(`[sync] Source list "${s}" has no items`);let f;if(d){const e=u.firstElementChild;if(!e)return void console.warn(`[sync] Target list "${s}" has sync-mode="child" but item wrapper has no children`);f=e.cloneNode(!0)}else f=u.cloneNode(!0),f.removeAttribute(e.attributes.elements.item.primary.split("=")[0]);let m=!1;if(p){let e=p.nextElementSibling;for(;e;){if(e===u){m=!0;break}e=e.nextElementSibling}}if(d){for(;u.firstChild;)u.removeChild(u.firstChild);h.forEach(t=>{const r=f.cloneNode(!0);c(t,r,e),u.appendChild(r)}),u.removeAttribute(e.attributes.elements.item.primary.split("=")[0])}else{Array.from(n.children).forEach(e=>{e!==p&&e.remove()});const t=Array.from(h).map(t=>{const r=f.cloneNode(!0);return c(t,r,e),r});p?m?t.forEach(e=>{n.appendChild(e)}):t.forEach(e=>{n.insertBefore(e,p)}):t.forEach(e=>{n.appendChild(e)})}i++}),{result:`sync initialized (${i} synced, ${a} skipped)`}}(o.sync);e?.destroy&&n.destroyFunctions.push(e.destroy);const s=await a(o.clickable);s?.destroy&&n.destroyFunctions.push(s.destroy);const i=await d(o.dupe);return i?.destroy&&n.destroyFunctions.push(i.destroy),{result:"normalize initialized",destroy:()=>{n.destroyFunctions.reverse().forEach(e=>{try{e()}catch(t){console.error("[normalize] Error during cleanup:",t)}}),n.destroyFunctions.length=0}}}catch(s){throw console.error("[normalize] Initialization failed:",s),n.destroyFunctions.reverse().forEach(e=>{try{e()}catch(t){console.error("[normalize] Error during error cleanup:",t)}}),s}}export{h as init};
2
- //# sourceMappingURL=normalize-DWI4olFS.js.map