Diane Portfolio
  • About Me
  • Contact

remove video controls

这个能用

window.onload = function() {
  var video = document.querySelector('video');
  video.removeAttribute('controls');
  video.muted = true;
  video.loop = true;
  video.style.borderRadius = '20px';
  video.autoplay = true;
  console.log("Video is now muted and looping, and controls are removed.");
};;

09/23 update

修改为:

update: the above doesn;’t load well when route change

backup

second version(from chagpt)

back up

third version from chat gpt

orginal mistakes:

如果document is read,那么handleroutechange,并且setup handler (文档的所有内容已经加载完成,包括dom和外部资源,检测到已经完成后,执行操作)

如果window正在loading,那么handleroutechange,并且setuproutechange handeler (页面正在加载时,脚本监听window onload,加载时也可以执行代码)

window.onload只有在页面全部加载完时才能触发

try to edit:

在subpage写的办法不好用,只能去主page

目前能用的代码备份

又改了,重新troubleshooting,这一次的backup

最后能用的版本!!!(全部备份)

add avoide fullscreen plaing functions

another code to limit maxplaying videos:

新的备份: with safari优化与视频自动暂停

新的控制video开始播放地办法:

preload error:

新的办法也可以有用,但是video就不暂停了

加上暂停

新的尝试 新的logic看看能不能用

\

这个版本能用,除了暂停有点奇怪

备份! 又好了

尝试地优化

备份!

Home

Work

Case Studies

Gallery

About Me

Contact Me

ruochen0421@yahoo.com

Designed by Diane Liu 2024

XDribbble
// Wait for the document to fully load
window.onload = function() {
  // Select the video element (if there are multiple videos, target it more precisely)
  var video = document.querySelector('video');

  // Remove the controls
  video.removeAttribute('controls');

  // Mute the video
  video.muted = true;

  // Set the video to loop
  video.loop = true;

  // Apply rounded corners via CSS
  video.style.borderRadius = '15px'; // Adjust the pixel value as needed

  // Autoplay the video if desired
  video.autoplay = true;
};
<script>
window.onload = function() {
  var videos = document.querySelectorAll('.notion-video video');
  
  videos.forEach(function(video) {
    // Set attributes and styles for each video
    video.removeAttribute('controls');
    video.muted = true;
    video.loop = true;
    video.style.borderRadius = '20px';
    video.autoplay = true;

    // Preload video to reduce delay in starting
    video.setAttribute('preload', 'auto');

    console.log("Video is now muted and looping, and controls are removed.");
    
    // Listen for the video to be ready to play
    video.addEventListener('canplay', function() {
      video.play();
    });
  });
};
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
  var videos = document.querySelectorAll('.notion-video video');
  
  videos.forEach(function(video) {
    // Set attributes and styles for each video
    video.removeAttribute('controls'); 
    video.muted = true;                 
    video.loop = true;                  
    video.style.borderRadius = '20px';  
    video.autoplay = true;              

    // Preload video to reduce delay in starting
    video.setAttribute('preload', 'auto'); 

    // Try to immediately play the video
    video.play().catch(function(error) {
      console.error("Error playing video:", error);
    });

    console.log("Video is now muted, looping, controls are removed, and autoplay is set.");
  });
});
</script>

function handleRouteChange() {
    updateCodeElements();
    updateImageSource();
    
    // Find all videos inside elements with class 'notion-video'
    const videos = document.querySelectorAll('.notion-video video');
    
    videos.forEach(function(video, index) {
        // Apply video settings
        video.muted = true;               // Mute the video
        video.removeAttribute('controls'); // Remove the controls
        video.loop = true;                 // Set loop to true
        video.style.borderRadius = '20px'; // Apply border-radius style
        video.autoplay = true;             // Ensure video autoplays
        video.setAttribute('preload', 'auto'); // Preload the video

        console.log("Applying settings to video " + (index + 1));

        // Listen for video readiness
        video.addEventListener('canplay', function() {
            console.log("Video " + (index + 1) + " is ready to play.");
            video.play().catch(err => console.error("Error playing video", err));
        });

        // Error handling for video loading issues
        video.addEventListener('error', function(event) {
            console.error("Error loading video " + (index + 1), event);
        });
    });

    // Theme toggle logic
    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener
        themeToggleButton.addEventListener('click', onThemeChange); // Add new listener
    }
}

function setupRouteChangeHandler() {
    // Check if the route change handler is available and set it up
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Run the script based on the page load state
if (document.readyState === 'complete' || document.readyState === 'interactive') {
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        handleRouteChange();
        setupRouteChangeHandler();
    };
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />



<script>
  
  
  
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter set to: none');
        }

        if (targetImage.src === imageSrc) {
            console.log('Image source successfully set.');
        } else {
            console.log('Failed to set image source.');
        }
    } else {
        console.log('Target image not found.');
    }
}

function onThemeChange() {
    setTimeout(updateImageSource, 0);
}

function handleRouteChange() {
    updateCodeElements();
    updateImageSource();

    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        themeToggleButton.addEventListener('click', onThemeChange);
    }
}

function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

if (document.readyState === 'complete') {
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        handleRouteChange();
        setupRouteChangeHandler();
    };























function handleRouteChange() {
    updateCodeElements();
    updateImageSource();
    
    // Find all videos inside elements with class 'notion-video'
    const videos = document.querySelectorAll('.notion-video video');
    
    videos.forEach(function(video, index) {
        // Apply video settings
        video.muted = true;               // Mute the video
        video.removeAttribute('controls'); // Remove the controls
        video.loop = true;                 // Set loop to true
        video.style.borderRadius = '20px'; // Apply border-radius style
        video.autoplay = true;             // Ensure video autoplays
        video.setAttribute('preload', 'auto'); // Preload the video

        console.log("Applying settings to video " + (index + 1));

        // Listen for video readiness
        video.addEventListener('canplay', function() {
            console.log("Video " + (index + 1) + " is ready to play.");
            video.play().catch(err => console.error("Error playing video", err));
        });

        // Error handling for video loading issues
        video.addEventListener('error', function(event) {
            console.error("Error loading video " + (index + 1), event);
        });
    });

    // Theme toggle logic
    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener
        themeToggleButton.addEventListener('click', onThemeChange); // Add new listener
    }
}

function setupRouteChangeHandler() {
    // Check if the route change handler is available and set it up
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Run the script based on the page load state
if (document.readyState === 'complete' || document.readyState === 'interactive') {
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        handleRouteChange();
        setupRouteChangeHandler();
    };
}

</script>

<script>
// Define your main function that runs on both page load and route changes
function YourFunction() {
    updateCodeElements();
    updateImageSource();
    updateVideoSettings();
}

// Function to update code elements (icons, text trimming)
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

// Function to update image source and apply filter based on theme
function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter set to: none');
        }

        console.log('Image source successfully set.');
    } else {
        console.log('Target image not found.');
    }
}

// Function to update video settings (muted, autoplay, etc.)
function updateVideoSettings() {
    const videos = document.querySelectorAll('.notion-video video');
    
    videos.forEach(function(video, index) {
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.autoplay = true;
        video.setAttribute('preload', 'auto'); // Preload video to reduce delay in starting
        
        console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");
        
        video.addEventListener('canplay', function() {
            video.play().catch(err => console.error("Error playing video " + (index + 1) + ": ", err));
        });

        video.addEventListener('error', function(event) {
            console.error("Error loading video " + (index + 1), event);
        });
    });
}

// Handles theme change logic
function onThemeChange() {
    setTimeout(updateImageSource, 0);
}

// Route change handler that calls the main function
const handleRouteChange = () => {
    YourFunction(); // Call your main function that updates videos, images, and code elements
};

// Sets up the route change handler to trigger on navigation events
const setupRouteChangeHandler = () => {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange); // Handle route changes
    } else {
        console.log('window.events.on is not available.');
    }
};

// Ensure the script runs on page load and on route changes
if (document.readyState === 'complete') {
    handleRouteChange(); // Call your function on initial load if document is already complete
    setupRouteChangeHandler(); // Set up route change handling
} else {
    window.onload = () => {
        handleRouteChange(); // Call your function on initial load when window is loaded
        setupRouteChangeHandler(); // Set up route change handling
    };
}
</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />



<script>
  
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter set to: none');
        }

        if (targetImage.src === imageSrc) {
            console.log('Image source successfully set.');
        } else {
            console.log('Failed to set image source.');
        }
    } else {
        console.log('Target image not found.');
    }
}

function updateVideoSettings() {
    const videos = document.querySelectorAll('.notion-video video');
    
    videos.forEach(function(video, index) {
        // Set attributes and styles for each video
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.autoplay = true;
        video.setAttribute('preload', 'auto'); // Preload video to reduce delay in starting
        
        console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");
        
        // Ensure video plays when ready
        video.addEventListener('canplay', function() {
            video.play().catch(err => console.error("Error playing video " + (index + 1) + ": ", err));
        });

        // Error handling for video loading
        video.addEventListener('error', function(event) {
            console.error("Error loading video " + (index + 1), event);
        });
    });
}

function onThemeChange() {
    setTimeout(updateImageSource, 0);
}

function handleRouteChange() {
    updateCodeElements();
    updateImageSource();
    updateVideoSettings();

    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        themeToggleButton.addEventListener('click', onThemeChange);
    }
}

