(function() { 'use strict'; const frames = [ "https://cdn.prod.website-files.com/692487b717cd11b0ad36e79a/6931ae113d658a370461cab6_256-black.png", "https://cdn.prod.website-files.com/692487b717cd11b0ad36e79a/6931ae88664c688760d6320d_256-white.png", ]; const speed = 2000; let link = null; let intervalId = null; let frameIndex = 0; let lastUpdate = 0; function getOrCreateFavicon() { if (!link || !document.head.contains(link)) { document.querySelectorAll('link[rel*="icon"]').forEach(el => el.remove()); link = document.createElement('link'); link.id = 'favicon'; link.rel = 'icon'; link.type = 'image/png'; link.href = frames[0]; document.head.appendChild(link); frameIndex = 0; } return link; } function updateFavicon() { if (!link) return; frameIndex = (frameIndex + 1) % frames.length; link.href = frames[frameIndex]; } function animate(now) { if (now - lastUpdate >= speed) { lastUpdate = now; updateFavicon(); } if (document.hidden) { return; } intervalId = requestAnimationFrame(animate); } function startAnimation() { if (intervalId) return; getOrCreateFavicon(); lastUpdate = performance.now(); if (document.hidden) { const handleVisibilityChange = () => { if (!document.hidden && !intervalId) { startAnimation(); } }; document.addEventListener('visibilitychange', handleVisibilityChange, { once: true }); return; } intervalId = requestAnimationFrame(animate); } function stopAnimation() { if (intervalId) { cancelAnimationFrame(intervalId); intervalId = null; } } function init() { startAnimation(); document.addEventListener('visibilitychange', () => { if (document.hidden) { stopAnimation(); } else { startAnimation(); } }); const mo = new MutationObserver((mutations) => { const faviconRemoved = mutations.some(mutation => Array.from(mutation.removedNodes).some(node => node === link || (node.nodeName === 'LINK' && node.id === 'favicon') ) ); if (faviconRemoved || !document.getElementById('favicon')) { stopAnimation(); startAnimation(); } }); mo.observe(document.head, { childList: true, subtree: true }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();