| |
| const hamburger = document.querySelector('.hamburger'); |
| const navMenu = document.querySelector('.nav-menu'); |
|
|
| if (hamburger) { |
| hamburger.addEventListener('click', () => { |
| navMenu.classList.toggle('active'); |
| hamburger.classList.toggle('active'); |
| }); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| function initSubmenuPositioning() { |
| |
| |
| const topLevelDropdowns = document.querySelectorAll('.nav-menu > .dropdown'); |
| |
| topLevelDropdowns.forEach(parentDropdown => { |
| const parentLink = parentDropdown.querySelector('a.nav-link'); |
| if (!parentLink) return; |
| |
| |
| const linkText = parentLink.textContent.trim(); |
| const linkHref = parentLink.getAttribute('href') || ''; |
| let parentType = null; |
| |
| if (linkText.includes('In') || linkHref.includes('/in.html') || linkHref.includes('/in/in.html')) { |
| parentType = 'in'; |
| } else if (linkText.includes('Proc') || linkHref.includes('/processing.html') || linkHref.includes('/processing/processing.html')) { |
| parentType = 'processing'; |
| } else if (linkText.includes('Out') || linkHref.includes('/out.html') || linkHref.includes('/out/out.html')) { |
| parentType = 'out'; |
| } |
| |
| |
| const parentDropdownMenu = parentDropdown.querySelector('.dropdown-menu'); |
| if (!parentDropdownMenu) return; |
| |
| |
| function determineParentDirection() { |
| const parentRect = parentDropdown.getBoundingClientRect(); |
| const viewportWidth = window.innerWidth; |
| const padding = 10; |
| const safetyMargin = 20; |
| const rightMargin = viewportWidth - padding - safetyMargin; |
| |
| |
| let maxDepth = 0; |
| function findMaxDepth(element, currentDepth = 0) { |
| |
| const directLiChildren = Array.from(element.children).filter(child => child.tagName === 'LI'); |
| const childMenus = []; |
| directLiChildren.forEach(li => { |
| const directUlChild = Array.from(li.children).find(child => child.tagName === 'UL'); |
| if (directUlChild) { |
| childMenus.push(directUlChild); |
| } |
| }); |
| |
| if (childMenus.length === 0) { |
| if (currentDepth > maxDepth) { |
| maxDepth = currentDepth; |
| } |
| return; |
| } |
| childMenus.forEach(childMenu => { |
| findMaxDepth(childMenu, currentDepth + 1); |
| }); |
| } |
| findMaxDepth(parentDropdownMenu); |
| |
| |
| const estimatedSubmenuWidth = 220; |
| |
| |
| |
| const rightmostEdgePosition = parentRect.right + (estimatedSubmenuWidth * maxDepth); |
| |
| |
| console.log(`[Menu Direction] ${parentType || 'unknown'}: parent.right=${parentRect.right.toFixed(0)}, maxDepth=${maxDepth}, rightmostEdge=${rightmostEdgePosition.toFixed(0)}, rightMargin=${rightMargin.toFixed(0)}`); |
| |
| |
| if (rightmostEdgePosition >= rightMargin) { |
| |
| console.log(`[Menu Direction] ${parentType || 'unknown'}: OVERFLOW DETECTED → pointing LEFTWARD`); |
| return 'leftward'; |
| } |
| |
| |
| const allChildMenus = parentDropdownMenu.querySelectorAll('ul'); |
| for (let childMenu of allChildMenus) { |
| |
| let depth = 0; |
| let current = childMenu; |
| while (current && current !== parentDropdownMenu) { |
| if (current.tagName === 'UL') { |
| depth++; |
| } |
| current = current.parentElement; |
| } |
| |
| |
| const parentMenuItem = childMenu.parentElement; |
| if (parentMenuItem) { |
| const menuItemRect = parentMenuItem.getBoundingClientRect(); |
| |
| const estimatedRightEdge = menuItemRect.right + estimatedSubmenuWidth; |
| |
| |
| if (estimatedRightEdge >= rightMargin) { |
| console.log(`[Menu Direction] ${parentType || 'unknown'}: Individual menu overflow → pointing LEFTWARD`); |
| return 'leftward'; |
| } |
| } |
| } |
| |
| |
| if (parentType === 'out' || parentType === 'processing') { |
| const spaceOnRight = viewportWidth - parentRect.right - padding - safetyMargin; |
| const spaceOnLeft = parentRect.left - padding; |
| |
| |
| if (parentRect.right > viewportWidth * 0.7 || spaceOnRight < spaceOnLeft * 1.2) { |
| console.log(`[Menu Direction] ${parentType}: Close to right edge → pointing LEFTWARD`); |
| return 'leftward'; |
| } |
| } |
| |
| |
| console.log(`[Menu Direction] ${parentType || 'unknown'}: Enough space → pointing RIGHTWARD`); |
| return 'rightward'; |
| } |
| |
| |
| const parentDirection = determineParentDirection(); |
| |
| |
| const allChildMenus = parentDropdownMenu.querySelectorAll('ul'); |
| |
| |
| allChildMenus.forEach(childMenu => { |
| if (parentDirection === 'leftward') { |
| |
| childMenu.classList.add('submenu-reversed'); |
| childMenu.style.setProperty('left', 'auto', 'important'); |
| childMenu.style.setProperty('right', '100%', 'important'); |
| childMenu.style.setProperty('margin-left', '0', 'important'); |
| childMenu.style.setProperty('margin-right', '2px', 'important'); |
| } else { |
| |
| childMenu.classList.remove('submenu-reversed'); |
| childMenu.style.setProperty('left', '100%', 'important'); |
| childMenu.style.setProperty('right', 'auto', 'important'); |
| childMenu.style.setProperty('margin-left', '2px', 'important'); |
| childMenu.style.setProperty('margin-right', '0', 'important'); |
| } |
| }); |
| |
| |
| const menuItemsWithChildren = parentDropdownMenu.querySelectorAll('li:has(> ul)'); |
| |
| menuItemsWithChildren.forEach(menuItem => { |
| |
| const submenu = Array.from(menuItem.children).find(child => child.tagName === 'UL'); |
| if (!submenu) return; |
| |
| |
| menuItem.addEventListener('mouseenter', () => { |
| if (parentDirection === 'leftward') { |
| submenu.classList.add('submenu-reversed'); |
| submenu.style.setProperty('left', 'auto', 'important'); |
| submenu.style.setProperty('right', '100%', 'important'); |
| submenu.style.setProperty('margin-left', '0', 'important'); |
| submenu.style.setProperty('margin-right', '2px', 'important'); |
| } else { |
| submenu.classList.remove('submenu-reversed'); |
| submenu.style.setProperty('left', '100%', 'important'); |
| submenu.style.setProperty('right', 'auto', 'important'); |
| submenu.style.setProperty('margin-left', '2px', 'important'); |
| submenu.style.setProperty('margin-right', '0', 'important'); |
| } |
| }); |
| }); |
| }); |
| |
| |
| let resizeTimer; |
| window.addEventListener('resize', () => { |
| clearTimeout(resizeTimer); |
| resizeTimer = setTimeout(() => { |
| initSubmenuPositioning(); |
| }, 100); |
| }); |
| } |
|
|
| |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', initSubmenuPositioning); |
| } else { |
| initSubmenuPositioning(); |
| } |
|
|
| |
| setTimeout(initSubmenuPositioning, 600); |
| setTimeout(initSubmenuPositioning, 1000); |
|
|
| |
| |
| const observer = new MutationObserver((mutations) => { |
| |
| let shouldUpdate = false; |
| mutations.forEach(mutation => { |
| mutation.addedNodes.forEach(node => { |
| if (node.nodeType === 1 && ( |
| node.classList?.contains('dropdown') || |
| node.classList?.contains('dropdown-menu') || |
| node.querySelector?.('.dropdown') || |
| node.querySelector?.('.dropdown-menu') |
| )) { |
| shouldUpdate = true; |
| } |
| }); |
| }); |
| if (shouldUpdate) { |
| setTimeout(initSubmenuPositioning, 100); |
| } |
| }); |
| observer.observe(document.body, { childList: true, subtree: true }); |
|
|
| |
| const navLinks = document.querySelectorAll('.nav-link, .dropdown-link, .submenu-link'); |
| navLinks.forEach(link => { |
| link.addEventListener('click', () => { |
| navMenu.classList.remove('active'); |
| hamburger.classList.remove('active'); |
| }); |
| }); |
|
|
| |
| const dropdowns = document.querySelectorAll('.dropdown'); |
| dropdowns.forEach(dropdown => { |
| const dropdownLink = dropdown.querySelector('.nav-link'); |
| if (dropdownLink) { |
| dropdownLink.addEventListener('click', (e) => { |
| if (window.innerWidth <= 768) { |
| e.preventDefault(); |
| dropdown.classList.toggle('active'); |
| } |
| }); |
| } |
| }); |
|
|
| |
| |
| (function() { |
| if (typeof localStorage !== 'undefined') { |
| const savedTheme = localStorage.getItem('theme') || 'light'; |
| if (savedTheme === 'dark') { |
| |
| const darkThemeStyle = document.createElement('style'); |
| darkThemeStyle.id = 'dark-theme-override-style'; |
| darkThemeStyle.textContent = ` |
| /* Override CSS variables at root level */ |
| :root.dark-theme, |
| html.dark-theme, |
| body.dark-theme { |
| --color-text: #ffffff !important; |
| --color-text-light: #ffffff !important; |
| } |
| |
| /* Force all content-text and children to white */ |
| body.dark-theme .content-text, |
| html.dark-theme .content-text, |
| body.dark-theme .content-text *, |
| html.dark-theme .content-text *, |
| body.dark-theme .content-text p, |
| html.dark-theme .content-text p, |
| body.dark-theme .section .content-text, |
| html.dark-theme .section .content-text, |
| body.dark-theme .section .content-text *, |
| html.dark-theme .section .content-text *, |
| body.dark-theme .section .content-text p, |
| html.dark-theme .section .content-text p, |
| body.dark-theme main .content-text, |
| html.dark-theme main .content-text, |
| body.dark-theme main .content-text *, |
| html.dark-theme main .content-text *, |
| body.dark-theme main .content-text p, |
| html.dark-theme main .content-text p, |
| body.dark-theme .container .content-text, |
| html.dark-theme .container .content-text, |
| body.dark-theme .container .content-text *, |
| html.dark-theme .container .content-text *, |
| body.dark-theme .container .content-text p, |
| html.dark-theme .container .content-text p, |
| body.dark-theme .content-grid .content-text, |
| html.dark-theme .content-grid .content-text, |
| body.dark-theme .content-grid .content-text *, |
| html.dark-theme .content-grid .content-text *, |
| body.dark-theme .content-grid .content-text p, |
| html.dark-theme .content-grid .content-text p { |
| color: #ffffff !important; |
| --color-text: #ffffff !important; |
| --color-text-light: #ffffff !important; |
| } |
| |
| /* Force background colors */ |
| body.dark-theme main, |
| html.dark-theme main, |
| body.dark-theme .section, |
| html.dark-theme .section, |
| body.dark-theme .container, |
| html.dark-theme .container, |
| body.dark-theme .content-grid, |
| html.dark-theme .content-grid { |
| background-color: #1a1a1a !important; |
| color: #ffffff !important; |
| --color-text: #ffffff !important; |
| --color-text-light: #ffffff !important; |
| } |
| |
| /* Force h1 in content-grid */ |
| body.dark-theme .content-grid h1, |
| html.dark-theme .content-grid h1, |
| body.dark-theme .content-text h1, |
| html.dark-theme .content-text h1 { |
| color: #ffffff !important; |
| } |
| `; |
| |
| if (document.head) { |
| document.head.appendChild(darkThemeStyle); |
| } else { |
| document.addEventListener('DOMContentLoaded', function() { |
| if (!document.getElementById('dark-theme-override-style')) { |
| document.head.appendChild(darkThemeStyle); |
| } |
| }); |
| } |
| } |
| } |
| })(); |
|
|
| function applyInlineDarkThemeStyles() { |
| |
| let darkThemeStyle = document.getElementById('dark-theme-override-style'); |
| if (!darkThemeStyle) { |
| darkThemeStyle = document.createElement('style'); |
| darkThemeStyle.id = 'dark-theme-override-style'; |
| |
| document.head.appendChild(darkThemeStyle); |
| } |
| |
| darkThemeStyle.textContent = ` |
| /* Override CSS variables at root level */ |
| :root.dark-theme, |
| html.dark-theme, |
| body.dark-theme { |
| --color-text: #ffffff !important; |
| --color-text-light: #ffffff !important; |
| } |
| |
| /* Force all content-text and children to white */ |
| body.dark-theme .content-text, |
| html.dark-theme .content-text, |
| body.dark-theme .content-text *, |
| html.dark-theme .content-text *, |
| body.dark-theme .content-text p, |
| html.dark-theme .content-text p, |
| body.dark-theme .section .content-text, |
| html.dark-theme .section .content-text, |
| body.dark-theme .section .content-text *, |
| html.dark-theme .section .content-text *, |
| body.dark-theme .section .content-text p, |
| html.dark-theme .section .content-text p, |
| body.dark-theme main .content-text, |
| html.dark-theme main .content-text, |
| body.dark-theme main .content-text *, |
| html.dark-theme main .content-text *, |
| body.dark-theme main .content-text p, |
| html.dark-theme main .content-text p, |
| body.dark-theme .container .content-text, |
| html.dark-theme .container .content-text, |
| body.dark-theme .container .content-text *, |
| html.dark-theme .container .content-text *, |
| body.dark-theme .container .content-text p, |
| html.dark-theme .container .content-text p, |
| body.dark-theme .content-grid .content-text, |
| html.dark-theme .content-grid .content-text, |
| body.dark-theme .content-grid .content-text *, |
| html.dark-theme .content-grid .content-text *, |
| body.dark-theme .content-grid .content-text p, |
| html.dark-theme .content-grid .content-text p { |
| color: #ffffff !important; |
| --color-text: #ffffff !important; |
| --color-text-light: #ffffff !important; |
| } |
| |
| /* Force background colors */ |
| body.dark-theme main, |
| html.dark-theme main, |
| body.dark-theme .section, |
| html.dark-theme .section, |
| body.dark-theme .container, |
| html.dark-theme .container, |
| body.dark-theme .content-grid, |
| html.dark-theme .content-grid { |
| background-color: #1a1a1a !important; |
| color: #ffffff !important; |
| --color-text: #ffffff !important; |
| --color-text-light: #ffffff !important; |
| } |
| |
| /* Force h1 in content-grid */ |
| body.dark-theme .content-grid h1, |
| html.dark-theme .content-grid h1, |
| body.dark-theme .content-text h1, |
| html.dark-theme .content-text h1 { |
| color: #ffffff !important; |
| } |
| `; |
| |
| |
| document.documentElement.style.setProperty('--color-text', '#ffffff', 'important'); |
| document.documentElement.style.setProperty('--color-text-light', '#ffffff', 'important'); |
| document.documentElement.style.setProperty('background-color', '#1a1a1a', 'important'); |
| document.body.style.setProperty('--color-text', '#ffffff', 'important'); |
| document.body.style.setProperty('--color-text-light', '#ffffff', 'important'); |
| document.body.style.setProperty('background-color', '#1a1a1a', 'important'); |
| |
| |
| const contentTextElements = document.querySelectorAll('.content-text'); |
| const main = document.querySelector('main'); |
| const section = document.querySelector('.section'); |
| const container = document.querySelector('.container'); |
| const contentGrid = document.querySelector('.content-grid'); |
| |
| |
| if (main) { |
| main.style.setProperty('background-color', '#1a1a1a', 'important'); |
| main.style.setProperty('color', '#ffffff', 'important'); |
| main.style.setProperty('--color-text', '#ffffff', 'important'); |
| main.style.setProperty('--color-text-light', '#ffffff', 'important'); |
| } |
| if (section) { |
| section.style.setProperty('background-color', '#1a1a1a', 'important'); |
| section.style.setProperty('color', '#ffffff', 'important'); |
| section.style.setProperty('--color-text', '#ffffff', 'important'); |
| section.style.setProperty('--color-text-light', '#ffffff', 'important'); |
| } |
| if (container) { |
| container.style.setProperty('color', '#ffffff', 'important'); |
| container.style.setProperty('--color-text', '#ffffff', 'important'); |
| container.style.setProperty('--color-text-light', '#ffffff', 'important'); |
| } |
| if (contentGrid) { |
| contentGrid.style.setProperty('color', '#ffffff', 'important'); |
| contentGrid.style.setProperty('--color-text', '#ffffff', 'important'); |
| contentGrid.style.setProperty('--color-text-light', '#ffffff', 'important'); |
| } |
| |
| |
| contentTextElements.forEach(el => { |
| |
| el.style.setProperty('--color-text', '#ffffff', 'important'); |
| el.style.setProperty('--color-text-light', '#ffffff', 'important'); |
| el.style.setProperty('color', '#ffffff', 'important'); |
| el.style.setProperty('background-color', 'transparent', 'important'); |
| |
| |
| const paragraphs = el.querySelectorAll('p'); |
| paragraphs.forEach(p => { |
| |
| p.style.setProperty('color', '#ffffff', 'important'); |
| p.style.setProperty('--color-text-light', '#ffffff', 'important'); |
| }); |
| |
| |
| const allChildren = el.querySelectorAll('*:not(p)'); |
| allChildren.forEach(child => { |
| child.style.setProperty('color', '#ffffff', 'important'); |
| }); |
| |
| const headings = el.querySelectorAll('h1, h2, h3, h4, h5, h6'); |
| headings.forEach(h => { |
| h.style.setProperty('color', '#ffffff', 'important'); |
| }); |
| |
| const textElements = el.querySelectorAll('strong, b, a, span, em, i'); |
| textElements.forEach(t => { |
| t.style.setProperty('color', '#ffffff', 'important'); |
| }); |
| }); |
| |
| |
| const h1Elements = document.querySelectorAll('.content-grid h1, .content-text h1'); |
| h1Elements.forEach(h1 => { |
| h1.style.setProperty('color', '#ffffff', 'important'); |
| }); |
| } |
|
|
| function removeInlineDarkThemeStyles() { |
| |
| const darkThemeStyle = document.getElementById('dark-theme-override-style'); |
| if (darkThemeStyle) { |
| darkThemeStyle.remove(); |
| } |
| |
| |
| document.documentElement.style.removeProperty('background-color'); |
| document.documentElement.style.setProperty('background-color', '#ffffff', 'important'); |
| document.body.style.removeProperty('background-color'); |
| document.body.style.setProperty('background-color', '#ffffff', 'important'); |
| |
| |
| document.documentElement.style.removeProperty('--color-text'); |
| document.documentElement.style.removeProperty('--color-text-light'); |
| document.body.style.removeProperty('--color-text'); |
| document.body.style.removeProperty('--color-text-light'); |
| |
| |
| const contentTextElements = document.querySelectorAll('.content-text'); |
| const main = document.querySelector('main'); |
| const section = document.querySelector('.section'); |
| const container = document.querySelector('.container'); |
| const contentGrid = document.querySelector('.content-grid'); |
| |
| |
| if (main) { |
| main.style.setProperty('background-color', '#ffffff', 'important'); |
| main.style.removeProperty('color'); |
| main.style.removeProperty('--color-text'); |
| main.style.removeProperty('--color-text-light'); |
| } |
| if (section) { |
| section.style.setProperty('background-color', '#ffffff', 'important'); |
| section.style.removeProperty('color'); |
| section.style.removeProperty('--color-text'); |
| section.style.removeProperty('--color-text-light'); |
| } |
| if (container) { |
| container.style.removeProperty('color'); |
| container.style.removeProperty('--color-text'); |
| container.style.removeProperty('--color-text-light'); |
| } |
| if (contentGrid) { |
| contentGrid.style.removeProperty('color'); |
| contentGrid.style.removeProperty('--color-text'); |
| contentGrid.style.removeProperty('--color-text-light'); |
| } |
| |
| |
| contentTextElements.forEach(el => { |
| el.style.removeProperty('--color-text'); |
| el.style.removeProperty('--color-text-light'); |
| el.style.removeProperty('color'); |
| el.style.removeProperty('background-color'); |
| |
| |
| const paragraphs = el.querySelectorAll('p'); |
| paragraphs.forEach(p => { |
| p.style.removeProperty('color'); |
| p.style.removeProperty('--color-text-light'); |
| }); |
| |
| |
| const allChildren = el.querySelectorAll('*:not(p)'); |
| allChildren.forEach(child => { |
| child.style.removeProperty('color'); |
| }); |
| }); |
| |
| |
| const h1Elements = document.querySelectorAll('.content-grid h1, .content-text h1'); |
| h1Elements.forEach(h1 => { |
| h1.style.removeProperty('color'); |
| }); |
| } |
|
|
| function initThemeToggle() { |
| const themeToggle = document.getElementById('themeToggle'); |
| const body = document.body; |
| const html = document.documentElement; |
| |
| if (!themeToggle) { |
| |
| setTimeout(initThemeToggle, 100); |
| return; |
| } |
| |
| const themeIcon = themeToggle.querySelector('.theme-icon'); |
|
|
| |
| const currentTheme = localStorage.getItem('theme') || 'light'; |
| if (currentTheme === 'dark') { |
| body.classList.add('dark-theme'); |
| html.classList.add('dark-theme'); |
| document.documentElement.classList.add('dark-theme'); |
| if (themeIcon) themeIcon.textContent = '☀️'; |
| |
| setTimeout(() => { |
| applyInlineDarkThemeStyles(); |
| }, 0); |
| } else { |
| body.classList.remove('dark-theme'); |
| html.classList.remove('dark-theme'); |
| document.documentElement.classList.remove('dark-theme'); |
| if (themeIcon) themeIcon.textContent = '🌙'; |
| |
| removeInlineDarkThemeStyles(); |
| } |
|
|
| |
| if (!themeToggle.hasAttribute('data-listener-attached')) { |
| themeToggle.setAttribute('data-listener-attached', 'true'); |
| |
| |
| themeToggle.addEventListener('click', (e) => { |
| e.preventDefault(); |
| e.stopPropagation(); |
| |
| |
| const style = document.createElement('style'); |
| style.textContent = ` |
| *, *::before, *::after { |
| transition: none !important; |
| } |
| `; |
| document.head.appendChild(style); |
| |
| |
| const currentlyDark = body.classList.contains('dark-theme'); |
| if (currentlyDark) { |
| |
| body.classList.remove('dark-theme'); |
| html.classList.remove('dark-theme'); |
| document.documentElement.classList.remove('dark-theme'); |
| } else { |
| |
| body.classList.add('dark-theme'); |
| html.classList.add('dark-theme'); |
| document.documentElement.classList.add('dark-theme'); |
| } |
| const isDark = body.classList.contains('dark-theme'); |
| |
| |
| if (themeIcon) { |
| themeIcon.textContent = isDark ? '☀️' : '🌙'; |
| } |
| |
| |
| localStorage.setItem('theme', isDark ? 'dark' : 'light'); |
| |
| |
| if (isDark) { |
| applyInlineDarkThemeStyles(); |
| } else { |
| removeInlineDarkThemeStyles(); |
| } |
| |
| |
| requestAnimationFrame(() => { |
| requestAnimationFrame(() => { |
| if (document.head.contains(style)) { |
| document.head.removeChild(style); |
| } |
| }); |
| }); |
| }); |
| } |
| } |
|
|
| |
| function initializeThemeToggle() { |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', initThemeToggle); |
| } else if (document.readyState === 'interactive' || document.readyState === 'complete') { |
| |
| initThemeToggle(); |
| } else { |
| |
| initThemeToggle(); |
| } |
| } |
|
|
| |
| initializeThemeToggle(); |
|
|
| |
| setTimeout(() => { |
| const themeToggle = document.getElementById('themeToggle'); |
| if (themeToggle && !themeToggle.hasAttribute('data-listener-attached')) { |
| initThemeToggle(); |
| } |
| }, 100); |
|
|
| |
| function initChatAgent() { |
| |
| const chatButton = document.getElementById('chatButton') || document.getElementById('chatAgentBtn'); |
| const chatWindow = document.getElementById('chatWindow'); |
| const chatClose = document.getElementById('chatClose'); |
| const chatInput = document.getElementById('chatInput'); |
| const chatSend = document.getElementById('chatSend'); |
| const chatMessages = document.getElementById('chatMessages'); |
|
|
| if (chatButton && chatWindow) { |
| |
| if (!chatButton.hasAttribute('data-chat-listener-attached')) { |
| chatButton.setAttribute('data-chat-listener-attached', 'true'); |
| chatButton.addEventListener('click', () => { |
| chatWindow.classList.toggle('active'); |
| }); |
| } |
| } |
| |
| if (chatClose) { |
| chatClose.addEventListener('click', () => { |
| chatWindow.classList.remove('active'); |
| }); |
| } |
| |
| if (chatSend && chatInput) { |
| chatSend.addEventListener('click', () => { |
| const message = chatInput.value.trim(); |
| if (message) { |
| addChatMessage(message, true); |
| chatInput.value = ''; |
| |
| setTimeout(() => { |
| addChatMessage('Thank you for your message. How can I help you?'); |
| }, 500); |
| } |
| }); |
|
|
| chatInput.addEventListener('keypress', (e) => { |
| if (e.key === 'Enter') { |
| chatSend.click(); |
| } |
| }); |
| } |
| } |
|
|
| |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', initChatAgent); |
| } else { |
| initChatAgent(); |
| } |
|
|
| |
| setTimeout(() => { |
| const chatButton = document.getElementById('chatButton') || document.getElementById('chatAgentBtn'); |
| if (chatButton && !chatButton.hasAttribute('data-chat-listener-attached')) { |
| chatButton.setAttribute('data-chat-listener-attached', 'true'); |
| initChatAgent(); |
| } |
| }, 100); |
|
|
| function addChatMessage(message, isUser = false) { |
| const chatMessages = document.getElementById('chatMessages'); |
| if (!chatMessages) return; |
| const messageDiv = document.createElement('div'); |
| messageDiv.className = `chat-message ${isUser ? 'user' : 'bot'}`; |
| messageDiv.textContent = message; |
| chatMessages.appendChild(messageDiv); |
| chatMessages.scrollTop = chatMessages.scrollHeight; |
| } |
|
|
| |
| |
| |
| |
| |
|
|
| (function() { |
| 'use strict'; |
| |
| |
| if (window.pageTransitionInitialized) return; |
| window.pageTransitionInitialized = true; |
| |
| |
| const FADE_IN_DURATION = 80; |
| const EASING = 'cubic-bezier(0.2, 0, 0.2, 1)'; |
| |
| |
| function initPageFadeIn() { |
| |
| document.body.style.opacity = '0'; |
| document.body.classList.add('page-fade-in'); |
| |
| |
| requestAnimationFrame(() => { |
| document.body.style.opacity = '1'; |
| |
| setTimeout(() => { |
| document.body.classList.remove('page-fade-in'); |
| }, FADE_IN_DURATION); |
| }); |
| } |
| |
| |
| function handleLinkClicks() { |
| |
| const links = document.querySelectorAll('a[href]'); |
| |
| links.forEach(link => { |
| |
| if (link.dataset.transitionHandler === 'true') return; |
| link.dataset.transitionHandler = 'true'; |
| |
| const href = link.getAttribute('href'); |
| |
| |
| if (!href || |
| href.startsWith('#') || |
| href.startsWith('javascript:') || |
| href.startsWith('mailto:') || |
| href.startsWith('tel:') || |
| (link.hasAttribute('target') && link.getAttribute('target') === '_blank') || |
| link.hasAttribute('download')) { |
| return; |
| } |
| |
| |
| try { |
| const url = new URL(href, window.location.origin); |
| if (url.origin !== window.location.origin) { |
| return; |
| } |
| } catch (e) { |
| |
| } |
| |
| |
| link.addEventListener('mouseenter', function() { |
| if (href && !href.startsWith('#')) { |
| |
| const linkElement = document.createElement('link'); |
| linkElement.rel = 'prefetch'; |
| linkElement.href = href; |
| document.head.appendChild(linkElement); |
| } |
| }, { passive: true }); |
| |
| |
| link.addEventListener('click', function(e) { |
| |
| if (e.ctrlKey || e.metaKey || e.shiftKey || e.button !== 0) { |
| return; |
| } |
| |
| |
| document.body.classList.add('page-transition-out'); |
| |
| |
| |
| }, { passive: true }); |
| }); |
| } |
| |
| |
| function handleBrowserNavigation() { |
| |
| window.addEventListener('pageshow', function(event) { |
| |
| document.body.classList.remove('page-transition-out'); |
| |
| |
| if (event.persisted) { |
| |
| document.body.style.opacity = '1'; |
| } else { |
| |
| initPageFadeIn(); |
| } |
| }); |
| |
| |
| window.addEventListener('beforeunload', function() { |
| |
| document.body.classList.add('page-transition-out'); |
| }); |
| } |
| |
| |
| function initPageTransitions() { |
| |
| document.body.classList.remove('page-transition-out'); |
| |
| |
| initPageFadeIn(); |
| |
| |
| handleLinkClicks(); |
| |
| |
| handleBrowserNavigation(); |
| } |
| |
| |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', initPageTransitions); |
| } else { |
| |
| initPageTransitions(); |
| } |
| |
| |
| setTimeout(handleLinkClicks, 100); |
| |
| |
| const observer = new MutationObserver(function(mutations) { |
| let shouldReinit = false; |
| mutations.forEach(function(mutation) { |
| if (mutation.addedNodes.length > 0) { |
| mutation.addedNodes.forEach(function(node) { |
| if (node.nodeType === 1 && (node.tagName === 'A' || node.querySelector('a'))) { |
| shouldReinit = true; |
| } |
| }); |
| } |
| }); |
| if (shouldReinit) { |
| handleLinkClicks(); |
| } |
| }); |
| |
| |
| if (document.body) { |
| observer.observe(document.body, { |
| childList: true, |
| subtree: true |
| }); |
| } |
| |
| |
| document.addEventListener('mouseover', function(e) { |
| const link = e.target.closest('a[href]'); |
| if (link && link.dataset.transitionHandler === 'true') { |
| const href = link.getAttribute('href'); |
| if (href && !href.startsWith('#') && !href.startsWith('javascript:')) { |
| try { |
| const url = new URL(href, window.location.origin); |
| if (url.origin === window.location.origin) { |
| |
| const prefetchLink = document.createElement('link'); |
| prefetchLink.rel = 'prefetch'; |
| prefetchLink.href = href; |
| if (!document.querySelector(`link[rel="prefetch"][href="${href}"]`)) { |
| document.head.appendChild(prefetchLink); |
| } |
| } |
| } catch (e) { |
| |
| } |
| } |
| } |
| }, { passive: true }); |
| })(); |
|
|
| |
| |
| |
| |
|
|
| (function() { |
| 'use strict'; |
| |
| |
| if (window.resizeRefreshInitialized) return; |
| window.resizeRefreshInitialized = true; |
| |
| let resizeTimer; |
| let isRefreshing = false; |
| let lastWidth = window.innerWidth; |
| let lastHeight = window.innerHeight; |
| |
| |
| function getColumnCount() { |
| const width = window.innerWidth; |
| if (width < 768) return 1; |
| if (width < 1024) return 2; |
| if (width < 1440) return 3; |
| return 4; |
| } |
| |
| let lastColumnCount = getColumnCount(); |
| |
| |
| function hardRefresh() { |
| if (isRefreshing) return; |
| isRefreshing = true; |
| |
| |
| window.location.reload(true); |
| } |
| |
| |
| function handleResize() { |
| if (isRefreshing) return; |
| |
| const currentWidth = window.innerWidth; |
| const currentHeight = window.innerHeight; |
| const currentColumnCount = getColumnCount(); |
| |
| |
| if (currentColumnCount !== lastColumnCount) { |
| lastColumnCount = currentColumnCount; |
| clearTimeout(resizeTimer); |
| resizeTimer = setTimeout(hardRefresh, 200); |
| return; |
| } |
| |
| |
| const widthChanged = Math.abs(currentWidth - lastWidth) > 10; |
| const heightChanged = Math.abs(currentHeight - lastHeight) > 10; |
| |
| if (widthChanged || heightChanged) { |
| lastWidth = currentWidth; |
| lastHeight = currentHeight; |
| clearTimeout(resizeTimer); |
| resizeTimer = setTimeout(hardRefresh, 200); |
| } |
| } |
| |
| |
| function handleOrientationChange() { |
| if (isRefreshing) return; |
| setTimeout(hardRefresh, 100); |
| } |
| |
| |
| function observeColumnChanges() { |
| const contentElements = document.querySelectorAll('main, .content-grid, .section, .container'); |
| |
| if (contentElements.length > 0 && window.ResizeObserver) { |
| const resizeObserver = new ResizeObserver(function(entries) { |
| if (isRefreshing) return; |
| |
| for (let entry of entries) { |
| const currentColumnCount = getColumnCount(); |
| if (currentColumnCount !== lastColumnCount) { |
| lastColumnCount = currentColumnCount; |
| clearTimeout(resizeTimer); |
| resizeTimer = setTimeout(hardRefresh, 200); |
| break; |
| } |
| } |
| }); |
| |
| contentElements.forEach(function(element) { |
| resizeObserver.observe(element); |
| }); |
| } |
| } |
| |
| |
| function initResizeRefresh() { |
| |
| window.addEventListener('resize', handleResize, { passive: true }); |
| |
| |
| window.addEventListener('orientationchange', handleOrientationChange, { passive: true }); |
| |
| |
| observeColumnChanges(); |
| |
| |
| setTimeout(observeColumnChanges, 500); |
| } |
| |
| |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', initResizeRefresh); |
| } else { |
| initResizeRefresh(); |
| } |
| |
| |
| if (document.body) { |
| const observer = new MutationObserver(function() { |
| observeColumnChanges(); |
| }); |
| |
| observer.observe(document.body, { |
| childList: true, |
| subtree: true |
| }); |
| } |
| })(); |
|
|