function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        handleRouteChange();
        setupRouteChangeHandler();
    };
}

</script>

<script>
function YourFunction() {
    updateCodeElements();   // Update icons and text content
    updateImageSource();    // Update the image source and filter based on the theme
    updateVideoSettings();  // Apply video settings like autoplay, mute, and preload
}

// Function to update code elements (icons, text trimming)
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

// Function to update image source and apply filter based on theme
function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        // Detect theme and apply corresponding filter
        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter applied.');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter removed.');
        }

        console.log('Image source successfully set.');
    } else {
        console.log('Target image not found.');
    }
}

// Function to update video settings (muted, autoplay, etc.)
function updateVideoSettings() {
    const videos = document.querySelectorAll('.notion-video video');
    
    videos.forEach(function(video, index) {
        video.muted = true;                // Mute video
        video.removeAttribute('controls'); // Remove controls
        video.loop = true;                 // Loop video
        video.style.borderRadius = '20px'; // Set border radius
        video.autoplay = true;             // Autoplay
        video.setAttribute('preload', 'auto'); // Preload to reduce delay

        console.log(`Video ${index + 1} settings applied: muted, looping, no controls.`);

        // Ensure video starts playing when it's ready
        video.addEventListener('canplay', function() {
            video.play().catch(err => console.error(`Error playing video ${index + 1}:`, err));
        });

        // Handle video loading errors
        video.addEventListener('error', function(event) {
            console.error(`Error loading video ${index + 1}:`, event);
        });
    });
}

// Theme change handler to dynamically update the image source and filter
function onThemeChange() {
    updateImageSource();
}

// Route change handler
const handleRouteChange = () => {
    YourFunction(); // Call the main function to update everything on route change
    listenForThemeToggle(); // Ensure the theme toggle button works properly
};

// Ensure theme toggle works without page refresh
function listenForThemeToggle() {
    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Prevent duplicate listeners
        themeToggleButton.addEventListener('click', onThemeChange);    // Add listener to handle theme change
    }
}

// Set up the route change handler and ensure videos are updated accordingly
const setupRouteChangeHandler = () => {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange); // Handle route changes
    } else {
        console.log('window.events.on is not available.');
    }
};

// Ensure the script runs on both initial page load and route changes
if (document.readyState === 'complete') {
    handleRouteChange();       // Trigger function on initial load
    setupRouteChangeHandler(); // Set up handling for route changes
} else {
    window.onload = () => {
        handleRouteChange();       // Trigger function when page is fully loaded
        setupRouteChangeHandler(); // Set up handling for route changes
    };
}
</script>
Hello
The way that Super works is that Scripts are loaded and run once, and not on page navigation to optimize the page speed, but you can trigger this to happen.
Please adapt your script using this:
<script>
function YourFunction() {
    // Add your function here as appropriate
};

const handleRouteChange = () => {
    YourFunction(); // Call your function(s) as required on route change
};

const setupRouteChangeHandler = () => {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
};

// Check if document is already loaded
if (document.readyState === 'complete') {
    handleRouteChange(); // Call your function on initial load if document is already complete
    setupRouteChangeHandler(); // Set up route change handling
} else {
    window.onload = () => {
        handleRouteChange(); // Call your function on initial load when window is loaded
        setupRouteChangeHandler(); // Set up route change handling
    };
}
</script>
function applyVideoSettings(video) {
    // Remove controls, mute the video, and set it to loop
    video.removeAttribute('controls');
    video.muted = true;
    video.loop = true;
    video.style.borderRadius = '20px';  // Apply corner radius
    video.autoplay = true;              // Autoplay
    video.setAttribute('preload', 'auto'); // Preload video
    
    console.log("Applied video settings: muted, looping, controls removed, and autoplay.");
    
    // Ensure video plays when ready
    video.addEventListener('canplay', function() {
        video.play().catch(err => console.error("Error playing video: ", err));
    });
    
    // Error handling for video loading issues
    video.addEventListener('error', function(event) {
        console.error("Error loading video: ", event);
    });
}



function handleRouteChange() {
    // Get all video elements
    const videos = document.querySelectorAll('.notion-video video');
    
    // Apply video settings for each video
    videos.forEach(function(video) {
        applyVideoSettings(video);
    });
    
    console.log("Route change handled and video settings applied.");
}

// Set up route change handling, which triggers on every route change
function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Ensure it runs on page load as well
if (document.readyState === 'complete') {
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        handleRouteChange();
        setupRouteChangeHandler();
    };
}
<script>
document.addEventListener('DOMContentLoaded', function() {
    var videos = document.querySelectorAll('.notion-video video');
    
    videos.forEach(function(video) {
        // Ensure video preloading and play behavior
        video.setAttribute('preload', 'auto');
        
        // Try to play the video when it's ready
        video.addEventListener('canplay', function() {
            video.play().catch(function(err) {
                console.error("Error playing video: ", err);
            });
        });
        
        // Handle video loading errors
        video.addEventListener('error', function(event) {
            console.error("Error loading video: ", event);
        });
        
        console.log("Video settings applied and play attempted on subpage.");
    });
});
</script>
<script>
// Function to apply video settings (muting, looping, etc.)
function applyVideoSettings(video) {
    video.removeAttribute('controls');  // Remove controls
    video.muted = true;                 // Mute video
    video.loop = true;                  // Loop video
    video.style.borderRadius = '20px';  // Apply corner radius
    video.autoplay = true;              // Set to autoplay
    video.setAttribute('preload', 'auto'); // Preload video
    
    // Ensure video plays when ready
    video.addEventListener('canplay', function() {
        video.play().catch(err => console.error("Error playing video:", err));
    });

    // Error handling for video loading
    video.addEventListener('error', function(event) {
        console.error("Error loading video:", event);
    });
}

// Update code elements (for example, add icons or adjust styles)
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

// Update image source based on the current theme
function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter applied.');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter removed.');
        }

        console.log('Image source successfully set.');
    } else {
        console.log('Target image not found.');
    }
}

// Handle theme toggle change
function onThemeChange() {
    updateImageSource();
}

// Handle route change and call the necessary functions
const handleRouteChange = () => {
    // Update code elements and image sources
    updateCodeElements();
    updateImageSource();

    // Apply video settings for each video
    const videos = document.querySelectorAll('.notion-video video');
    videos.forEach(function(video) {
        applyVideoSettings(video);
    });

    // Handle the theme toggle button event listener
    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        themeToggleButton.addEventListener('click', onThemeChange);    // Add new listener
    }
    
    console.log("Route change handled and all updates applied.");
};

// Setup route change handler
const setupRouteChangeHandler = () => {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
};

// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
    handleRouteChange();       // Call the function on initial load
    setupRouteChangeHandler(); // Set up route change handling
} else {
    window.onload = () => {
        handleRouteChange();       // Call the function on initial load when the window is loaded
        setupRouteChangeHandler(); // Set up route change handling
    };
}
</script>
window.onload = function() {
  var videos = document.querySelectorAll('.notion-video video');
  
  videos.forEach(function(video) {
    // Set attributes and styles for each video
    video.removeAttribute('controls');
    video.muted = true;
    video.loop = true;
    video.style.borderRadius = '20px';
    video.autoplay = true;

    // Preload video to reduce delay in starting
    video.setAttribute('preload', 'auto');

    console.log("Video is now muted and looping, and controls are removed.");
    
    // Listen for the video to be ready to play
    video.addEventListener('canplay', function() {
      video.play();
    });
  });
};
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />







<script>
  
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter set to: none');
        }

        if (targetImage.src === imageSrc) {
            console.log('Image source successfully set.');
        } else {
            console.log('Failed to set image source.');
        }
    } else {
        console.log('Target image not found.');
    }
}




function onThemeChange() {
    setTimeout(updateImageSource, 0);
}

function handleRouteChange() {
    updateCodeElements();
    updateImageSource();

    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        themeToggleButton.addEventListener('click', onThemeChange);
    }
}

function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        handleRouteChange();
        setupRouteChangeHandler();
    };
}

</script>


<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />







<script>
  
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter set to: none');
        }

        if (targetImage.src === imageSrc) {
            console.log('Image source successfully set.');
        } else {
            console.log('Failed to set image source.');
        }
    } else {
        console.log('Target image not found.');
    }
}




function onThemeChange() {
    setTimeout(updateImageSource, 0);
}

function updateVideoSettings() {
    const videos = document.querySelectorAll('.notion-video video');
    
    videos.forEach(function(video, index) {
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.autoplay = true;
        video.setAttribute('preload', 'auto'); // Preload video to reduce delay in starting
        
        console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");
        
        video.addEventListener('canplay', function() {
            video.play().catch(err => console.error("Error playing video " + (index + 1) + ": ", err));
        });

        video.addEventListener('error', function(event) {
            console.error("Error loading video " + (index + 1), event);
        });
    });
}



function handleRouteChange() {
    updateCodeElements();
    updateImageSource();
    updateVideoSettings();

    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        themeToggleButton.addEventListener('click', onThemeChange);
    }
}

function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        handleRouteChange();
        setupRouteChangeHandler();
    };
}

</script>


<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />







<script>
  
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter set to: none');
        }

        if (targetImage.src === imageSrc) {
            console.log('Image source successfully set.');
        } else {
            console.log('Failed to set image source.');
        }
    } else {
        console.log('Target image not found.');
    }
}




function onThemeChange() {
    setTimeout(updateImageSource, 0);
}

function updateVideoSettings() {
    const videos = document.querySelectorAll('.notion-video video');

    videos.forEach(function(video, index) {
        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting

        console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");
        
        // Force video to load its resource
        video.load();

        // Function to handle video play with fallback
        function tryPlayVideo() {
            video.play().then(() => {
                console.log("Video " + (index + 1) + " is playing.");
            }).catch(err => {
                console.error("Error playing video " + (index + 1) + ": ", err);
            });
        }

        // Add canplay and canplaythrough listeners
        video.addEventListener('canplay', function() {
            console.log("canplay event fired for video " + (index + 1));
            tryPlayVideo();  // Try playing when canplay is fired
        });

        video.addEventListener('canplaythrough', function() {
            console.log("canplaythrough event fired for video " + (index + 1));
            tryPlayVideo();  // Try playing when canplaythrough is fired
        });

        // Enhanced error handling for loading issues
        video.addEventListener('error', function(event) {
            console.error("Error loading video " + (index + 1), event);
            // Check the video's source to see if it's correctly set
            console.log("Video " + (index + 1) + " source: ", video.src);
        });

        // Try playing immediately after DOMContentLoaded
        document.addEventListener('DOMContentLoaded', function() {
            console.log("DOM fully loaded, trying to play video " + (index + 1));
            tryPlayVideo();
        });
    });
}

// Call the function to set up the videos
if (document.readyState === 'complete') {
    updateVideoSettings();
} else {
    window.addEventListener('load', function() {
        updateVideoSettings();
    });
}



function handleRouteChange() {
    updateCodeElements();
    updateImageSource();
    updateVideoSettings();

    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        themeToggleButton.addEventListener('click', onThemeChange);
    }
}

function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        handleRouteChange();
        setupRouteChangeHandler();
    };
}

</script>


function updateVideoSettings(maxPlayingVideos = 1) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];

    videos.forEach(function(video, index) {
        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
        video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
        video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions

        console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");

        // Event listener for when a video starts playing
        video.addEventListener('play', function() {
            // Add the current video to the list of playing videos
            currentlyPlaying.push(video);

            // If the number of playing videos exceeds the limit, pause the oldest one
            if (currentlyPlaying.length > maxPlayingVideos) {
                let videoToPause = currentlyPlaying.shift(); // Remove and get the oldest video
                videoToPause.pause();
                console.log("Paused a video to maintain limit.");
            }
        });

        // Event listener for when a video is paused
        video.addEventListener('pause', function() {
            // Remove the paused video from the currently playing list
            const index = currentlyPlaying.indexOf(video);
            if (index > -1) {
                currentlyPlaying.splice(index, 1);
            }
        });

        // Force video to load its resource
        video.load();
    });
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />







<script>
  
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter set to: none');
        }

        if (targetImage.src === imageSrc) {
            console.log('Image source successfully set.');
        } else {
            console.log('Failed to set image source.');
        }
    } else {
        console.log('Target image not found.');
    }
}




function onThemeChange() {
    setTimeout(updateImageSource, 0);
}



function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];

    // Create an Intersection Observer to detect when a video enters/exits the viewport
    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            // If the video is in the viewport
            if (entry.isIntersecting) {
                // Check if the video is not already playing
                if (currentlyPlaying.length < maxPlayingVideos && video.paused) {
                    video.play();
                    currentlyPlaying.push(video);
                    console.log("Playing video.");
                }
            } else {
                // If the video leaves the viewport, pause it
                if (!video.paused) {
                    video.pause();
                    console.log("Paused video because it left the viewport.");
                    const index = currentlyPlaying.indexOf(video);
                    if (index > -1) {
                        currentlyPlaying.splice(index, 1);
                    }
                }
            }
        });
    }, {
        threshold: 0.5 // Adjust this value to control how much of the video should be visible before playing
    });

    videos.forEach(function(video, index) {
        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
        video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
        video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions

        console.log("Video " + (index + 1) + " is now muted, looping, and controls are removed.");

        // Observe each video to detect when it enters/leaves the viewport
        observer.observe(video);
        
        
        
        
        // Force video to load its resource
        video.load();

        // Function to handle video play with fallback
        function tryPlayVideo() {
            video.play().then(() => {
                console.log("Video " + (index + 1) + " is playing.");
            }).catch(err => {
                console.error("Error playing video " + (index + 1) + ": ", err);
            });
        }

        // Add canplay and canplaythrough listeners
        video.addEventListener('canplay', function() {
            console.log("canplay event fired for video " + (index + 1));
            tryPlayVideo();  // Try playing when canplay is fired
        });


        // Enhanced error handling for loading issues
        video.addEventListener('error', function(event) {
            console.error("Error loading video " + (index + 1), event);
            // Check the video's source to see if it's correctly set
            console.log("Video " + (index + 1) + " source: ", video.src);
        });


    });
}








// Call the function to set up the videos
if (document.readyState === 'complete') {
    updateVideoSettings();
} else {
    window.addEventListener('load', function() {
        updateVideoSettings();
    });
}











function handleRouteChange() {
    updateCodeElements();
    updateImageSource();
    updateVideoSettings();

    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        themeToggleButton.addEventListener('click', onThemeChange);
    }
}

function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        handleRouteChange();
        setupRouteChangeHandler();
    };
}

</script>


function updateVideoSettings(maxPlayingVideos = 1) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];

    // Create an Intersection Observer to detect when a video enters/exits the viewport
    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            // If the video is in the viewport
            if (entry.isIntersecting) {
                // Start playing the video only when it's visible
                if (currentlyPlaying.length < maxPlayingVideos && video.paused) {
                    video.play(); // Start playing the video
                    currentlyPlaying.push(video);
                    console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");

                    // Optional: Remove the observer after the video starts playing if you don't want to track it further
                    observer.unobserve(video);
                }
            } else {
                // If the video leaves the viewport, pause it
                if (!video.paused) {
                    video.pause();
                    console.log("Paused video " + (Array.from(videos).indexOf(video) + 1) + " because it left the viewport.");
                    const index = currentlyPlaying.indexOf(video);
                    if (index > -1) {
                        currentlyPlaying.splice(index, 1);
                    }
                }
            }
        });
    }, {
        threshold: 0.5 // Adjust this value to control how much of the video should be visible before playing
    });

    videos.forEach(function(video, index) {
        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto'); // Start preloading the video on page load
        video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
        video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions

        console.log("Video " + (index + 1) + " is preloading but will not autoplay until it enters the viewport.");

        // Observe each video to detect when it enters/leaves the viewport
        observer.observe(video);
    });
}
function updateVideoSettings(maxPlayingVideos = 2) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];

    // Create an Intersection Observer to detect when a video is about to enter the viewport (starts preloading)
    const preloadObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            // Start preloading when the video is about to enter the viewport (50% visible)
            if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
                video.setAttribute('preload', 'auto'); // Start preloading the video
                console.log("Preloading video " + (Array.from(videos).indexOf(video) + 1) + " as it approaches the viewport.");
                preloadObserver.unobserve(video); // No need to keep observing for preload
            }
        });
    }, {
        threshold: 0.1 // Start preloading when 10% of the video is visible
    });

    // Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
    const playObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            // If the video is fully in the viewport
            if (entry.isIntersecting) {
                // Start playing the video only when it's fully visible
                if (currentlyPlaying.length < maxPlayingVideos && video.paused) {
                    video.play(); // Start playing the video
                    currentlyPlaying.push(video);
                    console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");

                    // Optional: Remove the observer after the video starts playing if you don't want to track it further
                    playObserver.unobserve(video);
                }
            } else {
                // If the video leaves the viewport, pause it
                if (!video.paused) {
                    video.pause();
                    console.log("Paused video " + (Array.from(videos).indexOf(video) + 1) + " because it left the viewport.");
                    const index = currentlyPlaying.indexOf(video);
                    if (index > -1) {
                        currentlyPlaying.splice(index, 1);
                    }
                }
            }
        });
    }, {
        threshold: 0.5 // Only play the video when at least 50% is visible
    });

    videos.forEach(function(video, index) {
        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
        video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
        video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions

        console.log("Video " + (index + 1) + " will preload and play based on viewport visibility.");

        // Observe each video to detect when it's approaching the viewport (for preloading)
        preloadObserver.observe(video);

        // Observe each video to detect when it fully enters/leaves the viewport (for playing/pausing)
        playObserver.observe(video);
    });
}
function updateVideoSettings(maxPlayingVideos = 2) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];

    // Create an Intersection Observer to detect when a video is about to enter the viewport (for loading)
    const preloadObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            // Start preloading when the video is about to enter the viewport (50% visible)
            if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
                video.setAttribute('preload', 'auto'); // Start preloading the video
                console.log("Preloading video " + (Array.from(videos).indexOf(video) + 1) + " as it approaches the viewport.");
                preloadObserver.unobserve(video); // No need to keep observing for preload
            }
        });
    }, {
        threshold: 0.1 // Start preloading when 10% of the video is visible
    });

    // Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
    const playObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            // If the video is in the viewport
            if (entry.isIntersecting) {
                // Start playing the video only when it's visible
                if (currentlyPlaying.length < maxPlayingVideos && video.paused) {
                    video.play(); // Start playing the video
                    currentlyPlaying.push(video);
                    console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");

                    // Optional: Remove the observer after the video starts playing if you don't want to track it further
                    playObserver.unobserve(video);
                }
            } else {
                // When the video leaves the viewport, we don't pause it to allow it to keep loading
                console.log("Video " + (Array.from(videos).indexOf(video) + 1) + " is still loading even though it left the viewport.");
                // Remove it from currently playing but allow it to keep buffering or loading in the background
                const index = currentlyPlaying.indexOf(video);
                if (index > -1) {
                    currentlyPlaying.splice(index, 1);
                }
            }
        });
    }, {
        threshold: 0.5 // Only play the video when at least 50% is visible
    });

    videos.forEach(function(video, index) {
        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
        video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
        video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions

        console.log("Video " + (index + 1) + " will preload and play based on viewport visibility.");

        // Observe each video to detect when it's approaching the viewport (for preloading)
        preloadObserver.observe(video);

        // Observe each video to detect when it fully enters/leaves the viewport (for playing)
        playObserver.observe(video);
    });
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />







<script>
  
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter set to: none');
        }

        if (targetImage.src === imageSrc) {
            console.log('Image source successfully set.');
        } else {
            console.log('Failed to set image source.');
        }
    } else {
        console.log('Target image not found.');
    }
}




function onThemeChange() {
    setTimeout(updateImageSource, 0);
}



function updateVideoSettings(maxPlayingVideos = 2) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];

    // Create an Intersection Observer to detect when a video is about to enter the viewport (for loading)
    const preloadObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            // Start preloading when the video is about to enter the viewport (50% visible)
            if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
                video.setAttribute('preload', 'auto'); // Start preloading the video
                console.log("Preloading video " + (Array.from(videos).indexOf(video) + 1) + " as it approaches the viewport.");
                preloadObserver.unobserve(video); // No need to keep observing for preload
            }
        });
    }, {
        threshold: 0.1 // Start preloading when 10% of the video is visible
    });

    // Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
    const playObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            // If the video is in the viewport
            if (entry.isIntersecting) {
                // Start playing the video only when it's visible
                if (currentlyPlaying.length < maxPlayingVideos && video.paused) {
                    video.play(); // Start playing the video
                    currentlyPlaying.push(video);
                    console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");

                    // Optional: Remove the observer after the video starts playing if you don't want to track it further
                    playObserver.unobserve(video);
                }
            } else {
                // When the video leaves the viewport, we don't pause it to allow it to keep loading
                console.log("Video " + (Array.from(videos).indexOf(video) + 1) + " is still loading even though it left the viewport.");
                // Remove it from currently playing but allow it to keep buffering or loading in the background
                const index = currentlyPlaying.indexOf(video);
                if (index > -1) {
                    currentlyPlaying.splice(index, 1);
                }
            }
        });
    }, {
        threshold: 0.5 // Only play the video when at least 50% is visible
    });

    videos.forEach(function(video, index) {
        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
        video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
        video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions

        console.log("Video " + (index + 1) + " will preload and play based on viewport visibility.");

        // Observe each video to detect when it's approaching the viewport (for preloading)
        preloadObserver.observe(video);

        // Observe each video to detect when it fully enters/leaves the viewport (for playing)
        playObserver.observe(video);

        





        // Function to handle video play with fallback
        function tryPlayVideo() {
            video.play().then(() => {
                console.log("Video " + (index + 1) + " is playing.");
            }).catch(err => {
                console.error("Error playing video " + (index + 1) + ": ", err);
            });
        }

        // Add canplay and canplaythrough listeners
        video.addEventListener('canplay', function() {
            console.log("canplay event fired for video " + (index + 1));
            tryPlayVideo();  // Try playing when canplay is fired
        });


        // Enhanced error handling for loading issues
        video.addEventListener('error', function(event) {
            console.error("Error loading video " + (index + 1), event);
            // Check the video's source to see if it's correctly set
            console.log("Video " + (index + 1) + " source: ", video.src);
        });


    });
}








// Call the function to set up the videos
if (document.readyState === 'complete') {
    updateVideoSettings();
} else {
    window.addEventListener('load', function() {
        updateVideoSettings();
    });
}











function handleRouteChange() {
    updateCodeElements();
    updateImageSource();
    updateVideoSettings();

    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        themeToggleButton.addEventListener('click', onThemeChange);
    }
}

function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        handleRouteChange();
        setupRouteChangeHandler();
    };
}

</script>


function updateVideoSettings(maxPlayingVideos = 2) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];

    // Track videos that have finished loading
    const fullyLoadedVideos = new Set();

    // Create an Intersection Observer to detect when a video is about to enter the viewport (for loading)
    const preloadObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            // Start preloading when the video is about to enter the viewport (50% visible)
            if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
                video.setAttribute('preload', 'auto'); // Start preloading the video
                console.log("Preloading video " + (Array.from(videos).indexOf(video) + 1) + " as it approaches the viewport.");
                preloadObserver.unobserve(video); // No need to keep observing for preload
            }
        });
    }, {
        threshold: 0.1 // Start preloading when 10% of the video is visible
    });

    // Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
    const playObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            // If the video is in the viewport
            if (entry.isIntersecting) {
                // Start playing the video only if it's fully loaded and visible
                if (fullyLoadedVideos.has(video) && currentlyPlaying.length < maxPlayingVideos && video.paused) {
                    video.play(); // Start playing the video
                    currentlyPlaying.push(video);
                    console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");
                }
            } else {
                // Pause the video only if it has finished loading
                if (fullyLoadedVideos.has(video) && !video.paused) {
                    video.pause();
                    console.log("Paused video " + (Array.from(videos).indexOf(video) + 1) + " because it left the viewport after loading.");
                    const index = currentlyPlaying.indexOf(video);
                    if (index > -1) {
                        currentlyPlaying.splice(index, 1);
                    }
                }
            }
        });
    }, {
        threshold: 0.5 // Only play/pause the video when at least 50% is visible
    });

    videos.forEach(function(video, index) {
        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
        video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
        video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions

        console.log("Video " + (index + 1) + " will preload and play based on viewport visibility.");

        // Listen for the 'canplaythrough' event, which indicates the video has finished loading
        video.addEventListener('canplaythrough', function() {
            fullyLoadedVideos.add(video); // Mark the video as fully loaded
            console.log("Video " + (index + 1) + " has finished loading.");
        });

        // Observe each video to detect when it's approaching the viewport (for preloading)
        preloadObserver.observe(video);

        // Observe each video to detect when it fully enters/leaves the viewport (for playing/pausing)
        playObserver.observe(video);
    });
}
function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];
    const fullyLoadedVideos = new Set();

    // Create an Intersection Observer to detect when a video is about to enter the viewport (for loading)
    const preloadObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
                video.setAttribute('preload', 'auto');
                console.log("Preloading video " + (Array.from(videos).indexOf(video) + 1) + " as it approaches the viewport.");
                preloadObserver.unobserve(video); // No need to keep observing for preload
            }
        });
    }, {
        threshold: 0.1 // Start preloading when 10% of the video is visible
    });

    // Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
    const playObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            if (entry.isIntersecting) {
                if (fullyLoadedVideos.has(video) && currentlyPlaying.length < maxPlayingVideos && video.paused) {
                    video.play();
                    currentlyPlaying.push(video);
                    console.log("Playing video " + (Array.from(videos).indexOf(video) + 1) + " because it entered the viewport.");
                }
            } else {
                if (fullyLoadedVideos.has(video) && !video.paused) {
                    video.pause();
                    console.log("Paused video " + (Array.from(videos).indexOf(video) + 1) + " because it left the viewport after loading.");
                    const index = currentlyPlaying.indexOf(video);
                    if (index > -1) {
                        currentlyPlaying.splice(index, 1);
                    }
                }
            }
        });
    }, {
        threshold: 0.1 // Lower threshold to play when 10% is visible
    });

    videos.forEach(function(video, index) {
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
        video.setAttribute('playsinline', 'true'); 
        video.setAttribute('webkit-playsinline', 'true'); 

        // Listen for the 'canplay' event (fired earlier than 'canplaythrough')
        video.addEventListener('canplay', function() {
            fullyLoadedVideos.add(video);
            console.log("Video " + (index + 1) + " is ready to play.");
        });

        preloadObserver.observe(video);
        playObserver.observe(video);
    });
}
function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];
    const fullyLoadedVideos = new Set();

    // Helper function to check if the video is in the viewport
    function isInViewport(video) {
        const rect = video.getBoundingClientRect();
        return (
            rect.top >= 0 &&
            rect.left >= 0 &&
            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
            rect.right <= (window.innerWidth || document.documentElement.clientWidth)
        );
    }

    // Function to play the video if it is in the viewport and fully loaded
    function attemptPlay(video, index) {
        if (isInViewport(video) && currentlyPlaying.length < maxPlayingVideos && video.paused) {
            video.play();
            currentlyPlaying.push(video);
            console.log(`Playing video ${index + 1} because it is in the viewport and fully loaded.`);
        }
    }

    // Create an Intersection Observer to detect when a video is about to enter the viewport (for loading)
    const preloadObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            if (entry.isIntersecting && video.getAttribute('preload') === 'none') {
                video.setAttribute('preload', 'auto');
                console.log(`Preloading video ${Array.from(videos).indexOf(video) + 1} as it approaches the viewport.`);
                preloadObserver.unobserve(video); // No need to keep observing for preload
            }
        });
    }, {
        threshold: 0.1 // Start preloading when 10% of the video is visible
    });

    // Create an Intersection Observer to detect when a video fully enters/exits the viewport (for playing)
    const playObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;
            const index = Array.from(videos).indexOf(video); // Get the index of the video

            if (entry.isIntersecting) {
                console.log(`Video ${index + 1} entered the viewport.`);
                // Try to play the video if it's fully loaded
                attemptPlay(video, index);
            } else {
                if (!video.paused && fullyLoadedVideos.has(video)) {
                    video.pause();
                    console.log(`Paused video ${index + 1} because it left the viewport after loading.`);
                    const currentlyPlayingIndex = currentlyPlaying.indexOf(video);
                    if (currentlyPlayingIndex > -1) {
                        currentlyPlaying.splice(currentlyPlayingIndex, 1);
                    }
                }
            }
        });
    }, {
        threshold: 0.1 // Lower threshold to play when 10% is visible
    });

    videos.forEach(function(video, index) {
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'none'); // Do not preload until it approaches the viewport
        video.setAttribute('playsinline', 'true'); 
        video.setAttribute('webkit-playsinline', 'true'); 

        // Troubleshooting for 'canplaythrough' event and auto-play when fully loaded and in viewport
        video.addEventListener('canplaythrough', function() {
            fullyLoadedVideos.add(video);
            console.log(`canplaythrough event fired for video ${index + 1}. Video is fully buffered and ready to play.`);

            // Try to play the video as soon as it finishes buffering if it's in the viewport
            attemptPlay(video, index);
        });

        // Observe each video to detect when it's approaching the viewport (for preloading)
        preloadObserver.observe(video);

        // Observe each video to detect when it fully enters/leaves the viewport (for playing/pausing)
        playObserver.observe(video);
    });
}
function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];
    const fullyLoadedVideos = new Set(); // Videos that have fired canplay
    const partiallyLoadedVideos = new Set(); // Videos that are still loading

    // Helper function to check if the video is in the viewport
    function isInViewport(video) {
        const rect = video.getBoundingClientRect();
        return (
            rect.top >= 0 &&
            rect.left >= 0 &&
            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
            rect.right <= (window.innerWidth || document.documentElement.clientWidth)
        );
    }

    // Function to play the video if it is in the viewport and fully loaded
    function attemptPlay(video, index) {
        if (isInViewport(video) && currentlyPlaying.length < maxPlayingVideos && video.paused) {
            video.play();
            currentlyPlaying.push(video);
            console.log(`Playing video ${index + 1} because it is in the viewport and fully loaded.`);
        }
    }

    // Intersection Observer to detect when the video is about to enter the viewport
    const observer = new IntersectionObserver((entries, observer) => {
        entries.forEach(entry => {
            const video = entry.target;
            const index = Array.from(videos).indexOf(video);

            // If the video is about to enter the viewport (e.g., 50% visible)
            if (entry.isIntersecting) {
                console.log(`Video ${index + 1} is about to enter the viewport.`);

                // If the video is fully loaded, try to play it
                if (fullyLoadedVideos.has(video)) {
                    attemptPlay(video, index);
                } else if (!fullyLoadedVideos.has(video)) {
                    // If the video isn't fully loaded, keep loading and remove observer
                    partiallyLoadedVideos.add(video);
                    console.log(`Video ${index + 1} is still loading, keeping it in memory to load.`);
                }
            } else {
                // When the video is out of the viewport, stop observing but allow it to keep loading
                if (!fullyLoadedVideos.has(video)) {
                    // If video is not fully loaded, allow it to keep loading but stop observing
                    observer.unobserve(video);
                    console.log(`Stopped observing video ${index + 1}, it is out of the viewport but will keep loading.`);
                } else if (fullyLoadedVideos.has(video)) {
                    // Pause the video if it was playing and is fully loaded
                    if (!video.paused) {
                        video.pause();
                        console.log(`Paused video ${index + 1} because it left the viewport.`);
                        const currentlyPlayingIndex = currentlyPlaying.indexOf(video);
                        if (currentlyPlayingIndex > -1) {
                            currentlyPlaying.splice(currentlyPlayingIndex, 1);
                        }
                    }
                }
            }
        });
    }, {
        threshold: 0.5 // Detect when 50% of the video is visible (about to enter viewport)
    });

    // Iterate over all videos and apply event listeners
    videos.forEach(function(video, index) {
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'none'); // Delay preloading until it's in the viewport
        video.setAttribute('playsinline', 'true'); 
        video.setAttribute('webkit-playsinline', 'true'); 

        // Event listener for 'canplay' event (fired when enough data is buffered to start)
        video.addEventListener('canplay', function() {
            fullyLoadedVideos.add(video);
            console.log(`canplay event fired for video ${index + 1}. Video is ready to play.`);
            attemptPlay(video, index); // Attempt to play immediately if it is ready and in the viewport
        });

        // Use the observer to detect when the video is about to enter the viewport
        observer.observe(video);
    });
}
function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];
    let firstVideoPlayed = false; // Flag to track the first video play
    
    // Create an Intersection Observer to detect when a video enters/exits the viewport
    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            const video = entry.target;

            // If the video is in the viewport
            if (entry.isIntersecting) {
                if (video.readyState >= 3) {  // If the video has enough data to play
                    playVideo(video);
                } else {
                    console.log("Video " + video.src + " has not finished loading but is in the viewport.");
                }
            } else {
                // If the video leaves the viewport, pause it
                if (!video.paused) {
                    pauseVideo(video, false);
                    console.log("Paused video " + video.src + " because it left the viewport.");
                }
            }
        });
    }, {
        threshold: 0.1 // Adjust this value to control how much of the video should be visible before playing
    });

    videos.forEach(function(video, index) {
        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
        video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
        video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions

        console.log("Video " + (index + 1) + " is set up for autoplay, muted, and looped.");

        // If it's the first video, play it immediately after preloading
        if (index === 0 && !firstVideoPlayed) {
            video.load();
            video.addEventListener('canplay', () => {
                playVideo(video);
                console.log("First video " + video.src + " is playing immediately after preloading.");
                firstVideoPlayed = true;
            });
        } else {
            // For other videos, observe when they enter/leave the viewport
            observer.observe(video);
            video.load();  // Preload the video when the page is loaded
        }

        // Play video logic
        function playVideo(video) {
            if (!currentlyPlaying.includes(video)) {
                video.play().then(() => {
                    console.log("Video " + video.src + " is playing.");
                    currentlyPlaying.push(video);
                }).catch(err => {
                    console.error("Error playing video " + video.src + ": ", err);
                    // Allow user to manually play the video if it failed to autoplay
                    video.addEventListener('click', () => {
                        toggleVideoPlayPause(video);
                    });
                });
            }
        }

        // Pause video logic, with manual flag to track if paused by user
        function pauseVideo(video, userPaused) {
            if (!video.paused) {
                video.pause();
                console.log("Video " + video.src + " is paused.");
                if (userPaused) {
                    console.log("Video " + video.src + " was paused by the user.");
                }
                const index = currentlyPlaying.indexOf(video);
                if (index > -1) {
                    currentlyPlaying.splice(index, 1);
                }
            }
        }

        // Toggle play/pause for manual control
        function toggleVideoPlayPause(video) {
            if (video.paused) {
                playVideo(video);
            } else {
                pauseVideo(video, true);
            }
        }

        // Video loaded event
        video.addEventListener('canplaythrough', function() {
            console.log("Video " + (index + 1) + " has fully loaded and is ready for playback.");
        });

        // Looping video, video will restart automatically after finishing
        video.addEventListener('ended', function() {
            console.log("Video " + (index + 1) + " finished playing and will loop.");
            playVideo(video); // Automatically play the video again as it is looped
        });

        // Enhanced error handling for loading issues
        video.addEventListener('error', function(event) {
            console.error("Error loading video " + (index + 1), event);
            // Check the video's source to see if it's correctly set
            console.log("Video " + (index + 1) + " source: ", video.src);
        });

        // Allow user to manually control play/pause by clicking on the video
        video.addEventListener('click', function() {
            toggleVideoPlayPause(video);
        });
    });
}

// Call the function to set up the videos
if (document.readyState === 'complete') {
    updateVideoSettings();
} else {
    window.addEventListener('load', function() {
        updateVideoSettings();
    });
}
function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];
    let firstVideoPlayed = false;

    console.log("Initializing IntersectionObserver...");
    
    // Create an Intersection Observer to detect when a video enters/exits the viewport
    const observer = new IntersectionObserver((entries) => {
        console.log("Observer callback triggered. Checking entries...");
        entries.forEach(entry => {
            const video = entry.target;

            // Log the intersection ratio and whether the video is intersecting
            console.log(`Video ${video.src} intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
            
            // If the video is in the viewport
            if (entry.isIntersecting) {
                if (video.readyState >= 3) {  // If the video has enough data to play
                    playVideo(video);
                } else {
                    console.log("Video " + video.src + " is in the viewport but has not finished loading.");
                    // Add canplay event listener in case it finishes loading
                    video.addEventListener('canplay', () => {
                        console.log("Video " + video.src + " has finished loading in the viewport, starting playback.");
                        playVideo(video);
                    });
                }
            } else {
                // If the video leaves the viewport, pause it
                if (!video.paused) {
                    pauseVideo(video);
                    console.log("Paused video " + video.src + " because it left the viewport.");
                }
            }
        });
    }, {
        threshold: 0.1 // Adjust this value to control how much of the video should be visible before playing
    });

    videos.forEach(function(video, index) {
        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
        video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
        video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions

        console.log("Video " + (index + 1) + " is set up for autoplay, muted, and looped.");

        // If it's the first video, play it immediately after preloading
        if (index === 0 && !firstVideoPlayed) {
            video.load();
            video.addEventListener('canplay', () => {
                playVideo(video);
                console.log("First video " + video.src + " is playing immediately after preloading.");
                firstVideoPlayed = true;
            });
        } else {
            // For other videos, observe when they enter/leave the viewport
            console.log("Observing video " + (index + 1) + " for intersection changes.");
            observer.observe(video); // Start observing the video
            video.load();  // Preload the video when the page is loaded
        }

        // Allow user to manually control play/pause by clicking on the video
        video.addEventListener('click', function() {
            toggleVideoPlayPause(video);
        });

        // Video loaded event
        video.addEventListener('canplaythrough', function() {
            console.log("Video " + (index + 1) + " has fully loaded and is ready for playback.");
        });

        // Looping video, video will restart automatically after finishing
        video.addEventListener('ended', function() {
            console.log("Video " + (index + 1) + " finished playing and will loop.");
            playVideo(video); // Automatically play the video again as it is looped
        });

        // Enhanced error handling for loading issues
        video.addEventListener('error', function(event) {
            console.error("Error loading video " + (index + 1), event);
            console.log("Video " + (index + 1) + " source: ", video.src);
        });
    });

    // Play video logic
    function playVideo(video) {
        if (!currentlyPlaying.includes(video)) {
            video.play().then(() => {
                console.log("Video " + video.src + " is playing.");
                currentlyPlaying.push(video);
            }).catch(err => {
                console.error("Error playing video " + video.src + ": ", err);
            });
        }
    }

    // Pause video logic
    function pauseVideo(video) {
        if (!video.paused) {
            video.pause();
            console.log("Video " + video.src + " is paused.");
            const index = currentlyPlaying.indexOf(video);
            if (index > -1) {
                currentlyPlaying.splice(index, 1);
            }
        }
    }

    // Toggle play/pause for manual control
    function toggleVideoPlayPause(video) {
        if (video.paused) {
            playVideo(video);
        } else {
            pauseVideo(video);
        }
    }
}

// Call the function to set up the videos
if (document.readyState === 'complete') {
    updateVideoSettings();
} else {
    window.addEventListener('load', function() {
        updateVideoSettings();
    });
}
function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];
    let firstVideoPlayed = false;

    console.log("Initializing IntersectionObserver...");

    // Create an Intersection Observer to detect when a video enters/exits the viewport
    const observer = new IntersectionObserver((entries) => {
        console.log("Observer callback triggered. Checking entries...");
        entries.forEach(entry => {
            const video = entry.target;
            const videoIndex = video.dataset.index; // Use data attribute to get the video index

            // Log the intersection ratio and whether the video is intersecting
            console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
            
            // If the video is in the viewport
            if (entry.isIntersecting) {
                if (video.readyState >= 3) {  // If the video has enough data to play
                    playVideo(video, videoIndex);
                } else {
                    console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
                    // Add canplay event listener in case it finishes loading
                    video.addEventListener('canplay', () => {
                        console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
                        playVideo(video, videoIndex);
                    });
                }
            } else {
                // If the video leaves the viewport, pause it
     
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />







<script>
  
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter set to: none');
        }

        if (targetImage.src === imageSrc) {
            console.log('Image source successfully set.');
        } else {
            console.log('Failed to set image source.');
        }
    } else {
        console.log('Target image not found.');
    }
}




function onThemeChange() {
    setTimeout(updateImageSource, 0);
}

function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];
    let firstVideoPlayed = false;

    console.log("Initializing IntersectionObserver...");

    // Create an Intersection Observer to detect when a video enters/exits the viewport
    const observer = new IntersectionObserver((entries) => {
        console.log("Observer callback triggered. Checking entries...");
        entries.forEach(entry => {
            const video = entry.target;
            const videoIndex = video.dataset.index; // Use data attribute to get the video index

            // Log the intersection ratio and whether the video is intersecting
            console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
            
            // If the video is in the viewport
            if (entry.isIntersecting) {
                if (video.readyState >= 3) {  // If the video has enough data to play
                    playVideo(video, videoIndex);
                } else {
                    console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
                    // Add canplay event listener in case it finishes loading
                    video.addEventListener('canplay', () => {
                        console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
                        playVideo(video, videoIndex);
                    });
                }
            } else {
                // If the video leaves the viewport, pause it
                if (!video.paused) {
                    pauseVideo(video, videoIndex);
                    console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
                }
            }
        });
    }, {
        threshold: 0.1 // Adjust this value to control how much of the video should be visible before playing
    });

    videos.forEach(function(video, index) {
        // Set a data attribute for the video index
        video.dataset.index = index + 1;

        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
        video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
        video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions

        console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);

        // If it's the first video, play it immediately after preloading
        if (index === 0 && !firstVideoPlayed) {
            video.load();
            video.addEventListener('canplay', () => {
                playVideo(video, index + 1);
                console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
                firstVideoPlayed = true;
            });
        } else {
            // For other videos, observe when they enter/leave the viewport
            console.log(`Observing video ${index + 1} for intersection changes.`);
            observer.observe(video); // Start observing the video
            video.load();  // Preload the video when the page is loaded
        }

        // Allow user to manually control play/pause by clicking on the video
        video.addEventListener('click', function() {
            toggleVideoPlayPause(video, index + 1);
        });

        // Video loaded event
        video.addEventListener('canplaythrough', function() {
            console.log(`Video ${index + 1} (src: ${video.src}) has fully loaded and is ready for playback.`);
        });

        // Looping video, video will restart automatically after finishing
        video.addEventListener('ended', function() {
            console.log(`Video ${index + 1} (src: ${video.src}) finished playing and will loop.`);
            playVideo(video, index + 1); // Automatically play the video again as it is looped
        });

        // Enhanced error handling for loading issues
        video.addEventListener('error', function(event) {
            console.error(`Error loading video ${index + 1} (src: ${video.src}): `, event);
        });
    });

    // Play video logic
    function playVideo(video, videoIndex) {
        if (!currentlyPlaying.includes(video)) {
            video.play().then(() => {
                console.log(`Video ${videoIndex} (src: ${video.src}) is playing.`);
                currentlyPlaying.push(video);
            }).catch(err => {
                console.error(`Error playing video ${videoIndex} (src: ${video.src}): `, err);
            });
        }
    }

    // Pause video logic
    function pauseVideo(video, videoIndex) {
        if (!video.paused) {
            video.pause();
            console.log(`Video ${videoIndex} (src: ${video.src}) is paused.`);
            const index = currentlyPlaying.indexOf(video);
            if (index > -1) {
                currentlyPlaying.splice(index, 1);
            }
        }
    }

    // Toggle play/pause for manual control
    function toggleVideoPlayPause(video, videoIndex) {
        if (video.paused) {
            playVideo(video, videoIndex);
        } else {
            pauseVideo(video, videoIndex);
        }
    }
}

// Call the function to set up the videos
if (document.readyState === 'complete') {
    updateVideoSettings();
} else {
    window.addEventListener('load', function() {
        updateVideoSettings();
    });
}






function handleRouteChange() {
    updateCodeElements();
    updateImageSource();
    updateVideoSettings();

    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        themeToggleButton.addEventListener('click', onThemeChange);
    }
}

function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        handleRouteChange();
        setupRouteChangeHandler();
    };
}

</script>


function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];
    let firstVideoPlayed = false;

    console.log("Initializing IntersectionObserver...");

    // Create an Intersection Observer to detect when a video enters/exits the viewport
    const observer = new IntersectionObserver((entries) => {
        console.log("Observer callback triggered. Checking entries...");
        entries.forEach(entry => {
            const video = entry.target;
            const videoIndex = video.dataset.index; // Use data attribute to get the video index

            // Log the intersection ratio and whether the video is intersecting
            console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
            
            // If the video is in the viewport
            if (entry.isIntersecting) {
                if (video.readyState >= 3) {  // If the video has enough data to play
                    playVideo(video, videoIndex);
                } else {
                    console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
                    // Add canplay event listener in case it finishes loading
                    video.addEventListener('canplay', () => {
                        console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
                        playVideo(video, videoIndex);
                    });
                }
            } else {
                // If the video leaves the viewport, pause it
                if (!video.paused) {
                    pauseVideo(video, videoIndex);
                    console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
                }
            }
        });
    }, {
        threshold: 0.1 // Adjust this value to control how much of the video should be visible before playing
    });

    videos.forEach(function(video, index) {
        // Set a data attribute for the video index
        video.dataset.index = index + 1;

        // Set video attributes
        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto'); // Preload to reduce delay in starting
        video.setAttribute('playsinline', 'true'); // Prevent fullscreen on mobile Safari
        video.setAttribute('webkit-playsinline', 'true'); // For older iOS versions

        console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);

        // If it's the first video, play it immediately after preloading
        if (index === 0 && !firstVideoPlayed) {
            video.load();
            video.addEventListener('canplay', () => {
                playVideo(video, index + 1);
                console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
                firstVideoPlayed = true;
            });
        } else {
            // For other videos, observe when they enter/leave the viewport
            console.log(`Observing video ${index + 1} for intersection changes.`);
            observer.observe(video); // Start observing the video
            video.load();  // Preload the video when the page is loaded
        }

        // Allow user to manually control play/pause by clicking on the video
        video.addEventListener('click', function() {
            toggleVideoPlayPause(video, index + 1);
        });

        // Video loaded event
        video.addEventListener('canplaythrough', function() {
            console.log(`Video ${index + 1} (src: ${video.src}) has fully loaded and is ready for playback.`);
        });

        // Looping video, video will restart automatically after finishing
        video.addEventListener('ended', function() {
            console.log(`Video ${index + 1} (src: ${video.src}) finished playing and will loop.`);
            playVideo(video, index + 1); // Automatically play the video again as it is looped
        });

        // Enhanced error handling for loading issues
        video.addEventListener('error', function(event) {
            console.error(`Error loading video ${index + 1} (src: ${video.src}): `, event);
        });
    });

    // Play video logic
    function playVideo(video, videoIndex) {
        if (!currentlyPlaying.includes(video)) {
            video.play().then(() => {
                console.log(`Video ${videoIndex} (src: ${video.src}) is playing.`);
                currentlyPlaying.push(video);
            }).catch(err => {
                console.error(`Error playing video ${videoIndex} (src: ${video.src}): `, err);
            });
        }
    }

    // Pause video logic
    function pauseVideo(video, videoIndex) {
        if (!video.paused) {
            video.pause();
            console.log(`Video ${videoIndex} (src: ${video.src}) is paused.`);
            const index = currentlyPlaying.indexOf(video);
            if (index > -1) {
                currentlyPlaying.splice(index, 1);
            }
        }
    }

    // Toggle play/pause for manual control
    function toggleVideoPlayPause(video, videoIndex) {
        if (video.paused) {
            playVideo(video, videoIndex);
        } else {
            pauseVideo(video, videoIndex);
        }
    }
}

// Call the function to set up the videos
if (document.readyState === 'complete') {
    updateVideoSettings();
} else {
    window.addEventListener('load', function() {
        updateVideoSettings();
    });
}
let observer; // Define the observer globally to manage its lifecycle

function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];
    let firstVideoPlayed = false;

    console.log("Initializing IntersectionObserver...");

    // If there's an existing observer, disconnect it to prevent duplication
    if (observer) {
        console.log("Disconnecting previous IntersectionObserver to avoid duplication.");
        observer.disconnect();
    }

    // Create a new Intersection Observer
    observer = new IntersectionObserver((entries) => {
        console.log("Observer callback triggered. Checking entries...");
        entries.forEach(entry => {
            const video = entry.target;
            const videoIndex = video.dataset.index;

            // Log the intersection ratio and whether the video is intersecting
            console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
            
            if (entry.isIntersecting) {
                if (video.readyState >= 3) {
                    playVideo(video, videoIndex);
                } else {
                    console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
                    video.addEventListener('canplay', () => {
                        console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
                        playVideo(video, videoIndex);
                    }, { once: true }); // Ensure the listener is only added once
                }
            } else {
                if (!video.paused) {
                    pauseVideo(video, videoIndex);
                    console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
                }
            }
        });
    }, {
        threshold: 0.1
    });

    videos.forEach(function(video, index) {
        video.dataset.index = index + 1;

        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto');
        video.setAttribute('playsinline', 'true');
        video.setAttribute('webkit-playsinline', 'true');

        console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);

        if (index === 0 && !firstVideoPlayed) {
            video.load();
            video.addEventListener('canplay', () => {
                playVideo(video, index + 1);
                console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
                firstVideoPlayed = true;
            });
        } else {
            observer.observe(video);
            video.load();
        }

        // Log whenever a click event listener is added
        console.log(`Attaching click event listener to video ${index + 1}`);
        
        // Remove any existing click listeners before adding new ones to avoid duplication
        video.removeEventListener('click', () => toggleVideoPlayPause(video, index + 1));
        
        // Add click listener to toggle play/pause
        video.addEventListener('click', () => {
            console.log(`Click event triggered for video ${index + 1}`);
            toggleVideoPlayPause(video, index + 1);
        });
    });

    function playVideo(video, videoIndex) {
        if (!currentlyPlaying.includes(video)) {
            video.play().then(() => {
                console.log(`Video ${videoIndex} (src: ${video.src}) is playing.`);
                currentlyPlaying.push(video);
            }).catch(err => {
                console.error(`Error playing video ${videoIndex} (src: ${video.src}): `, err);
            });
        }
    }

    function pauseVideo(video, videoIndex) {
        if (!video.paused) {
            video.pause();
            console.log(`Video ${videoIndex} (src: ${video.src}) is paused.`);
            const index = currentlyPlaying.indexOf(video);
            if (index > -1) {
                currentlyPlaying.splice(index, 1);
            }
        }
    }

    function toggleVideoPlayPause(video, videoIndex) {
        if (video.paused) {
            playVideo(video, videoIndex);
        } else {
            pauseVideo(video, videoIndex);
        }
    }
}

function handleRouteChange() {
    console.log('Route change detected, updating elements and listeners.');

    updateCodeElements();  // Assuming this updates code elements
    updateImageSource();   // Assuming this updates image sources
    updateVideoSettings(); // Updating video settings and listeners

    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        console.log('Attaching theme change event listener to the toggle button.');
        themeToggleButton.addEventListener('click', onThemeChange);
    }
}

function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        console.log('Listening for route changes using window.events.on.');
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
    console.log('Document is fully loaded.');
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        console.log('Window onload event fired.');
        handleRouteChange();
        setupRouteChangeHandler();
    };
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />







<script>
  
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter set to: none');
        }

        if (targetImage.src === imageSrc) {
            console.log('Image source successfully set.');
        } else {
            console.log('Failed to set image source.');
        }
    } else {
        console.log('Target image not found.');
    }
}




function onThemeChange() {
    setTimeout(updateImageSource, 0);
}








let observer; // Define the observer globally to manage its lifecycle

function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let currentlyPlaying = [];
    let firstVideoPlayed = false;

    console.log("Initializing IntersectionObserver...");

    // If there's an existing observer, disconnect it to prevent duplication
    if (observer) {
        console.log("Disconnecting previous IntersectionObserver to avoid duplication.");
        observer.disconnect();
    }

    // Create a new Intersection Observer
    observer = new IntersectionObserver((entries) => {
        console.log("Observer callback triggered. Checking entries...");
        entries.forEach(entry => {
            const video = entry.target;
            const videoIndex = video.dataset.index;

            // Log the intersection ratio and whether the video is intersecting
            console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
            
            if (entry.isIntersecting) {
                if (video.readyState >= 3) {
                    playVideo(video, videoIndex);
                } else {
                    console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
                    video.addEventListener('canplay', () => {
                        console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
                        playVideo(video, videoIndex);
                    }, { once: true }); // Ensure the listener is only added once
                }
            } else {
                if (!video.paused) {
                    pauseVideo(video, videoIndex);
                    console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
                }
            }
        });
    }, {
        threshold: 0.1
    });

    videos.forEach(function(video, index) {
        video.dataset.index = index + 1;

        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto');
        video.setAttribute('playsinline', 'true');
        video.setAttribute('webkit-playsinline', 'true');

        console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);

        if (index === 0 && !firstVideoPlayed) {
            video.load();
            video.addEventListener('canplay', () => {
                playVideo(video, index + 1);
                console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
                firstVideoPlayed = true;
            });
        } else {
            observer.observe(video);
            video.load();
        }

        // Log whenever a click event listener is added
        console.log(`Attaching click event listener to video ${index + 1}`);
        
        // Remove any existing click listeners before adding new ones to avoid duplication
        video.removeEventListener('click', () => toggleVideoPlayPause(video, index + 1));
        
        // Add click listener to toggle play/pause
        video.addEventListener('click', () => {
            console.log(`Click event triggered for video ${index + 1}`);
            toggleVideoPlayPause(video, index + 1);
        });
    });

    function playVideo(video, videoIndex) {
        if (!currentlyPlaying.includes(video)) {
            video.play().then(() => {
                console.log(`Video ${videoIndex} (src: ${video.src}) is playing.`);
                currentlyPlaying.push(video);
            }).catch(err => {
                console.error(`Error playing video ${videoIndex} (src: ${video.src}): `, err);
            });
        }
    }

    function pauseVideo(video, videoIndex) {
        if (!video.paused) {
            video.pause();
            console.log(`Video ${videoIndex} (src: ${video.src}) is paused.`);
            const index = currentlyPlaying.indexOf(video);
            if (index > -1) {
                currentlyPlaying.splice(index, 1);
            }
        }
    }

    function toggleVideoPlayPause(video, videoIndex) {
        if (video.paused) {
            playVideo(video, videoIndex);
        } else {
            pauseVideo(video, videoIndex);
        }
    }
}

function handleRouteChange() {
    console.log('Route change detected, updating elements and listeners.');

    updateCodeElements();  // Assuming this updates code elements
    updateImageSource();   // Assuming this updates image sources
    updateVideoSettings(); // Updating video settings and listeners

    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        console.log('Attaching theme change event listener to the toggle button.');
        themeToggleButton.addEventListener('click', onThemeChange);
    }
}

function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        console.log('Listening for route changes using window.events.on.');
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
    console.log('Document is fully loaded.');
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        console.log('Window onload event fired.');
        handleRouteChange();
        setupRouteChangeHandler();
    };
}

</script>


let observer; // Define the observer globally to manage its lifecycle
let currentlyPlaying = [];

function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let firstVideoPlayed = false;

    console.log("Initializing IntersectionObserver...");

    // If there's an existing observer, disconnect it to prevent duplication
    if (observer) {
        console.log("Disconnecting previous IntersectionObserver to avoid duplication.");
        observer.disconnect();
    }

    // Create a new Intersection Observer
    observer = new IntersectionObserver((entries) => {
        console.log("Observer callback triggered. Checking entries...");
        entries.forEach(entry => {
            const video = entry.target;
            const videoIndex = video.dataset.index;

            // Log the intersection ratio and whether the video is intersecting
            console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
            
            if (entry.isIntersecting) {
                if (video.readyState >= 3) {
                    playVideo(video, videoIndex);
                } else {
                    console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
                    video.addEventListener('canplay', () => {
                        console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
                        playVideo(video, videoIndex);
                    }, { once: true }); // Ensure the listener is only added once
                }
            } else {
                if (!video.paused) {
                    pauseVideo(video, videoIndex);
                    console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
                }
            }
        });
    }, {
        threshold: 0.1
    });

    videos.forEach(function (video, index) {
        video.dataset.index = index + 1;

        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto');
        video.setAttribute('playsinline', 'true');
        video.setAttribute('webkit-playsinline', 'true');

        console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);

        if (index === 0 && !firstVideoPlayed) {
            video.load();
            video.addEventListener('canplay', () => {
                playVideo(video, index + 1);
                console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
                firstVideoPlayed = true;
            }, { once: true });
        } else {
            observer.observe(video); // Start observing the video
            video.load();
        }

        // Manage click event listener to toggle play/pause
        manageEventListener(video, index);
    });
}

// Function to manage click event listeners on videos
function manageEventListener(video, index) {
    const listener = () => {
        console.log(`Click event triggered for video ${index + 1}`);
        toggleVideoPlayPause(video, index + 1);
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..1000;1,200..1000&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,200..1000&family=Poppins&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />

<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
      
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap" rel="stylesheet">

<link href="https://fonts.googleapis.com/css2?family=PT+Serif+Caption:ital@1&display=swap" rel="stylesheet">


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />


<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />







<script>
  
function updateCodeElements() {
    const codeElements = document.querySelectorAll('.code');
    codeElements.forEach(el => {
        el.classList.add('material-symbols-outlined');
        el.classList.add('icon-color');
        el.textContent = el.textContent.trim();
        console.log("Updated element:", el, "with icon:", el.textContent);
    });
}

function updateImageSource() {
    const targetImage = document.querySelector('#block-0fc849fdab3f475e949553a035ed89ea img');
    const imageSrc = "https://lrcwebdata.s3.us-east-2.amazonaws.com/Home/final-ezgif.com-crop.gif";

    if (targetImage) {
        targetImage.src = imageSrc;

        if (document.documentElement.classList.contains('theme-dark')) {
            targetImage.style.filter = 'invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)';
            console.log('Theme is dark. Image filter set to: invert(1) contrast(1) brightness(0.8) saturate(2.4) hue-rotate(-5deg)');
        } else if (document.documentElement.classList.contains('theme-light')) {
            targetImage.style.filter = 'none';
            console.log('Theme is light. Image filter set to: none');
        }

        if (targetImage.src === imageSrc) {
            console.log('Image source successfully set.');
        } else {
            console.log('Failed to set image source.');
        }
    } else {
        console.log('Target image not found.');
    }
}




function onThemeChange() {
    setTimeout(updateImageSource, 0);
}








let observer; // Define the observer globally to manage its lifecycle
let currentlyPlaying = [];

function updateVideoSettings(maxPlayingVideos = 3) {
    const videos = document.querySelectorAll('.notion-video video');
    let firstVideoPlayed = false;

    console.log("Initializing IntersectionObserver...");

    // If there's an existing observer, disconnect it to prevent duplication
    if (observer) {
        console.log("Disconnecting previous IntersectionObserver to avoid duplication.");
        observer.disconnect();
    }

    // Create a new Intersection Observer
    observer = new IntersectionObserver((entries) => {
        console.log("Observer callback triggered. Checking entries...");
        entries.forEach(entry => {
            const video = entry.target;
            const videoIndex = video.dataset.index;

            // Log the intersection ratio and whether the video is intersecting
            console.log(`Video ${videoIndex} (src: ${video.src}) intersection ratio: ${entry.intersectionRatio}, isIntersecting: ${entry.isIntersecting}`);
            
            if (entry.isIntersecting) {
                if (video.readyState >= 3) {
                    playVideo(video, videoIndex);
                } else {
                    console.log(`Video ${videoIndex} (src: ${video.src}) is in the viewport but has not finished loading.`);
                    video.addEventListener('canplay', () => {
                        console.log(`Video ${videoIndex} (src: ${video.src}) has finished loading in the viewport, starting playback.`);
                        playVideo(video, videoIndex);
                    }, { once: true }); // Ensure the listener is only added once
                }
            } else {
                if (!video.paused) {
                    pauseVideo(video, videoIndex);
                    console.log(`Paused video ${videoIndex} (src: ${video.src}) because it left the viewport.`);
                }
            }
        });
    }, {
        threshold: 0.1
    });

    videos.forEach(function (video, index) {
        video.dataset.index = index + 1;

        video.muted = true;
        video.removeAttribute('controls');
        video.loop = true;
        video.style.borderRadius = '20px';
        video.setAttribute('preload', 'auto');
        video.setAttribute('playsinline', 'true');
        video.setAttribute('webkit-playsinline', 'true');

        console.log(`Video ${index + 1} is set up for autoplay, muted, and looped.`);

        if (index === 0 && !firstVideoPlayed) {
            video.load();
            video.addEventListener('canplay', () => {
                playVideo(video, index + 1);
                console.log(`First video ${index + 1} (src: ${video.src}) is playing immediately after preloading.`);
                firstVideoPlayed = true;
            }, { once: true });
        } else {
            observer.observe(video); // Start observing the video
            video.load();
        }

        // Manage click event listener to toggle play/pause
        manageEventListener(video, index);
    });
}

// Function to manage click event listeners on videos
function manageEventListener(video, index) {
    const listener = () => {
        console.log(`Click event triggered for video ${index + 1}`);
        toggleVideoPlayPause(video, index + 1);
    };

    // Remove any existing click listener to prevent duplication
    video.removeEventListener('click', listener);
    
    // Add the click event listener
    video.addEventListener('click', listener);
    console.log(`Attached click event listener to video ${index + 1}`);
}

// Play video logic
function playVideo(video, videoIndex) {
    if (currentlyPlaying.length < 3 && !currentlyPlaying.includes(video)) { // Limit the number of videos playing simultaneously
        video.play().then(() => {
            console.log(`Video ${videoIndex} (src: ${video.src}) is playing.`);
            currentlyPlaying.push(video);
        }).catch(err => {
            console.error(`Error playing video ${videoIndex} (src: ${video.src}): `, err);
        });
    }
}

// Pause video logic
function pauseVideo(video, videoIndex) {
    if (!video.paused) {
        video.pause();
        console.log(`Video ${videoIndex} (src: ${video.src}) is paused.`);
        const index = currentlyPlaying.indexOf(video);
        if (index > -1) {
            currentlyPlaying.splice(index, 1); // Remove video from currently playing list
        }
    }
}

// Toggle play/pause for manual control
function toggleVideoPlayPause(video, videoIndex) {
    if (video.paused) {
        playVideo(video, videoIndex);
    } else {
        pauseVideo(video, videoIndex);
    }
}

// Function to clean up event listeners and observers when navigating away or rerunning the script
function cleanupEventListeners(videos) {
    videos.forEach(video => {
        // Remove any click event listeners
        video.removeEventListener('click', toggleVideoPlayPause);
        console.log(`Removed event listeners for video ${video.dataset.index}`);
    });
}

// Function to handle route changes
function handleRouteChange() {
    console.log('Route change detected, updating elements and listeners.');

    updateCodeElements();  // Assuming this updates code elements
    updateImageSource();   // Assuming this updates image sources
    updateVideoSettings(); // Updating video settings and listeners

    const themeToggleButton = document.querySelector('.super-navbar__theme-toggle');
    if (themeToggleButton) {
        themeToggleButton.removeEventListener('click', onThemeChange); // Remove existing listener if any
        console.log('Attaching theme change event listener to the toggle button.');
        themeToggleButton.addEventListener('click', onThemeChange);
    }
}

// Set up route change handler and initialize observers/listeners
function setupRouteChangeHandler() {
    if (window.events && window.events.on) {
        console.log('Listening for route changes using window.events.on.');
        window.events.on('routeChangeComplete', handleRouteChange);
    } else {
        console.log('window.events.on is not available.');
    }
}

// Ensure the code runs after the page has loaded
if (document.readyState === 'complete') {
    console.log('Document is fully loaded.');
    handleRouteChange();
    setupRouteChangeHandler();
} else {
    window.onload = () => {
        console.log('Window onload event fired.');
        handleRouteChange();
        setupRouteChangeHandler();
    };
}

</script>