host.tools

robots.txt parser

HTTP /api/v1/http/robots

Fetch and parse robots.txt — User-agent groups, Disallow/Allow, Sitemap, Crawl-delay.

https://crypt.tools/robots.txt 200 207558 bytes 0 User-agent groups
Raw robots.txt
<!DOCTYPE html><html lang="en" dir="ltr" class="h-full"> 
    

<head> <meta charset="UTF-8"> 
    
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    
    


    <title>Crypt.Tools - Advanced Cryptography Toolkit</title> 
    
    


    
    <!-- Dark mode initialization - Must be as early as possible --> 
     
    
    
    <script> // Check for saved dark mode preference or system preference if (localStorage.getItem('theme') === 'dark' || (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)) { document.documentElement.classList.add('dark'); } </script> <!-- SEO Meta Tags --> <meta name="description" content="Perform cryptographic operations with Crypt.Tools. Hash with MD5, encrypt/decrypt with Base64, and use other cryptographic algorithms easily."> <meta name="keywords" content="cryptography, md5, base64, encryption, decryption, hash, sha1, sha256, crypto tools"> <!-- Open Graph Meta Tags --> <meta property="og:title" content="Crypt.Tools - Advanced Cryptography Toolkit"> <meta property="og:description" content="Perform cryptographic operations with Crypt.Tools. Hash with MD5, encrypt/decrypt with Base64, and use other cryptographic algorithms easily."> 



<meta property="og:type" content="website"> <meta property="og:url" content="https://crypt.tools/">


<!-- Generated with HostFavIcons.com -->
<link rel="icon" type="image/svg+xml" href="https://hostfavicons.com/emoji.php?t=CT&shape=rounded&size=256&bg=0170f5&fg=ffffff&padding=0.18">
<link rel="icon" type="image/png" sizes="32x32" href="https://hostfavicons.com/emoji.php?t=CT&shape=rounded&size=32&bg=0170f5&fg=ffffff&padding=0.18">
<link rel="icon" type="image/png" sizes="16x16" href="https://hostfavicons.com/emoji.php?t=CT&shape=rounded&size=16&bg=0170f5&fg=ffffff&padding=0.18">
<link rel="apple-touch-icon" href="https://hostfavicons.com/emoji.php?t=CT&shape=rounded&size=180&bg=0170f5&fg=ffffff&padding=0.18">




<!-- Tailwind CSS --> <script src="https://cdn.tailwindcss.com"></script> <!-- Tailwind dark mode configuration --> <script> tailwind.config = { darkMode: 'class', theme: { extend: { animation: { 'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite', } }, }, } </script> <!-- Font Awesome --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <!-- CryptoJS library for cryptographic functions --> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/aes.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/tripledes.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/rabbit.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/rc4.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/hmac.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/pbkdf2.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/js-blake2/dist/blake2b.js"></script> <script src="https://cdn.jsdelivr.net/npm/js-blake2/dist/blake2s.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/base32.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/bs58.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/ascii85.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/punycode.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/scrypt.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/bcrypt.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/qrcode.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jwt.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js"></script>

 
 <!-- Custom CSS -->
<style>
    /* General styling */
    .notification {
        transition: opacity 0.3s, transform 0.3s;
    }
    
    /* Tool selector styling */
    .tool-selector {
        width: 100%;
        padding: 0.75rem; /* p-3 */
        border: 1px solid #D1D5DB; /* gray-300 */
        border-radius: 0.5rem; /* rounded-lg */
        background-color: #FFFFFF;
        color: #111827;
    }
    .tool-selector:focus {
        outline: none;
        box-shadow: 0 0 0 2px #2563EB; /* ring-2 ring-blue-600 */
        border-color: #2563EB;
    }
    .dark .tool-selector {
        background-color: #374151; /* gray-700 */
        border-color: #4B5563; /* gray-600 */
        color: #FFFFFF;
    }
    
    /* Sidebar transition and positioning */
    #sidebar {
        position: fixed;
        left: 0;
        right: auto;
        transition: transform 0.3s ease-in-out;
    }
    body.sidebar-right #sidebar {
        left: auto;
        right: 0;
    }
    
    /* File drop zone styles */
    #file-drop-zone {
        transition: all 0.2s ease-in-out;
    }
    #file-drop-zone:hover {
        border-color: #60A5FA; /* blue-400 */
        background-color: rgba(239, 246, 255, 0.5); /* blue-50/50 */
    }
    .dark #file-drop-zone:hover {
        background-color: rgba(30, 58, 138, 0.1); /* blue-900/10 */
    }
    
    /* Responsive adjustments */
    @media (max-width: 768px) {
        #sidebar {
            transform: translateX(-100%);
        }
        
        #sidebar.translate-x-0 {
            transform: translateX(0);
        }
        
        #main-content {
            margin-left: 0 !important;
        }
    }
    
    @media (min-width: 769px) {
        /* Apply content offset only when the sidebar is open */
        body.sidebar-open:not(.sidebar-right) #main-content {
            margin-left: 16rem; /* w-64 = 16rem */
        }
        body.sidebar-open.sidebar-right #main-content {
            margin-right: 16rem; /* w-64 = 16rem */
        }
        /* When closed, no extra margins */
        body:not(.sidebar-open) #main-content {
            margin-left: 0;
            margin-right: 0;
        }
    }
    
    /* Dark mode adjustments for syntax highlighting */
    .dark pre {
        background-color: #1F2937; /* gray-800 */
    }
    
    /* Loading indicator */
    .loading-spinner {
        border: 3px solid rgba(0, 0, 0, 0.1);
        border-radius: 50%;
        border-top: 3px solid #3498db;
        width: 20px;
        height: 20px;
        animation: spin 1s linear infinite;
    }
    
    @keyframes spin {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
    }
    
    .dark .loading-spinner {
        border-color: rgba(255, 255, 255, 0.1);
        border-top-color: #3498db;
    }
    
    /* QR Code section */
    .qr-code-container {
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 1rem; /* p-4 */
        background: #FFFFFF; /* bg-white */
        border-radius: 0.5rem; /* rounded-lg */
        box-shadow: inset 0 2px 4px rgba(0,0,0,0.06); /* shadow-inner */
        max-width: 20rem; /* max-w-xs */
        margin-left: auto;
        margin-right: auto; /* mx-auto */
    }
    
    /* Tool tag badges */
    .tool-tag {
        display: inline-block;
        font-size: 0.75rem; /* text-xs */
        padding: 0.25rem 0.5rem; /* px-2 py-1 */
        border-radius: 9999px; /* rounded-full */
        background: #DBEAFE; /* blue-100 */
        color: #1E40AF; /* blue-800 */
        margin-right: 0.5rem; /* mr-2 */
        margin-bottom: 0.5rem; /* mb-2 */
    }
    .dark .tool-tag {
        background: #1E3A8A; /* blue-900 */
        color: #BFDBFE; /* blue-200 */
    }
    
    /* Collapse and expand animations */
    .collapse-enter-active, .collapse-leave-active {
        transition: max-height 0.3s ease-out;
        overflow: hidden;
        max-height: 1000px;
    }
    .collapse-enter, .collapse-leave-to {
        max-height: 0;
        overflow: hidden;
    }
    
    /* Custom scrollbar */
    ::-webkit-scrollbar {
        width: 8px;
        height: 8px;
    }
    
    ::-webkit-scrollbar-track {
        background: transparent;
    }
    
    ::-webkit-scrollbar-thumb {
        background: #cbd5e0;
        border-radius: 4px;
    }
    
    ::-webkit-scrollbar-thumb:hover {
        background: #a0aec0;
    }
    
    .dark ::-webkit-scrollbar-thumb {
        background: #4a5568;
    }
    
    .dark ::-webkit-scrollbar-thumb:hover {
        background: #718096;
    }
    
    /* Highlight effect for active tool */
    .tool-link.active {
        color: #2563EB; /* blue-600 */
        font-weight: 600; /* semibold */
    }
    .dark .tool-link.active {
        color: #60A5FA; /* blue-400 */
    }
    
    /* Tooltip styles */
    .tooltip {
        visibility: hidden;
        position: absolute;
        z-index: 10;
        padding: 0.5rem 0.75rem; /* px-3 py-2 */
        font-size: 0.875rem; /* text-sm */
        font-weight: 500; /* font-medium */
        color: #FFFFFF; /* text-white */
        transition: opacity 0.3s ease;
        background: #111827; /* gray-900 */
        border-radius: 0.5rem; /* rounded-lg */
        box-shadow: 0 1px 2px rgba(0,0,0,0.05); /* shadow-sm */
        opacity: 0;
    }
    .dark .tooltip {
        background: #374151; /* gray-700 */
    }
    
    .has-tooltip:hover .tooltip {
        visibility: visible;
        opacity: 1;
    }
    
    /* Function feature badges */
    .feature-badge {
        font-size: 0.75rem; /* text-xs */
        padding: 0.125rem 0.5rem; /* py-0.5 px-2 */
        border-radius: 9999px; /* rounded-full */
    }
    
    .feature-badge.new {
        background: #D1FAE5; /* green-100 */
        color: #065F46; /* green-800 */
    }
    .dark .feature-badge.new {
        background: #064E3B; /* green-900 */
        color: #A7F3D0; /* green-200 */
    }
    
    .feature-badge.popular {
        background: #FFEDD5; /* orange-100 */
        color: #9A3412; /* orange-800 */
    }
    .dark .feature-badge.popular {
        background: #7C2D12; /* orange-900 */
        color: #FED7AA; /* orange-200 */
    }
    
    /* Zoom effect on hovering cards */
    .zoom-on-hover {
        transition: transform 0.2s ease-in-out;
    }
    
    .zoom-on-hover:hover {
        transform: scale(1.02);
    }
    
    /* Pulse animation for important elements */
    .pulse-animation {
        animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
    }
    
    @keyframes pulse {
        0%, 100% {
            opacity: 1;
        }
        50% {
            opacity: 0.7;
        }
    }
    
    /* Custom checkbox styles */
    .custom-checkbox {
        width: 1rem; /* w-4 */
        height: 1rem; /* h-4 */
        background: #F3F4F6; /* gray-100 */
        border: 1px solid #D1D5DB; /* gray-300 */
        border-radius: 0.25rem; /* rounded */
        accent-color: #2563EB; /* text-blue-600 equivalent for inputs */
    }
    .custom-checkbox:focus {
        outline: none;
        box-shadow: 0 0 0 2px #3B82F6; /* ring-2 ring-blue-500 */
    }
    .dark .custom-checkbox {
        background: #374151; /* gray-700 */
        border-color: #4B5563; /* gray-600 */
    }
</style>

</head> <body class="bg-gray-50 dark:bg-gray-900 text-gray-800 dark:text-gray-200 transition-colors duration-300 min-h-screen flex flex-col"> <!-- Header --> <header class="bg-white dark:bg-gray-800 shadow fixed top-0 left-0 w-full z-50 h-16"> <div class="flex justify-between items-center h-full px-4"> <!-- Left section with hamburger and logo --> <div class="flex items-center"> <!-- Hamburger menu for sidebar --> <button id="sidebar-toggle" class="text-gray-600 hover:text-blue-600 mr-4 focus:outline-none transition-colors duration-300 dark:text-gray-300 dark:hover:text-blue-400"> <i class="fas fa-bars fa-lg"></i> </button> <!-- Logo --> <a href="#" class="text-blue-600 text-2xl font-bold flex items-center"> <i class="fas fa-lock mr-3"></i> <span class="hidden sm:inline">Crypt.Tools</span> </a> </div>

        <!-- Center - Primary Navigation (Desktop) -->
        <nav class="hidden lg:flex items-center space-x-6">
            <a href="index.html" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Home</a>
            <a href="#faq" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">FAQ</a>
            <a href="#contact" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Contact</a>
            <a href="#api" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">API</a>
            <a href="partners.html" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Partners</a>
        </nav>
        
        <!-- Right Side (Settings, Dark Mode) -->
        <div class="flex items-center space-x-2 md:space-x-4">
            <!-- Settings Button -->
            <button id="settings-btn" class="text-gray-600 hover:text-blue-600 focus:outline-none transition-colors duration-300 dark:text-gray-300 dark:hover:text-blue-400 hidden md:block" title="Settings">
                <i class="fas fa-cog fa-lg"></i>
            </button>
            
            <!-- Dark Mode Toggle -->
            <button id="dark-mode-toggle" class="text-gray-600 hover:text-blue-600 focus:outline-none transition-colors duration-300 dark:text-gray-300 dark:hover:text-blue-400" title="Toggle Dark Mode">
                <i class="fas fa-moon fa-lg"></i>
                <i class="fas fa-sun fa-lg hidden"></i>
            </button>
            
            <!-- Mobile Menu Button -->
            <button id="menu-button" class="text-gray-600 hover:text-blue-600 md:hidden focus:outline-none transition-colors duration-300 dark:text-gray-300 dark:hover:text-blue-400">
                <i class="fas fa-ellipsis-v fa-lg"></i>
            </button>
        </div>
    </div>
</header>

<!-- Mobile Navigation Menu -->
<div id="mobile-menu" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden">
    <div class="fixed top-0 right-0 h-full w-64 bg-white dark:bg-gray-800 shadow-lg transform transition-transform duration-300 translate-x-full">
        <div class="p-6">
            <button id="close-menu" class="absolute top-4 right-4 text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">
                <i class="fas fa-times fa-lg"></i>
            </button>
            <nav class="mt-8 space-y-4">
                <a href="index.html" class="block text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Home</a>
                <a href="#faq" class="block text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">FAQ</a>
                <a href="#contact" class="block text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Contact</a>
                <a href="#api" class="block text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">API</a>
                <a href="partners.html" class="block text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Partners</a>
                
                <hr class="my-4 border-gray-200 dark:border-gray-700">
                
                <!-- Dark Mode Toggle for Mobile -->
                <div class="pt-2">
                    <button id="mobile-dark-mode-toggle" data-toggle="dark-mode" class="flex items-center justify-between w-full text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">
                        <span>Dark Mode</span>
                        <span>
                            <i class="fas fa-moon fa-lg"></i>
                            <i class="fas fa-sun fa-lg hidden"></i>
                        </span>
                    </button>
                </div>
            </nav>
        </div>
    </div>
</div>

<!-- Keyboard Shortcuts Modal -->
<div id="shortcuts-modal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center">
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto">
        <div class="p-6">
            <div class="flex justify-between items-center mb-4">
                <h3 class="text-xl font-semibold dark:text-white">Keyboard Shortcuts</h3>
                <button id="close-shortcuts" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">
                    <i class="fas fa-times fa-lg"></i>
                </button>
            </div>
            
            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div>
                    <h4 class="font-medium mb-2 text-gray-800 dark:text-gray-200">General</h4>
                    <ul class="space-y-2">
                        <li class="flex justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Process current function</span>
                            <kbd class="px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded text-sm">Ctrl+Enter</kbd>
                        </li>
                        <li class="flex justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Search tools</span>
                            <kbd class="px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded text-sm">Ctrl+/</kbd>
                        </li>
                        <li class="flex justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Clear input</span>
                            <kbd class="px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded text-sm">Esc</kbd>
                        </li>
                        <li class="flex justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Toggle dark mode</span>
                            <kbd class="px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded text-sm">Shift+D</kbd>
                        </li>
                        <li class="flex justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Toggle sidebar</span>
                            <kbd class="px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded text-sm">Shift+S</kbd>
                        </li>
                    </ul>
                </div>
                
                <div>
                    <h4 class="font-medium mb-2 text-gray-800 dark:text-gray-200">Quick Access</h4>
                    <ul class="space-y-2">
                        <li class="flex justify-between">
                            <span class="text-gray-600 dark:text-gray-400">MD5 Hash</span>
                            <kbd class="px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded text-sm">Alt+1</kbd>
                        </li>
                        <li class="flex justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Base64</span>
                            <kbd class="px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded text-sm">Alt+2</kbd>
                        </li>
                        <li class="flex justify-between">
                            <span class="text-gray-600 dark:text-gray-400">AES Encryption</span>
                            <kbd class="px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded text-sm">Alt+3</kbd>
                        </li>
                        <li class="flex justify-between">
                            <span class="text-gray-600 dark:text-gray-400">URL Encode/Decode</span>
                            <kbd class="px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded text-sm">Alt+4</kbd>
                        </li>
                        <li class="flex justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Password Generator</span>
                            <kbd class="px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded text-sm">Alt+5</kbd>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Settings Modal -->
<div id="settings-modal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center">
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-md w-full mx-4">
        <div class="p-6">
            <div class="flex justify-between items-center mb-4">
                <h3 class="text-xl font-semibold dark:text-white">Settings</h3>
                <button id="close-settings" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">
                    <i class="fas fa-times fa-lg"></i>
                </button>
            </div>
            
            <div class="space-y-4">
                <!-- Theme Settings -->
                <div>
                    <h4 class="font-medium mb-2 text-gray-800 dark:text-gray-200">Theme</h4>
                    <div class="flex items-center justify-between">
                        <span class="text-gray-600 dark:text-gray-400">Dark Mode</span>
                        <label class="relative inline-flex items-center cursor-pointer">
                            <input type="checkbox" id="settings-dark-mode" class="sr-only peer">
                            <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
                        </label>
                    </div>
                </div>
                
                <!-- Interface Settings -->
                <div>
                    <h4 class="font-medium mb-2 text-gray-800 dark:text-gray-200">Interface</h4>
                    <div class="space-y-2">
                        <div class="flex items-center justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Sidebar Position</span>
                            <select id="sidebar-position" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                                <option value="left">Left</option>
                                <option value="right">Right</option>
                            </select>
                        </div>
                        <div class="flex items-center justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Font Size</span>
                            <select id="font-size" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                                <option value="small">Small</option>
                                <option value="medium" selected>Medium</option>
                                <option value="large">Large</option>
                            </select>
                        </div>
                        <div class="flex items-center justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Autosave</span>
                            <label class="relative inline-flex items-center cursor-pointer">
                                <input type="checkbox" id="autosave-setting" class="sr-only peer" checked>
                                <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
                            </label>
                        </div>
                    </div>
                </div>
                
                <!-- Behavior Settings -->
                <div>
                    <h4 class="font-medium mb-2 text-gray-800 dark:text-gray-200">Behavior</h4>
                    <div class="space-y-2">
                        <div class="flex items-center justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Live Preview</span>
                            <label class="relative inline-flex items-center cursor-pointer">
                                <input type="checkbox" id="live-preview-setting" class="sr-only peer" checked>
                                <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
                            </label>
                        </div>
                        <div class="flex items-center justify-between">
                            <span class="text-gray-600 dark:text-gray-400">Keep History</span>
                            <label class="relative inline-flex items-center cursor-pointer">
                                <input type="checkbox" id="keep-history-setting" class="sr-only peer" checked>
                                <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
                            </label>
                        </div>
                    </div>
                </div>
                
                <div class="pt-4 flex justify-end">
                    <button id="reset-settings" class="mr-2 px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-md dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600">
                        Reset to Default
                    </button>
                    <button id="save-settings" class="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md">
                        Save Changes
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Main Content Container with Sidebar -->
<div class="flex pt-16">
    <!-- Sidebar -->
    <aside id="sidebar" class="bg-white dark:bg-gray-800 shadow-lg w-64 fixed h-full overflow-y-auto transition-all duration-300 z-40 transform -translate-x-full">
        <!-- Search Box -->
        <div class="p-4 border-b border-gray-200 dark:border-gray-700">
            <div class="relative">
                <div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
                    <i class="fas fa-search text-gray-400"></i>
                </div>
                <input type="search" id="tool-search" class="block w-full p-2 pl-10 text-sm border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white" placeholder="Search tools...">
            </div>
        </div>
        
        <div class="p-4">
            <!-- Favorites Section -->
            <div class="mb-6" id="favorites-section">
                <div class="flex items-center justify-between mb-3">
                    <h3 class="text-lg font-semibold dark:text-white">Favorites</h3>
                    <button id="manage-favorites" class="text-xs text-blue-600 dark:text-blue-400 hover:underline">
                        Manage
                    </button>
                </div>
                <ul id="favorites-list" class="space-y-1 text-gray-600 dark:text-gray-300">
                    <li class="italic text-gray-500 dark:text-gray-400 text-sm">No favorites yet</li>
                </ul>
            </div>
            
            <!-- Recent Functions -->
            <div class="mb-6" id="recent-section">
                <div class="flex items-center justify-between mb-3">
                    <h3 class="text-lg font-semibold dark:text-white">Recent</h3>
                    <button id="clear-recent" class="text-xs text-blue-600 dark:text-blue-400 hover:underline">
                        Clear
                    </button>
                </div>
                <ul id="recentFunctions" class="space-y-1 text-gray-600 dark:text-gray-300">
                    <li class="italic text-gray-500 dark:text-gray-400 text-sm">No recent functions</li>
                </ul>
            </div>
            
            <!-- Available Tools -->
            <div class="mb-6">
                <h3 class="text-lg font-semibold mb-3 dark:text-white" id="hash-section">Hash Functions</h3>
                <ul class="space-y-1 text-gray-600 dark:text-gray-300">
                    <li class="flex items-center">
                        <a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300 flex-grow" data-function="md5">MD5</a>
                        <span class="feature-badge popular text-xs">Popular</span>
                    </li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="sha1">SHA-1</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="sha256">SHA-256</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="sha512">SHA-512</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="sha3">SHA-3</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="ripemd160">RIPEMD-160</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="blake2b">BLAKE2b</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="blake2s">BLAKE2s</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="keccak">Keccak</a></li>
                </ul>
                
                <h3 class="text-lg font-semibold mb-3 mt-6 dark:text-white" id="encoding-section">Encoding/Decoding</h3>
                <ul class="space-y-1 text-gray-600 dark:text-gray-300">
                    <li class="flex items-center">
                        <a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300 flex-grow" data-function="base64" data-has-mode="true">Base64</a>
                        <span class="feature-badge popular text-xs">Popular</span>
                    </li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="base32" data-has-mode="true">Base32</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="base58" data-has-mode="true">Base58</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="ascii85" data-has-mode="true">ASCII85</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="url" data-has-mode="true">URL</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="html" data-has-mode="true">HTML</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="hex" data-has-mode="true">Hex</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="binary" data-has-mode="true">Binary</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="morse" data-has-mode="true">Morse Code</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="punycode" data-has-mode="true">Punycode</a></li>
                    <li class="flex items-center">
                        <a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300 flex-grow" data-function="json" data-has-mode="true">JSON</a>
                        <span class="feature-badge new text-xs">New</span>
                    </li>
                </ul>
                
                <h3 class="text-lg font-semibold mb-3 mt-6 dark:text-white" id="encryption-section">Encryption</h3>
                <ul class="space-y-1 text-gray-600 dark:text-gray-300">
                    <li class="flex items-center">
                        <a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300 flex-grow" data-function="aes" data-has-mode="true">AES</a>
                        <span class="feature-badge popular text-xs">Popular</span>
                    </li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="des" data-has-mode="true">DES</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="tripledes" data-has-mode="true">Triple DES</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="rabbit" data-has-mode="true">Rabbit</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="rc4" data-has-mode="true">RC4</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="blowfish" data-has-mode="true">Blowfish</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="twofish" data-has-mode="true">Twofish</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="camellia" data-has-mode="true">Camellia</a></li>
                </ul>
                
                <h3 class="text-lg font-semibold mb-3 mt-6 dark:text-white">Key Derivation</h3>
                <ul class="space-y-1 text-gray-600 dark:text-gray-300">
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="pbkdf2">PBKDF2</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="scrypt">Scrypt</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="bcrypt">Bcrypt</a></li>
                </ul>
                
                <h3 class="text-lg font-semibold mb-3 mt-6 dark:text-white" id="other-section">Other Tools</h3>
                <ul class="space-y-1 text-gray-600 dark:text-gray-300">
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="hmac">HMAC</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="jwt" data-has-mode="true">JWT</a></li>
                    <li class="flex items-center">
                        <a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300 flex-grow" data-function="password-generator">Password Generator</a>
                        <span class="feature-badge popular text-xs">Popular</span>
                    </li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="uuid">UUID Generator</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="hash-compare">Hash Comparison</a></li>
                    <li><a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300" data-function="file-checksum">File Checksum</a></li>
                    <li class="flex items-center">
                        <a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300 flex-grow" data-function="qr-code" data-has-mode="true">QR Code</a>
                        <span class="feature-badge new text-xs">New</span>
                    </li>
                    <li class="flex items-center">
                        <a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300 flex-grow" data-function="diff-checker">Text Diff Checker</a>
                        <span class="feature-badge new text-xs">New</span>
                    </li>
                    <li class="flex items-center">
                        <a href="#" class="tool-link hover:text-blue-600 transition-colors duration-300 flex-grow" data-function="regex-tester">Regex Tester</a>
                        <span class="feature-badge new text-xs">New</span>
                    </li>
                </ul>
            </div>
        </div>
        
        <!-- Footer Information -->
        <div class="mt-auto p-4 text-xs text-gray-500 dark:text-gray-400 border-t border-gray-200 dark:border-gray-700">
            <p>All operations are performed locally in your browser. Your data never leaves your device.</p>
            <p class="mt-2"> 2025 Crypt.Tools | <a href="#" class="text-blue-600 dark:text-blue-400 hover:underline">Privacy Policy</a></p>
        </div>
    </aside>
    
    <!-- Sidebar Overlay -->
    <div id="sidebar-overlay" class="fixed inset-0 bg-black bg-opacity-50 z-30 hidden md:hidden"></div>
    
    <!-- Main Content -->
    <main class="flex-1 p-4 md:p-6 transition-all duration-300" id="main-content">
        <div class="container mx-auto px-4 py-6">
            <!-- Breadcrumb -->
            <nav class="flex mb-5" aria-label="Breadcrumb">
                <ol class="inline-flex items-center space-x-1 md:space-x-3">
                    <li class="inline-flex items-center">
                        <a href="#" class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400">
                            <i class="fas fa-home mr-2"></i>
                            Home
                        </a>
                    </li>
                    <li aria-current="page">
                        <div class="flex items-center">
                            <i class="fas fa-chevron-right text-gray-400 mx-2 text-xs"></i>
                            <span id="breadcrumb-current" class="text-sm font-medium text-gray-500 dark:text-gray-400">Select a Tool</span>
                        </div>
                    </li>
                </ol>
            </nav>
            
            <!-- Tool Section -->
            <section class="bg-white dark:bg-gray-800 rounded-lg shadow-xl p-6 mb-8">
                <div class="flex flex-col md:flex-row justify-between items-center mb-6 gap-4">
                    <div class="w-full md:w-auto">
                        <select id="tool-selector" class="tool-selector">
                            <optgroup label="Hash Functions">
                                <option value="md5">MD5</option>
                                <option value="sha1">SHA-1</option>
                                <option value="sha256">SHA-256</option>
                                <option value="sha512">SHA-512</option>
                                <option value="sha3">SHA-3</option>
                                <option value="ripemd160">RIPEMD-160</option>
                                <option value="blake2b">BLAKE2b</option>
                                <option value="blake2s">BLAKE2s</option>
                                <option value="keccak">Keccak</option>
                            </optgroup>
                            <optgroup label="Encoding/Decoding">
                                <option value="base64" data-has-mode="true">Base64</option>
                                <option value="base32" data-has-mode="true">Base32</option>
                                <option value="base58" data-has-mode="true">Base58</option>
                                <option value="ascii85" data-has-mode="true">ASCII85</option>
                                <option value="url" data-has-mode="true">URL</option>
                                <option value="html" data-has-mode="true">HTML</option>
                                <option value="hex" data-has-mode="true">Hex</option>
                                <option value="binary" data-has-mode="true">Binary</option>
                                <option value="morse" data-has-mode="true">Morse Code</option>
                                <option value="punycode" data-has-mode="true">Punycode</option>
                                <option value="json" data-has-mode="true">JSON</option>
                            </optgroup>
                            <optgroup label="Encryption">
                                <option value="aes" data-has-mode="true">AES</option>
                                <option value="des" data-has-mode="true">DES</option>
                                <option value="tripledes" data-has-mode="true">Triple DES</option>
                                <option value="rabbit" data-has-mode="true">Rabbit</option>
                                <option value="rc4" data-has-mode="true">RC4</option>
                                <option value="blowfish" data-has-mode="true">Blowfish</option>
                                <option value="twofish" data-has-mode="true">Twofish</option>
                                <option value="camellia" data-has-mode="true">Camellia</option>
                            </optgroup>
                            <optgroup label="Key Derivation">
                                <option value="pbkdf2">PBKDF2</option>
                                <option value="scrypt">Scrypt</option>
                                <option value="bcrypt">Bcrypt</option>
                            </optgroup>
                            <optgroup label="Other Tools">
                                <option value="hmac">HMAC</option>
                                <option value="jwt" data-has-mode="true">JWT</option>
                                <option value="password-generator">Password Generator</option>
                                <option value="uuid">UUID Generator</option>
                                <option value="hash-compare">Hash Comparison</option>
                                <option value="file-checksum">File Checksum</option>
                                <option value="qr-code" data-has-mode="true">QR Code</option>
                                <option value="diff-checker">Text Diff Checker</option>
                                <option value="regex-tester">Regex Tester</option>
                            </optgroup>
                        </select>
                    </div>
                    
                    <!-- Tool Actions -->
                    <div class="flex gap-2">
                        <!-- Mode Switch (Encode/Decode) - Hidden by default -->
                        <div id="mode-switch-container" class="hidden">
                            <label class="inline-flex items-center cursor-pointer">
                                <span class="mr-3 text-sm font-medium text-gray-600 dark:text-gray-300">Encode</span>
                                <div class="relative">
                                    <input type="checkbox" id="mode-switch" class="sr-only peer">
                                    <div class="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"></div>
                                </div>
                                <span class="ml-3 text-sm font-medium text-gray-600 dark:text-gray-300">Decode</span>
                            </label>
                        </div>
                        
                        <!-- Favorite Button -->
                        <button id="favorite-btn" class="p-2.5 text-gray-500 hover:text-yellow-500 dark:text-gray-400 dark:hover:text-yellow-400 transition-colors duration-200 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700" title="Add to Favorites">
                            <i class="far fa-star"></i>
                        </button>
                        
                        <!-- Share Button -->
                        <button id="share-btn" class="p-2.5 text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400 transition-colors duration-200 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700" title="Share Tool">
                            <i class="fas fa-share-alt"></i>
                        </button>
                    </div>
                </div>
                
                <!-- File Drop Zone (Hidden by default) -->
                <div id="file-drop-zone" class="border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg p-8 text-center mb-6 hidden">
                    <div class="flex flex-col items-center">
                        <i class="fas fa-file-upload text-4xl text-gray-400 dark:text-gray-500 mb-3"></i>
                        <p class="text-gray-600 dark:text-gray-400 mb-2">Drag & drop a file here</p>
                        <p class="text-gray-500 dark:text-gray-500 text-sm">or</p>
                        <label class="mt-3 cursor-pointer">
                            <span class="bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg transition duration-300">Browse Files</span>
                            <input type="file" id="file-input" class="hidden">
                        </label>
                    </div>
                </div>
                
                <!-- Diff Checker UI (Hidden by default) -->
                <div id="diff-checker-container" class="hidden mb-6">
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                        <!-- Original Text -->
                        <div>
                            <h4 class="text-lg font-medium mb-3 dark:text-white">Original Text</h4>
                            <div class="relative mb-3">
                                <div class="textbox-icons absolute top-2 right-2 flex gap-2 z-10">
                                    <button type="button" class="text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400">
                                        <i class="fas fa-eraser"></i>
                                    </button>
                                </div>
                                <textarea id="diffOriginalText" rows="10" class="w-full p-4 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white resize-y" placeholder="Enter original text..."></textarea>
                            </div>
                        </div>
                        
                        <!-- Modified Text -->
                        <div>
                            <h4 class="text-lg font-medium mb-3 dark:text-white">Modified Text</h4>
                            <div class="relative mb-3">
                                <div class="textbox-icons absolute top-2 right-2 flex gap-2 z-10">
                                    <button type="button" class="text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400">
                                        <i class="fas fa-eraser"></i>
                                    </button>
                                </div>
                                <textarea id="diffModifiedText" rows="10" class="w-full p-4 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white resize-y" placeholder="Enter modified text..."></textarea>
                            </div>
                        </div>
                    </div>
                    
                    <div class="flex justify-center mt-4">
                        <div class="inline-flex rounded-md shadow-sm" role="group">
                            <button id="diffInlineBtn" class="px-4 py-2 text-sm font-medium text-gray-900 bg-white border border-gray-200 rounded-l-lg hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-700 dark:border-gray-600 dark:text-white dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-blue-500 dark:focus:text-white">
                                Inline
                            </button>
                            <button id="diffSideBySideBtn" class="px-4 py-2 text-sm font-medium text-gray-900 bg-white border border-gray-200 rounded-r-lg hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-2 focus:ring-blue-700 focus:text-blue-700 dark:bg-gray-700 dark:border-gray-600 dark:text-white dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-blue-500 dark:focus:text-white">
                                Side by Side
                            </button>
                        </div>
                    </div>
                </div>
                
                <!-- Regex Tester UI (Hidden by default) -->
                <div id="regex-tester-container" class="hidden mb-6">
                    <div class="mb-4">
                        <label class="block text-gray-700 dark:text-gray-300 mb-2" for="regexPattern">Regular Expression:</label>
                        <div class="flex">
                            <span class="inline-flex items-center px-3 text-sm text-gray-900 bg-gray-200 border border-r-0 border-gray-300 rounded-l-md dark:bg-gray-600 dark:text-gray-400 dark:border-gray-600">
                                /
                            </span>
                            <input type="text" id="regexPattern" class="rounded-none rounded-r-lg bg-gray-50 border border-gray-300 text-gray-900 focus:ring-blue-500 focus:border-blue-500 block flex-1 min-w-0 w-full text-sm p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Enter regex pattern...">
                            <span class="inline-flex items-center px-3 text-sm text-gray-900 bg-gray-200 border border-l-0 border-gray-300 rounded-r-md dark:bg-gray-600 dark:text-gray-400 dark:border-gray-600">
                                /
                            </span>
                            <input type="text" id="regexFlags" class="rounded-lg bg-gray-50 border border-gray-300 text-gray-900 focus:ring-blue-500 focus:border-blue-500 block w-20 text-sm p-2.5 ml-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="flags" value="g">
                        </div>
                    </div>
                    
                    <div class="mb-4">
                        <label class="block text-gray-700 dark:text-gray-300 mb-2" for="regexTestString">Test String:</label>
                        <textarea id="regexTestString" rows="6" class="w-full p-4 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white resize-y" placeholder="Enter text to test against the regex..."></textarea>
                    </div>
                </div>
                
                <!-- QR Code Generator UI (Hidden by default) -->
                <div id="qr-code-container" class="hidden mb-6">
                    <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                        <div>
                            <h4 class="text-lg font-medium mb-3 dark:text-white">QR Code Input</h4>
                            <div class="mb-4">
                                <textarea id="qrCodeInput" rows="6" class="w-full p-4 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white resize-y" placeholder="Enter text or URL to generate QR code..."></textarea>
                            </div>
                            
                            <div class="mb-4">
                                <label class="block text-gray-700 dark:text-gray-300 mb-2">QR Code Options</label>
                                <div class="grid grid-cols-2 gap-4">
                                    <div>
                                        <label class="block text-sm text-gray-600 dark:text-gray-400 mb-1">Size:</label>
                                        <select id="qrCodeSize" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                                            <option value="128">Small (128px)</option>
                                            <option value="200" selected>Medium (200px)</option>
                                            <option value="300">Large (300px)</option>
                                            <option value="400">Extra Large (400px)</option>
                                        </select>
                                    </div>
                                    <div>
                                        <label class="block text-sm text-gray-600 dark:text-gray-400 mb-1">Error Correction:</label>
                                        <select id="qrCodeErrorCorrection" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                                            <option value="L">Low (7%)</option>
                                            <option value="M" selected>Medium (15%)</option>
                                            <option value="Q">Quartile (25%)</option>
                                            <option value="H">High (30%)</option>
                                        </select>
                                    </div>
                                </div>
                            </div>
                        </div>
                        
                        <div>
                            <h4 class="text-lg font-medium mb-3 dark:text-white">QR Code Output</h4>
                            <div class="bg-white dark:bg-gray-700 p-4 rounded-lg shadow-inner flex items-center justify-center">
                                <div id="qrCodeOutput" class="qr-code-container">
                                    <div class="text-gray-400 dark:text-gray-500 text-center">
                                        <i class="fas fa-qrcode text-4xl mb-2"></i>
                                        <p>QR code will appear here</p>
                                    </div>
                                </div>
                            </div>
                            
                            <div class="mt-4 flex space-x-2 justify-center">
                                <button id="downloadQrCodeBtn" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors duration-300 flex items-center disabled:opacity-50 disabled:cursor-not-allowed" disabled>
                                    <i class="fas fa-download mr-2"></i>
                                    Download QR Code
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
                
                <!-- Two-column layout for input/output -->
                <div id="standard-input-output" class="grid grid-cols-1 md:grid-cols-2 gap-6">
                    <!-- Input Column -->
                    <div>
                        <div class="flex justify-between items-center mb-3">
                            <h4 class="text-lg font-medium dark:text-white">Input</h4>
                            <div class="flex items-center space-x-2">
                                <div class="text-sm text-gray-500 dark:text-gray-400">
                                    <span id="inputCharCount">0</span> chars
                                </div>
                                <select id="input-format" class="text-sm bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-blue-500 focus:border-blue-500 p-1 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                                    <option value="text">Text</option>
                                    <option value="json">JSON</option>
                                    <option value="xml">XML</option>
                                    <option value="html">HTML</option>
                                </select>
                            </div>
                        </div>
                        <div class="relative mb-6">
                            <!-- Icons in the top right of the textbox -->
                            <div class="textbox-icons absolute top-2 right-2 flex gap-2 z-10">
                                <button type="button" id="pasteBtn" title="Paste from Clipboard" class="text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400">
                                    <i class="fas fa-paste"></i>
                                </button>
                                <button type="button" id="clearBtn" title="Clear Text" class="text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400">
                                    <i class="fas fa-eraser"></i>
                                </button>
                                <button type="button" id="copyBtn" title="Copy to Clipboard" class="text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400">
                                    <i class="fas fa-copy"></i>
                                </button>
                            </div>
                            <textarea id="inputText" rows="12" class="w-full p-4 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white resize-y font-mono" placeholder="Type or paste your text here..."></textarea>
                        </div>
                    </div>
                    
                    <!-- Output Column -->
                    <div>
                        <div class="flex justify-between items-center mb-3">
                            <h4 class="text-lg font-medium dark:text-white">Output</h4>
                            <div class="flex items-center space-x-2">
                                <div class="text-sm text-gray-500 dark:text-gray-400">
                                    <span id="outputCharCount">0</span> chars
                                </div>
                                <select id="output-format" class="text-sm bg-gray-50 border border-gray-300 text-gray-900 rounded-lg focus:ring-blue-500 focus:border-blue-500 p-1 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
                                    <option value="text">Text</option>
                                    <option value="json">JSON</option>
                                    <option value="xml">XML</option>
                                    <option value="html">HTML</option>
                                </select>
                            </div>
                        </div>
                        <div class="relative mb-6">
                            <div class="textbox-icons absolute top-2 right-2 flex gap-2 z-10">
                                <button type="button" id="copyResultBtn" title="Copy to Clipboard" class="text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400">
                                    <i class="fas fa-copy"></i>
                                </button>
                                <button type="button" id="downloadResultBtn" title="Download Result" class="text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400">
                                    <i class="fas fa-download"></i>
                                </button>
                            </div>
                            <!-- HTML Output Container (for tools that output HTML markup) -->
                            <div id="outputHtml" class="w-full p-4 border rounded-lg dark:bg-gray-700 dark:border-gray-600 text-sm whitespace-pre-wrap hidden"></div>
                            <textarea id="outputText" rows="12" class="w-full p-4 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white resize-y font-mono" readonly placeholder="Results will appear here..."></textarea>
                        </div>
                    </div>
                </div>
                
                <!-- Additional input fields that appear based on selected function -->
                <div id="additionalInputs" class="mb-6 hidden">
                    <!-- HMAC Key Input (shown only when HMAC selected) -->
                    <div id="hmacKeyField" class="hidden">
                        <label class="block text-gray-600 dark:text-gray-400 mb-2">Secret Key:</label>
                        <input type="text" id="hmacKey" class="w-full p-3 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white" placeholder="Enter your secret key">
                    </div>
                    
                    <!-- Encryption Key Input -->
                    <div id="encryptionKeyField" class="hidden">
                        <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                            <div>
                                <label class="block text-gray-600 dark:text-gray-400 mb-2">Encryption Key:</label>
                                <div class="relative">
                                    <input type="password" id="encryptionKey" class="w-full p-3 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white pr-10" placeholder="Enter your encryption key">
                                    <button id="toggleKeyVisibility" class="absolute inset-y-0 right-0 px-3 flex items-center text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400">
                                        <i class="fas fa-eye"></i>
                                    </button>
                                </div>
                            </div>
                            <div>
                                <label class="block text-gray-600 dark:text-gray-400 mb-2">Encryption Options:</label>
                                <select id="encryptionMode" class="w-full p-3 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
                                    <option value="cbc">CBC Mode</option>
                                    <option value="ecb">ECB Mode</option>
                                    <option value="cfb">CFB Mode</option>
                                    <option value="ofb">OFB Mode</option>
                                </select>
                            </div>
                        </div>
                        <div class="mt-2">
                            <div class="flex items-center">
                                <input id="rememberKey" type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
                                <label for="rememberKey" class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300">Remember this key in browser storage</label>
                            </div>
                            <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">The key will be stored securely in your browser's local storage</p>
                        </div>
                    </div>
                    
                    <!-- Random String Generator Options -->
                    <div id="randomStringOptions" class="hidden">
                        <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                            <div>
                                <label class="block text-gray-600 dark:text-gray-400 mb-2">Length:</label>
                                <div class="flex items-center">
                                    <input type="range" id="randomLengthSlider" min="1" max="1024" value="16" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700">
                                    <input type="number" id="randomLength" class="ml-4 w-20 p-2 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white" value="16" min="1" max="1024">
                                </div>
                            </div>
                            <div>
                                <label class="block text-gray-600 dark:text-gray-400 mb-2">Character Set:</label>
                                <select id="randomCharset" class="w-full p-3 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
                                    <option value="alphanumeric">Alphanumeric</option>
                                    <option value="alphabetic">Alphabetic only</option>
                                    <option value="numeric">Numeric only</option>
                                    <option value="hex">Hexadecimal</option>
                                    <option value="custom">Custom character set</option>
                                </select>
                            </div>
                        </div>
                        <div id="customCharset" class="hidden mt-4">
                            <label class="block text-gray-600 dark:text-gray-400 mb-2">Custom Character Set:</label>
                            <input type="text" id="customCharsetInput" class="w-full p-3 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white" placeholder="Enter characters to use">
                        </div>
                        <div class="mt-4">
                            <div class="flex items-center">
                                <input id="excludeSimilar" type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
                                <label for="excludeSimilar" class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300">Exclude similar characters (i, l, 1, L, o, 0, O)</label>
                            </div>
                            <div class="flex items-center mt-2">
                                <input id="excludeAmbiguous" type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
                                <label for="excludeAmbiguous" class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300">Exclude ambiguous characters ({ } [ ] ( ) / \ ' " ` ~ , ; : . < >)</label>
                            </div>
                        </div>
                    </div>
                    
                    <!-- Password Generator Options -->
                    <div id="passwordOptions" class="hidden">
                        <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                            <div>
                                <label class="block text-gray-600 dark:text-gray-400 mb-2">Length: <span id="passwordLengthValue">16</span> characters</label>
                                <div class="flex items-center">
                                    <input type="range" id="passwordLengthSlider" min="4" max="64" value="16" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700">
                                    <input type="number" id="passwordLength" class="ml-4 w-20 p-2 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white" value="16" min="4" max="64">
                                </div>
                                
                                <div class="mt-4">
                                    <label class="block text-gray-600 dark:text-gray-400 mb-2">Password Strength</label>
                                    <div class="w-full bg-gray-200 rounded-full h-2.5 dark:bg-gray-700 mb-1">
                                        <div id="passwordStrength" class="bg-green-600 h-2.5 rounded-full" style="width: 100%"></div>
                                    </div>
                                    <p id="passwordStrengthText" class="text-sm text-green-700 dark:text-green-500">Very Strong</p>
                                </div>
                                
                                <div class="mt-4">
                                    <label class="block text-gray-600 dark:text-gray-400 mb-2">Memorable Password</label>
                                    <div class="flex items-center">
                                        <input id="memorablePassword" type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
                                        <label for="memorablePassword" class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-300">Generate memorable password</label>
                                    </div>
                                    <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Creates a password using words instead of random characters</p>
                                </div>
                            </div>
                            
                            <div>
                                <label class="block text-gray-600 dark:text-gray-400 mb-2">Character Types:</label>
                                <div class="space-y-2">
                                    <label class="flex items-center">
                                        <input type="checkbox" id="includeUppercase" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" checked>
                                        <span class="ml-2 text-gray-600 dark:text-gray-400">Uppercase Letters (A-Z)</span>
                                    </label>
                                    <label class="flex items-center">
                                        <input type="checkbox" id="includeLowercase" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" checked>
                                        <span class="ml-2 text-gray-600 dark:text-gray-400">Lowercase Letters (a-z)</span>
                                    </label>
                                    <label class="flex items-center">
                                        <input type="checkbox" id="includeNumbers" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" checked>
                                        <span class="ml-2 text-gray-600 dark:text-gray-400">Numbers (0-9)</span>
                                    </label>
                                    <label class="flex items-center">
                                        <input type="checkbox" id="includeSymbols" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" checked>
                                        <span class="ml-2 text-gray-600 dark:text-gray-400">Special Characters (!@#$%^&*)</span>
                                    </label>
                                </div>
                                
                                <div class="mt-4">
                                    <label class="block text-gray-600 dark:text-gray-400 mb-2">Additional Options:</label>
                                    <div class="space-y-2">
                                        <label class="flex items-center">
                                            <input type="checkbox" id="excludeSimilarChars" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
                                            <span class="ml-2 text-gray-600 dark:text-gray-400">Exclude similar characters (i, l, 1, I, o, 0, O)</span>
                                        </label>
                                        <label class="flex items-center">
                                            <input id="requireAllTypes" type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" checked>
                                            <span class="ml-2 text-gray-600 dark:text-gray-400">Require at least one of each selected type</span>
                                        </label>
                                    </div>
                                </div>
                                
                                <button id="generatePasswordBtn" class="mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors duration-300 flex items-center">
                                    <i class="fas fa-sync-alt mr-2"></i>
                                    Generate New Password
                                </button>
                            </div>
                        </div>
                    </div>
                    
                    <!-- Hash Comparison -->
                    <div id="hashCompareField" class="hidden">
                        <label class="block text-gray-600 dark:text-gray-400 mb-2">Hash to Compare:</label>
                        <input type="text" id="hashToCompare" class="w-full p-3 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white" placeholder="Enter hash to compare">
                        <div class="mt-2">
                            <select id="hashAlgorithm" class="w-full p-3 border rounded-lg focus:ring-2 focus:ring-blue-600 dark:bg-gray-700 dark:border-gray-600 dark:text-white">
                                <option value="auto">Auto-detect algorithm</option>
                                <option value="md5">MD5</option>
                                <option value="sha1">SHA-1</option>
                                <option value="sha256">SHA-256</option>
                                <option value="sha512">SHA-512</option>
                                <option value="sha3">SHA-3</option>
                            </select>
                        </div>
                    </div>
                </div>
                
                <div class="flex justify-center">
                    <button id="processBtn" class="bg-blue-600 hover:bg-blue-700 text-white font-semibold py-3 px-8 rounded-lg transition duration-300 focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-opacity-50 flex items-center">
                        <i class="fas fa-play mr-2"></i>
                        Process
                    </button>
                </div>
            </section>
            
            <!-- All Results Section -->
            <section id="allResultsSection" class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6 mb-8 hidden">
                <div class="flex justify-between items-center mb-4">
                    <h3 class="text-xl font-semibold dark:text-white">All Results</h3>
                    <button id="clearAllResults" class="text-sm text-gray-600 hover:text-red-600 dark:text-gray-400 dark:hover:text-red-600 transition-colors duration-200">
                        <i class="fas fa-trash mr-1"></i>
                        Clear All
                    </button>
                </div>
                <div id="allResultsContainer" class="space-y-4">
                    <!-- Results will be added here dynamically -->
                </div>
            </section>

            <!-- Tool Information Section -->
            <section class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6 mb-8">
                <div class="flex items-center justify-between mb-4">
                    <h3 class="text-xl font-semibold dark:text-white">Tool Information</h3>
                    <div class="flex items-center">
                        <button id="expandToolInfo" class="text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400 transition-colors duration-200">
                            <i class="fas fa-chevron-down"></i>
                        </button>
                    </div>
                </div>
                <div id="toolInfo" class="prose dark:prose-invert">
                    <p class="text-gray-600 dark:text-gray-300">Select a cryptographic function from the dropdown or sidebar to get started. Input your text and click "Process" to see the results.</p>
                </div>
            </section>

            <!-- Related Tools Section -->
            <section class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6 mb-8">
                <h3 class="text-xl font-semibold mb-4 dark:text-white">Related Tools</h3>
                <div id="relatedTools" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
                    <!-- Related tools will be added here dynamically -->
                    <div class="p-4 border rounded-lg shadow-sm bg-gray-50 dark:bg-gray-700 hover:shadow-md transition-shadow duration-300 zoom-on-hover">
                        <div class="flex items-center mb-2">
                            <i class="fas fa-hashtag text-blue-600 dark:text-blue-400 mr-3"></i>
                            <h4 class="font-medium text-gray-800 dark:text-white">MD5 Hash</h4>
                        </div>
                        <p class="text-sm text-gray-600 dark:text-gray-300">Generate MD5 hash from text input</p>
                    </div>
                    <div class="p-4 border rounded-lg shadow-sm bg-gray-50 dark:bg-gray-700 hover:shadow-md transition-shadow duration-300 zoom-on-hover">
                        <div class="flex items-center mb-2">
                            <i class="fas fa-exchange-alt text-blue-600 dark:text-blue-400 mr-3"></i>
                            <h4 class="font-medium text-gray-800 dark:text-white">Base64 Encode/Decode</h4>
                        </div>
                        <p class="text-sm text-gray-600 dark:text-gray-300">Convert text to/from Base64 encoding</p>
                    </div>
                    <div class="p-4 border rounded-lg shadow-sm bg-gray-50 dark:bg-gray-700 hover:shadow-md transition-shadow duration-300 zoom-on-hover">
                        <div class="flex items-center mb-2">
                            <i class="fas fa-key text-blue-600 dark:text-blue-400 mr-3"></i>
                            <h4 class="font-medium text-gray-800 dark:text-white">SHA-256 Hash</h4>
                        </div>
                        <p class="text-sm text-gray-600 dark:text-gray-300">Generate SHA-256 hash from text input</p>
                    </div>
                </div>
            </section>
            
            <!-- Usage Stats Section -->
            <section class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6 mb-8">
                <div class="flex justify-between items-center mb-4">
                    <h3 class="text-xl font-semibold dark:text-white">Usage Statistics</h3>
                    <div>
                        <button id="toggleStatsView" class="text-sm text-blue-600 dark:text-blue-400 hover:underline">
                            Switch to Table View
                        </button>
                    </div>
                </div>
                
                <div id="statsChartView">
                    <canvas id="usageStatsChart" height="200"></canvas>
                </div>
                
                <div id="statsTableView" class="hidden">
                    <div class="overflow-x-auto">
                        <table class="w-full text-sm text-left text-gray-500 dark:text-gray-400">
                            <thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
                                <tr>
                                    <th scope="col" class="px-6 py-3">Tool</th>
                                    <th scope="col" class="px-6 py-3">Usage Count</th>
                                    <th scope="col" class="px-6 py-3">Last Used</th>
                                </tr>
                            </thead>
                            <tbody id="statsTableBody">
                                <!-- Will be populated dynamically -->
                            </tbody>
                        </table>
                    </div>
                </div>
            </section>
        </div>
    </main>
</div>

<!-- Footer -->
<footer class="bg-white dark:bg-gray-800 shadow py-8 transition-all duration-300 mt-auto" id="main-footer">
    <div class="container mx-auto px-4">
        <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
            <!-- Quick Links -->
            <div>
                <h3 class="text-lg font-semibold mb-4 dark:text-white">Quick Links</h3>
                <ul class="space-y-2">
                    <li><a href="#hash-section" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Hash Functions</a></li>
                    <li><a href="#encoding-section" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Encoding Tools</a></li>
                    <li><a href="#encryption-section" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Encryption</a></li>
                    <li><a href="#other-section" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Other Tools</a></li>
                </ul>
            </div>
            
            <!-- Popular Tools -->
            <div>
                <h3 class="text-lg font-semibold mb-4 dark:text-white">Popular Tools</h3>
                <ul class="space-y-2">
                    <li><a href="#" class="tool-link text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400" data-function="md5">MD5 Hash</a></li>
                    <li><a href="#" class="tool-link text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400" data-function="base64" data-has-mode="true">Base64 Encode/Decode</a></li>
                    <li><a href="#" class="tool-link text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400" data-function="aes" data-has-mode="true">AES Encryption</a></li>
                    <li><a href="#" class="tool-link text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400" data-function="password-generator">Password Generator</a></li>
                </ul>
            </div>
            
            <!-- Connect -->
            <div>
                <h3 class="text-lg font-semibold mb-4 dark:text-white">Connect</h3>
                <ul class="space-y-2">
                    <li><a href="https://twitter.com/crypttools" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400"><i class="fab fa-twitter mr-2"></i>Twitter</a></li>
                    <li><a href="https://github.com/crypttools" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400"><i class="fab fa-github mr-2"></i>GitHub</a></li>
                    <li><a href="https://discord.gg/crypttools" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400"><i class="fab fa-discord mr-2"></i>Discord</a></li>
                    <li><a href="/cdn-cgi/l/email-protection#13707c7d677270675370616a63673d677c7c7f60" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400"><i class="fas fa-envelope mr-2"></i>Email</a></li>
                </ul>
            </div>
        </div>
        
        <div class="border-t border-gray-200 dark:border-gray-700 mt-8 pt-8 text-center">
            <p class="text-gray-500 dark:text-gray-400 text-sm">All cryptographic operations are performed in your browser. No data is sent to our servers.</p>
            <div class="flex justify-center space-x-4 mt-4">
                <a href="/privacy" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Privacy Policy</a>
                <a href="/terms" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Terms of Service</a>
                <a href="/security" class="text-gray-600 hover:text-blue-600 dark:text-gray-300 dark:hover:text-blue-400">Security</a>
            </div>
        </div>
    </div>
</footer>

<!-- Toast Notifications Container -->
<div id="toast-container" class="fixed bottom-4 right-4 z-50 flex flex-col gap-2"></div>

<!-- App Scripts -->
<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><script>
    // DOM Elements
    const sidebar = document.getElementById('sidebar');
    const sidebarToggle = document.getElementById('sidebar-toggle');
    const sidebarOverlay = document.getElementById('sidebar-overlay');
    const mainContent = document.getElementById('main-content');
    const toolSelector = document.getElementById('tool-selector');
    const modeSwitch = document.getElementById('mode-switch');
    const modeSwitchContainer = document.getElementById('mode-switch-container');
    const inputText = document.getElementById('inputText');
    const outputText = document.getElementById('outputText');
    const outputHtml = document.getElementById('outputHtml');
    const processBtn = document.getElementById('processBtn');
    const clearBtn = document.getElementById('clearBtn');
    const pasteBtn = document.getElementById('pasteBtn');
    const copyBtn = document.getElementById('copyBtn');
    const copyResultBtn = document.getElementById('copyResultBtn');
    const downloadResultBtn = document.getElementById('downloadResultBtn');
    const recentFunctionsList = document.getElementById('recentFunctions');
    const toolInfo = document.getElementById('toolInfo');
    const darkModeToggle = document.getElementById('dark-mode-toggle');
    const mobileDarkModeToggle = document.getElementById('mobile-dark-mode-toggle');
    const additionalInputs = document.getElementById('additionalInputs');
    const allResultsSection = document.getElementById('allResultsSection');
    const allResultsContainer = document.getElementById('allResultsContainer');
    const clearAllResults = document.getElementById('clearAllResults');
    const toolSearch = document.getElementById('tool-search');
    const favoritesList = document.getElementById('favorites-list');
    const favoriteBtn = document.getElementById('favorite-btn');
    const inputCharCount = document.getElementById('inputCharCount');
    const outputCharCount = document.getElementById('outputCharCount');
    const standardInputOutput = document.getElementById('standard-input-output');
    const diffCheckerContainer = document.getElementById('diff-checker-container');
    const regexTesterContainer = document.getElementById('regex-tester-container');
    const qrCodeContainer = document.getElementById('qr-code-container');
    const fileDropZone = document.getElementById('file-drop-zone');
    const toggleKeyVisibility = document.getElementById('toggleKeyVisibility');
    const breadcrumbCurrent = document.getElementById('breadcrumb-current');
    const relatedTools = document.getElementById('relatedTools');
    const settingsBtn = document.getElementById('settings-btn');
    const settingsModal = document.getElementById('settings-modal');
    const closeSettings = document.getElementById('close-settings');
    const saveSettings = document.getElementById('save-settings');
    const resetSettings = document.getElementById('reset-settings');
    const settingsDarkMode = document.getElementById('settings-dark-mode');
    const shortcutsBtn = document.getElementById('shortcuts-btn');
    const shortcutsModal = document.getElementById('shortcuts-modal');
    const closeShortcuts = document.getElementById('close-shortcuts');
    const passwordLengthSlider = document.getElementById('passwordLengthSlider');
    const passwordLength = document.getElementById('passwordLength');
    const passwordLengthValue = document.getElementById('passwordLengthValue');
    const passwordStrength = document.getElementById('passwordStrength');
    const passwordStrengthText = document.getElementById('passwordStrengthText');
    const generatePasswordBtn = document.getElementById('generatePasswordBtn');
    const usageStatsChart = document.getElementById('usageStatsChart');
    const toggleStatsView = document.getElementById('toggleStatsView');
    const statsChartView = document.getElementById('statsChartView');
    const statsTableView = document.getElementById('statsTableView');
    const statsTableBody = document.getElementById('statsTableBody');
    const manageFavorites = document.getElementById('manage-favorites');
    const clearRecent = document.getElementById('clear-recent');
    const shareBtn = document.getElementById('share-btn');
    
    // Global state
    let currentFunction = '';
    let chartInstance = null;
    
    // Initialize the app
    document.addEventListener('DOMContentLoaded', () => {
        initializeSidebar();
        initializeDarkMode();
        initializeToolSelector();
        initializeButtons();
        initializeRecentFunctions();
        initializeFavorites();
        initializeFileDropZone();
        initializeLivePreview();
        initializeSearch();
        initializeCharCount();
        initializeModals();
        initializeRangeSliders();
        initializeStats();
        initializeQRCode();
        initializeRegexTester();
        initializeDiffChecker();
        initializeKeyboardShortcuts();
        
        // Check URL params for direct tool access
        checkUrlParameters();
    });
    
    // Sidebar functionality
    function initializeSidebar() {
        // Apply saved sidebar position
        applySavedSidebarPosition();

        // Toggle sidebar on button click
        sidebarToggle.addEventListener('click', () => {
            toggleSidebar();
        });
        
        // Close sidebar when clicking on overlay
        sidebarOverlay.addEventListener('click', () => {
            closeSidebar();
        });
        
        // Close sidebar on window resize if in mobile view
        window.addEventListener('resize', () => {
            if (window.innerWidth >= 768) {
                // On desktop, default to showing the sidebar
                showSidebar();
                sidebarOverlay.classList.add('hidden');
            } else {
                // On mobile, keep it closed by default
                closeSidebar();
            }
        });

        // Show sidebar by default on desktop at load time
        if (window.innerWidth >= 768) {
            showSidebar();
        } else {
            closeSidebar();
        }

        // Wire settings select to update sidebar position
        const sidebarPositionSelect = document.getElementById('sidebar-position');
        if (sidebarPositionSelect) {
            // Set initial value from storage
            const savedPos = getSavedSidebarPosition();
            if (savedPos) {
                sidebarPositionSelect.value = savedPos;
            }
            sidebarPositionSelect.addEventListener('change', () => {
                setSavedSidebarPosition(sidebarPositionSelect.value);
                applySavedSidebarPosition();
            });
        }
        
        // Handle tool link clicks
        document.querySelectorAll('.tool-link').forEach(link => {
            link.addEventListener('click', (e) => {
                e.preventDefault();
                const functionName = link.getAttribute('data-function');
                const hasMode = link.getAttribute('data-has-mode') === 'true';
                
                // Set the tool selector value
                toolSelector.value = functionName;
                
                // Highlight active tool in sidebar
                document.querySelectorAll('.tool-link').forEach(l => l.classList.remove('active'));
                document.querySelectorAll(`.tool-link[data-function="${functionName}"]`).forEach(l => l.classList.add('active'));
                
                // Handle mode switch visibility
                toggleModeSwitch(hasMode);
                
                // Update tool information
                updateToolInfo(functionName);
                
                // Update breadcrumb
                updateBreadcrumb(functionName);
                
                // Add to recent functions
                addToRecentFunctions(functionName);
                
                // Handle additional inputs
                showRelevantInputs(functionName);
                
                // Show appropriate UI based on tool
                toggleUIBasedOnTool(functionName);
                
                // Update related tools
                updateRelatedTools(functionName);
                
                // Update favorite button state
                updateFavoriteButtonState(functionName);
                
                // On mobile, close the sidebar after selecting a tool
                if (window.innerWidth < 768) {
                    closeSidebar();
                }
                
                // Update URL with selected tool
                updateUrlWithTool(functionName);
                
                // Store current function
                currentFunction = functionName;
            });
        });
    }
    
    function toggleSidebar() {
        if (sidebar.classList.contains('translate-x-0')) {
            closeSidebar();
        } else {
            showSidebar();
        }
    }
    
    function showSidebar() {
        if (isSidebarRight()) {
            sidebar.classList.remove('translate-x-full');
        } else {
            sidebar.classList.remove('-translate-x-full');
        }
        sidebar.classList.add('translate-x-0');
        document.body.classList.add('sidebar-open');

        if (window.innerWidth < 768) {
            sidebarOverlay.classList.remove('hidden');
        }
    }
    
    function closeSidebar() {
        sidebar.classList.remove('translate-x-0');
        if (isSidebarRight()) {
            sidebar.classList.add('translate-x-full');
            sidebar.classList.remove('-translate-x-full');
        } else {
            sidebar.classList.add('-translate-x-full');
            sidebar.classList.remove('translate-x-full');
        }
        sidebarOverlay.classList.add('hidden');
        document.body.classList.remove('sidebar-open');
    }

    function isSidebarRight() {
        return document.body.classList.contains('sidebar-right');
    }

    function getSavedSidebarPosition() {
        return localStorage.getItem('sidebarPosition');
    }

    function setSavedSidebarPosition(pos) {
        localStorage.setItem('sidebarPosition', pos);
    }

    function applySavedSidebarPosition() {
        const pos = getSavedSidebarPosition() || 'left';
        if (pos === 'right') {
            document.body.classList.add('sidebar-right');
            // Ensure hidden state uses translate-x-full when right-sided
            sidebar.classList.remove('-translate-x-full');
            if (!sidebar.classList.contains('translate-x-0')) {
                sidebar.classList.add('translate-x-full');
            }
        } else {
            document.body.classList.remove('sidebar-right');
            sidebar.classList.remove('translate-x-full');
            if (!sidebar.classList.contains('translate-x-0')) {
                sidebar.classList.add('-translate-x-full');
            }
        }
    }
    
    // Dark mode functionality
    function initializeDarkMode() {
        // Function to toggle dark mode
        function toggleDarkMode() {
            if (document.documentElement.classList.contains('dark')) {
                document.documentElement.classList.remove('dark');
                localStorage.setItem('theme', 'light');
                document.querySelectorAll('.fa-moon').forEach(icon => icon.classList.remove('hidden'));
                document.querySelectorAll('.fa-sun').forEach(icon => icon.classList.add('hidden'));
                if (settingsDarkMode) settingsDarkMode.checked = false;
            } else {
                document.documentElement.classList.add('dark');
                localStorage.setItem('theme', 'dark');
                document.querySelectorAll('.fa-moon').forEach(icon => icon.classList.add('hidden'));
                document.querySelectorAll('.fa-sun').forEach(icon => icon.classList.remove('hidden'));
                if (settingsDarkMode) settingsDarkMode.checked = true;
            }
            
            // Update chart colors if chart exists
            updateChartTheme();
        }
        
        // Initialize dark mode icons based on current state
        if (document.documentElement.classList.contains('dark')) {
            document.querySelectorAll('.fa-moon').forEach(icon => icon.classList.add('hidden'));
            document.querySelectorAll('.fa-sun').forEach(icon => icon.classList.remove('hidden'));
            if (settingsDarkMode) settingsDarkMode.checked = true;
        } else {
            document.querySelectorAll('.fa-moon').forEach(icon => icon.classList.remove('hidden'));
            document.querySelectorAll('.fa-sun').forEach(icon => icon.classList.add('hidden'));
            if (settingsDarkMode) settingsDarkMode.checked = false;
        }
        
        // Add event listeners
        darkModeToggle.addEventListener('click', toggleDarkMode);
        mobileDarkModeToggle.addEventListener('click', toggleDarkMode);
        if (settingsDarkMode) {
            settingsDarkMode.addEventListener('change', toggleDarkMode);
        }
    }
    
    // Update chart theme based on dark mode
    function updateChartTheme() {
        if (chartInstance) {
            const isDark = document.documentElement.classList.contains('dark');
            
            chartInstance.options.plugins.legend.labels.color = isDark ? '#e2e8f0' : '#4a5568';
            chartInstance.options.scales.x.ticks.color = isDark ? '#e2e8f0' : '#4a5568';
            chartInstance.options.scales.y.ticks.color = isDark ? '#e2e8f0' : '#4a5568';
            chartInstance.options.scales.x.grid.color = isDark ? '#374151' : '#e2e8f0';
            chartInstance.options.scales.y.grid.color = isDark ? '#374151' : '#e2e8f0';
            
            chartInstance.update();
        }
    }
    
    // Tool selector functionality
    function initializeToolSelector() {
        toolSelector.addEventListener('change', () => {
            const selectedFunction = toolSelector.value;
            const selectedOption = toolSelector.options[toolSelector.selectedIndex];
            const hasMode = selectedOption.getAttribute('data-has-mode') === 'true';
            
            // Highlight active tool in sidebar
            document.querySelectorAll('.tool-link').forEach(l => l.classList.remove('active'));
            document.querySelectorAll(`.tool-link[data-function="${selectedFunction}"]`).forEach(l => l.classList.add('active'));
            
            // Handle mode switch visibility
            toggleModeSwitch(hasMode);
            
            // Update tool information
            updateToolInfo(selectedFunction);
            
            // Update breadcrumb
            updateBreadcrumb(selectedFunction);
            
            // Add to recent functions
            addToRecentFunctions(selectedFunction);
            
            // Handle additional inputs
            showRelevantInputs(selectedFunction);
            
            // Show appropriate UI based on tool
            toggleUIBasedOnTool(selectedFunction);
            
            // Update related tools
            updateRelatedTools(selectedFunction);
            
            // Update favorite button state
            updateFavoriteButtonState(selectedFunction);
            
            // Update URL with selected tool
            updateUrlWithTool(selectedFunction);
            
            // Store current function
            currentFunction = selectedFunction;
        });
        
        // Mode switch for encode/decode functions
        modeSwitch.addEventListener('change', () => {
            const mode = modeSwitch.checked ? 'decode' : 'encode';
            updateToolInfo(toolSelector.value, mode);
        });
        
        // Quick tool buttons
        document.querySelectorAll('.quick-tool-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                const functionName = btn.getAttribute('data-function');
                toolSelector.value = functionName;
                const event = new Event('change');
                toolSelector.dispatchEvent(event);
            });
        });
    }
    
    // Show/hide mode switch based on function type
    function toggleModeSwitch(hasMode) {
        if (hasMode) {
            modeSwitchContainer.classList.remove('hidden');
        } else {
            modeSwitchContainer.classList.add('hidden');
        }
    }
    
    // Toggle UI based on selected tool
    function toggleUIBasedOnTool(functionName) {
        // Hide all special containers first
        standardInputOutput.classList.add('hidden');
        diffCheckerContainer.classList.add('hidden');
        regexTesterContainer.classList.add('hidden');
        qrCodeContainer.classList.add('hidden');
        fileDropZone.classList.add('hidden');
        
        // Show appropriate container based on function
        switch (functionName) {
            case 'diff-checker':
                diffCheckerContainer.classList.remove('hidden');
                standardInputOutput.classList.remove('hidden');
                break;
            case 'regex-tester':
                regexTesterContainer.classList.remove('hidden');
                standardInputOutput.classList.remove('hidden');
                break;
            case 'qr-code':
                qrCodeContainer.classList.remove('hidden');
                break;
            case 'file-checksum':
                standardInputOutput.classList.remove('hidden');
                fileDropZone.classList.remove('hidden');
                break;
            default:
                standardInputOutput.classList.remove('hidden');
                break;
        }
    }
    
    // Show relevant additional input fields based on selected function
    function showRelevantInputs(functionName) {
        // Hide all input fields first
        document.querySelectorAll('#additionalInputs > div').forEach(div => {
            div.classList.add('hidden');
        });
        
        // Show the additional inputs container
        additionalInputs.classList.remove('hidden');
        
        // Show relevant fields based on function
        switch (functionName) {
            case 'hmac':
                document.getElementById('hmacKeyField').classList.remove('hidden');
                break;
            case 'aes':
            case 'des':
            case 'tripledes':
            case 'rabbit':
            case 'rc4':
            case 'blowfish':
            case 'twofish':
            case 'camellia':
                document.getElementById('encryptionKeyField').classList.remove('hidden');
                break;
            case 'random-string':
                document.getElementById('randomStringOptions').classList.remove('hidden');
                break;
            case 'password-generator':
                document.getElementById('passwordOptions').classList.remove('hidden');
                break;
            case 'hash-compare':
                document.getElementById('hashCompareField').classList.remove('hidden');
                break;
            default:
                additionalInputs.classList.add('hidden');
                break;
        }
    }
    
    // Update breadcrumb
    function updateBreadcrumb(functionName) {
        if (breadcrumbCurrent) {
            breadcrumbCurrent.textContent = formatFunctionName(functionName);
        }
    }
    
    // Initialize buttons
    function initializeButtons() {
        // Process button
        processBtn.addEventListener('click', () => {
            processCurrentFunction();
        });
        
        // Clear input button
        clearBtn.addEventListener('click', () => {
            inputText.value = '';
            updateCharCount();
            // Clear any additional inputs that might be visible
            document.querySelectorAll('#additionalInputs input, #additionalInputs select').forEach(input => {
                if (input.type === 'checkbox') {
                    input.checked = true; // Reset checkboxes to checked
                } else if (input.type === 'number') {
                    // Reset number inputs to default values
                    if (input.id === 'passwordLength' || input.id === 'randomLength') {
                        input.value = '16';
                    }
                } else if (input.type !== 'range') {
                    input.value = '';
                }
            });
            showToast('Input cleared!');
        });
        
        // Paste button
        if (pasteBtn) {
            pasteBtn.addEventListener('click', async () => {
                try {
                    const text = await navigator.clipboard.readText();
                    inputText.value = text;
                    updateCharCount();
                    showToast('Text pasted from clipboard!');
                } catch (err) {
                    showToast('Failed to read clipboard contents!', 'error');
                }
            });
        }
        
        // Copy input button
        copyBtn.addEventListener('click', () => {
            copyToClipboard(inputText.value);
            showToast('Input copied to clipboard!');
        });
        
        // Copy result button (supports HTML and Text outputs)
        copyResultBtn.addEventListener('click', () => {
            const isHtmlVisible = outputHtml && !outputHtml.classList.contains('hidden');
            const text = isHtmlVisible ? outputHtml.innerText : outputText.value;
            copyToClipboard(text);
            showToast('Result copied to clipboard!');
        });
        
        // Download result button
        downloadResultBtn.addEventListener('click', () => {
            downloadResult();
        });
        
        // Clear all results button
        if (clearAllResults) {
            clearAllResults.addEventListener('click', () => {
                allResultsContainer.innerHTML = '';
                allResultsSection.classList.add('hidden');
                showToast('All results cleared!');
            });
        }
        
        // Custom charset toggle
        const randomCharset = document.getElementById('randomCharset');
        if (randomCharset) {
            randomCharset.addEventListener('change', () => {
                const customCharsetDiv = document.getElementById('customCharset');
                if (randomCharset.value === 'custom') {
                    customCharsetDiv.classList.remove('hidden');
                } else {
                    customCharsetDiv.classList.add('hidden');
                }
            });
        }
        
        // Toggle password visibility
        if (toggleKeyVisibility) {
            toggleKeyVisibility.addEventListener('click', () => {
                const encryptionKey = document.getElementById('encryptionKey');
                const icon = toggleKeyVisibility.querySelector('i');
                
                if (encryptionKey.type === 'password') {
                    encryptionKey.type = 'text';
                    icon.classList.remove('fa-eye');
                    icon.classList.add('fa-eye-slash');
                } else {
                    encryptionKey.type = 'password';
                    icon.classList.remove('fa-eye-slash');
                    icon.classList.add('fa-eye');
                }
            });
        }
        
        // Favorite button
        if (favoriteBtn) {
            favoriteBtn.addEventListener('click', toggleFavorite);
        }
        
        // Generate password button
        if (generatePasswordBtn) {
            generatePasswordBtn.addEventListener('click', () => {
                generatePassword();
            });
        }
        
        // Toggle stats view
        if (toggleStatsView) {
            toggleStatsView.addEventListener('click', () => {
                const isTableView = statsTableView.classList.contains('hidden');
                
                if (isTableView) {
                    statsChartView.classList.add('hidden');
                    statsTableView.classList.remove('hidden');
                    toggleStatsView.textContent = 'Switch to Chart View';
                } else {
                    statsChartView.classList.remove('hidden');
                    statsTableView.classList.add('hidden');
                    toggleStatsView.textContent = 'Switch to Table View';
                }
            });
        }
        
        // Manage favorites
        if (manageFavorites) {
            manageFavorites.addEventListener('click', () => {
                // Logic for managing favorites would go here
                showToast('Favorites management coming soon!', 'info');
            });
        }
        
        // Clear recent
        if (clearRecent) {
            clearRecent.addEventListener('click', () => {
                localStorage.removeItem('recentFunctions');
                updateRecentFunctionsDisplay([]);
                showToast('Recent functions cleared!');
            });
        }
        
        // Share button
        if (shareBtn) {
            shareBtn.addEventListener('click', shareTool);
        }
    }
    
    // Function to share the current tool
    function shareTool() {
        if (navigator.share && currentFunction) {
            const url = new URL(window.location);
            url.searchParams.set('tool', currentFunction);
            
            navigator.share({
                title: `Crypt.Tools - ${formatFunctionName(currentFunction)}`,
                text: `Check out this useful cryptography tool: ${formatFunctionName(currentFunction)}`,
                url: url.toString()
            })
            .then(() => showToast('Shared successfully!'))
            .catch((error) => {
                if (error.name !== 'AbortError') {
                    showToast('Error sharing tool', 'error');
                }
            });
        } else {
            // Fallback to copy link
            const url = new URL(window.location);
            url.searchParams.set('tool', currentFunction);
            copyToClipboard(url.toString());
            showToast('Link copied to clipboard!');
        }
    }
    
    // Initialize modals
    function initializeModals() {
        // Settings modal
        if (settingsBtn && settingsModal && closeSettings) {
            settingsBtn.addEventListener('click', () => {
                settingsModal.classList.remove('hidden');
            });
            
            closeSettings.addEventListener('click', () => {
                settingsModal.classList.add('hidden');
            });
            
            // Close when clicking outside
            settingsModal.addEventListener('click', (e) => {
                if (e.target === settingsModal) {
                    settingsModal.classList.add('hidden');
                }
            });
            
            // Save settings
            if (saveSettings) {
                saveSettings.addEventListener('click', () => {
                    // Logic to save settings would go here
                    showToast('Settings saved!');
                    settingsModal.classList.add('hidden');
                });
            }
            
            // Reset settings
            if (resetSettings) {
                resetSettings.addEventListener('click', () => {
                    // Logic to reset settings would go here
                    showToast('Settings reset to default!');
                });
            }
        }
        
        // Shortcuts modal
        if (shortcutsBtn && shortcutsModal && closeShortcuts) {
            shortcutsBtn.addEventListener('click', () => {
                shortcutsModal.classList.remove('hidden');
            });
            
            closeShortcuts.addEventListener('click', () => {
                shortcutsModal.classList.add('hidden');
            });
            
            // Close when clicking outside
            shortcutsModal.addEventListener('click', (e) => {
                if (e.target === shortcutsModal) {
                    shortcutsModal.classList.add('hidden');
                }
            });
        }
        
        // Mobile menu
        const menuButton = document.getElementById('menu-button');
        const mobileMenu = document.getElementById('mobile-menu');
        const closeMenu = document.getElementById('close-menu');
        
        if (menuButton && mobileMenu && closeMenu) {
            menuButton.addEventListener('click', () => {
                mobileMenu.classList.remove('hidden');
                setTimeout(() => {
                    const mobileMenuContent = mobileMenu.querySelector('div');
                    mobileMenuContent.classList.remove('translate-x-full');
                }, 10);
            });
            
            closeMenu.addEventListener('click', () => {
                const mobileMenuContent = mobileMenu.querySelector('div');
                mobileMenuContent.classList.add('translate-x-full');
                setTimeout(() => {
                    mobileMenu.classList.add('hidden');
                }, 300);
            });
            
            // Close when clicking outside
            mobileMenu.addEventListener('click', (e) => {
                if (e.target === mobileMenu) {
                    const mobileMenuContent = mobileMenu.querySelector('div');
                    mobileMenuContent.classList.add('translate-x-full');
                    setTimeout(() => {
                        mobileMenu.classList.add('hidden');
                    }, 300);
                }
            });
        }
        
        // User menu
        const userMenuBtn = document.getElementById('user-menu-btn');
        const userMenu = document.getElementById('user-menu');
        
        if (userMenuBtn && userMenu) {
            userMenuBtn.addEventListener('click', () => {
                userMenu.classList.toggle('hidden');
            });
            
            // Close when clicking elsewhere
            document.addEventListener('click', (e) => {
                if (!userMenuBtn.contains(e.target) && !userMenu.contains(e.target)) {
                    userMenu.classList.add('hidden');
                }
            });
        }
    }
    
    // Initialize range sliders
    function initializeRangeSliders() {
        // Password length slider
        if (passwordLengthSlider && passwordLength && passwordLengthValue) {
            passwordLengthSlider.addEventListener('input', () => {
                passwordLength.value = passwordLengthSlider.value;
                passwordLengthValue.textContent = passwordLengthSlider.value;
                updatePasswordStrength();
            });
            
            passwordLength.addEventListener('input', () => {
                // Ensure value is within min and max
                const value = Math.max(4, Math.min(64, parseInt(passwordLength.value) || 16));
                passwordLength.value = value;
                passwordLengthSlider.value = value;
                passwordLengthValue.textContent = value;
                updatePasswordStrength();
            });
        }
        
        // Random string length slider
        const randomLengthSlider = document.getElementById('randomLengthSlider');
        const randomLength = document.getElementById('randomLength');
        
        if (randomLengthSlider && randomLength) {
            randomLengthSlider.addEventListener('input', () => {
                randomLength.value = randomLengthSlider.value;
            });
            
            randomLength.addEventListener('input', () => {
                // Ensure value is within min and max
                const value = Math.max(1, Math.min(1024, parseInt(randomLength.value) || 16));
                randomLength.value = value;
                randomLengthSlider.value = value;
            });
        }
    }
    
    // Update password strength indicator
    function updatePasswordStrength() {
        if (!passwordStrength || !passwordStrengthText) return;
        
        const length = parseInt(passwordLength.value) || 16;
        const useUpper = document.getElementById('includeUppercase').checked;
        const useLower = document.getElementById('includeLowercase').checked;
        const useNumbers = document.getElementById('includeNumbers').checked;
        const useSymbols = document.getElementById('includeSymbols').checked;
        
        // Calculate strength score (0-100)
        let score = 0;
        
        // Length contribution (up to 50 points)
        score += Math.min(50, length * 1.5);
        
        // Character set contribution (up to 50 points)
        let charsetScore = 0;
        if (useUpper) charsetScore += 10;
        if (useLower) charsetScore += 10;
        if (useNumbers) charsetScore += 15;
        if (useSymbols) charsetScore += 15;
        score += charsetScore;
        
        // Cap at 100
        score = Math.min(100, score);
        
        // Update visual indicators
        passwordStrength.style.width = `${score}%`;
        
        // Update color and text based on score
        if (score < 40) {
            passwordStrength.className = 'bg-red-600 h-2.5 rounded-full';
            passwordStrengthText.className = 'text-sm text-red-700 dark:text-red-500';
            passwordStrengthText.textContent = 'Weak';
        } else if (score < 70) {
            passwordStrength.className = 'bg-yellow-500 h-2.5 rounded-full';
            passwordStrengthText.className = 'text-sm text-yellow-700 dark:text-yellow-500';
            passwordStrengthText.textContent = 'Moderate';
        } else if (score < 90) {
            passwordStrength.className = 'bg-blue-600 h-2.5 rounded-full';
            passwordStrengthText.className = 'text-sm text-blue-700 dark:text-blue-500';
            passwordStrengthText.textContent = 'Strong';
        } else {
            passwordStrength.className = 'bg-green-600 h-2.5 rounded-full';
            passwordStrengthText.className = 'text-sm text-green-700 dark:text-green-500';
            passwordStrengthText.textContent = 'Very Strong';
        }
    }
    
    // Copy text to clipboard
    function copyToClipboard(text) {
        if (!text) return;
        
        navigator.clipboard.writeText(text).catch(err => {
            // Fallback method for browsers that don't support clipboard API
            const textArea = document.createElement('textarea');
            textArea.value = text;
            textArea.style.position = 'fixed';
            document.body.appendChild(textArea);
            textArea.focus();
            textArea.select();
            try {
                document.execCommand('copy');
            } catch (err) {
                console.error('Failed to copy: ', err);
            }
            document.body.removeChild(textArea);
        });
    }
    
    // Download result as a text file
    function downloadResult() {
        const isHtmlVisible = outputHtml && !outputHtml.classList.contains('hidden');
        const text = isHtmlVisible ? outputHtml.innerText : outputText.value;
        if (!text) {
            showToast('No result to download!', 'error');
            return;
        }
        
        const blob = new Blob([text], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        const functionName = toolSelector.value;
        
        a.href = url;
        a.download = `${functionName}-result-${new Date().toISOString().slice(0, 10)}.txt`;
        document.body.appendChild(a);
        a.click();
        
        // Cleanup
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
        showToast('Result downloaded!');
    }
    
    // Process the current function
    function processCurrentFunction() {
        const functionName = toolSelector.value;
        const input = inputText.value;
        
        // Check if input is empty for functions that require input
        if (!input && !['random-string', 'password-generator', 'uuid'].includes(functionName)) {
            showToast('Please enter some input text!', 'error');
            return;
        }
        
        let result;
        const isDecoding = modeSwitch.checked;
        
        try {
            // Add loading indicator to process button
            processBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>Processing...';
            processBtn.disabled = true;
            
            // Process based on function type
            switch (functionName) {
                // Hash functions
                case 'md5':
                    result = CryptoJS.MD5(input).toString();
                    break;
                case 'sha1':
                    result = CryptoJS.SHA1(input).toString();
                    break;
                case 'sha256':
                    result = CryptoJS.SHA256(input).toString();
                    break;
                case 'sha512':
                    result = CryptoJS.SHA512(input).toString();
                    break;
                case 'sha3':
                    result = CryptoJS.SHA3(input).toString();
                    break;
                case 'ripemd160':
                    result = CryptoJS.RIPEMD160(input).toString();
                    break;
                case 'keccak':
                    result = CryptoJS.SHA3(input, { outputLength: 256 }).toString();
                    break;
                    
                // Encoding/Decoding functions
                case 'base64':
                    if (isDecoding) {
                        try {
                            result = atob(input.trim());
                        } catch (e) {
                            throw new Error('Invalid Base64 string');
                        }
                    } else {
                        result = btoa(input);
                    }
                    break;
                case 'url':
                    if (isDecoding) {
                        result = decodeURIComponent(input);
                    } else {
                        result = encodeURIComponent(input);
                    }
                    break;
                case 'html':
                    if (isDecoding) {
                        const textarea = document.createElement('textarea');
                        textarea.innerHTML = input;
                        result = textarea.value;
                    } else {
                        const div = document.createElement('div');
                        div.textContent = input;
                        result = div.innerHTML;
                    }
                    break;
                case 'hex':
                    if (isDecoding) {
                        result = hexToString(input);
                    } else {
                        result = stringToHex(input);
                    }
                    break;
                case 'binary':
                    if (isDecoding) {
                        result = binaryToString(input);
                    } else {
                        result = stringToBinary(input);
                    }
                    break;
                case 'json':
                    if (isDecoding) {
                        try {
                            const obj = JSON.parse(input);
                            result = JSON.stringify(obj, null, 2);
                        } catch (e) {
                            throw new Error('Invalid JSON string');
                        }
                    } else {
                        try {
                            const obj = JSON.parse(input);
                            result = JSON.stringify(obj);
                        } catch (e) {
                            throw new Error('Invalid JSON object');
                        }
                    }
                    break;
                    
                // Encryption functions
                case 'aes':
                    const aesKey = document.getElementById('encryptionKey').value;
                    if (!aesKey) {
                        showToast('Please enter an encryption key!', 'error');
                        return;
                    }
                    
                    if (isDecoding) {
                        try {
                            const decrypted = CryptoJS.AES.decrypt(input, aesKey);
                            result = decrypted.toString(CryptoJS.enc.Utf8);
                            if (!result) throw new Error('Decryption failed');
                        } catch (e) {
                            throw new Error('Decryption failed. Check your key and input!');
                        }
                    } else {
                        result = CryptoJS.AES.encrypt(input, aesKey).toString();
                    }
                    break;
                    
                case 'des':
                case 'tripledes':
                    const desKey = document.getElementById('encryptionKey').value;
                    if (!desKey) {
                        showToast('Please enter an encryption key!', 'error');
                        return;
                    }
                    
                    if (isDecoding) {
                        try {
                            const decrypted = functionName === 'des' 
                                ? CryptoJS.DES.decrypt(input, desKey)
                                : CryptoJS.TripleDES.decrypt(input, desKey);
                            result = decrypted.toString(CryptoJS.enc.Utf8);
                            if (!result) throw new Error('Decryption failed');
                        } catch (e) {
                            throw new Error('Decryption failed. Check your key and input!');
                        }
                    } else {
                        result = functionName === 'des'
                            ? CryptoJS.DES.encrypt(input, desKey).toString()
                            : CryptoJS.TripleDES.encrypt(input, desKey).toString();
                    }
                    break;
                    
                case 'rabbit':
                    const rabbitKey = document.getElementById('encryptionKey').value;
                    if (!rabbitKey) {
                        showToast('Please enter an encryption key!', 'error');
                        return;
                    }
                    
                    if (isDecoding) {
                        try {
                            const decrypted = CryptoJS.Rabbit.decrypt(input, rabbitKey);
                            result = decrypted.toString(CryptoJS.enc.Utf8);
                            if (!result) throw new Error('Decryption failed');
                        } catch (e) {
                            throw new Error('Decryption failed. Check your key and input!');
                        }
                    } else {
                        result = CryptoJS.Rabbit.encrypt(input, rabbitKey).toString();
                    }
                    break;
                
            case 'rc4':
                const rc4Key = document.getElementById('encryptionKey').value;
                if (!rc4Key) {
                    showToast('Please enter an encryption key!', 'error');
                    return;
                }
                
                if (isDecoding) {
                    try {
                        const decrypted = CryptoJS.RC4.decrypt(input, rc4Key);
                        result = decrypted.toString(CryptoJS.enc.Utf8);
                        if (!result) throw new Error('Decryption failed');
                    } catch (e) {
                        throw new Error('Decryption failed. Check your key and input!');
                    }
                } else {
                    result = CryptoJS.RC4.encrypt(input, rc4Key).toString();
                }
                break;
                
            // Other functions    
            case 'hmac':
                const hmacKey = document.getElementById('hmacKey').value;
                if (!hmacKey) {
                    showToast('Please enter a secret key!', 'error');
                    return;
                }
                result = CryptoJS.HmacSHA256(input, hmacKey).toString();
                break;
                
            case 'random-string':
                const length = parseInt(document.getElementById('randomLength').value) || 16;
                const charsetType = document.getElementById('randomCharset').value;
                const excludeSimilar = document.getElementById('excludeSimilar').checked;
                const excludeAmbiguous = document.getElementById('excludeAmbiguous').checked;
                result = generateRandomString(length, charsetType, excludeSimilar, excludeAmbiguous);
                break;
                
            case 'password-generator':
                result = generatePassword();
                break;
                
            case 'uuid':
                result = generateUUID();
                break;
                
            case 'hash-compare':
                const hashToCompare = document.getElementById('hashToCompare').value;
                const hashAlgorithm = document.getElementById('hashAlgorithm').value;
                if (!hashToCompare) {
                    showToast('Please enter a hash to compare!', 'error');
                    return;
                }
                result = compareHash(input, hashToCompare, hashAlgorithm);
                break;
                
            case 'diff-checker':
                const originalText = document.getElementById('diffOriginalText').value;
                const modifiedText = document.getElementById('diffModifiedText').value;
                result = calculateDiff(originalText, modifiedText, 'inline');
                // Render HTML result in outputHtml for diff checker
                outputHtml.innerHTML = result;
                outputHtml.classList.remove('hidden');
                outputText.classList.add('hidden');
                
                // Add to usage stats
                addToUsageStats(functionName);
                
                // Reset process button
                processBtn.innerHTML = '<i class="fas fa-play mr-2"></i>Process';
                processBtn.disabled = false;
                
                return;
                
            case 'regex-tester':
                const regexPattern = document.getElementById('regexPattern').value;
                const regexFlags = document.getElementById('regexFlags').value;
                const testString = document.getElementById('regexTestString').value;
                
                if (!regexPattern) {
                    showToast('Please enter a regex pattern!', 'error');
                    return;
                }
                
                result = testRegex(regexPattern, regexFlags, testString);
                // Render HTML result in outputHtml for regex tester
                outputHtml.innerHTML = result;
                outputHtml.classList.remove('hidden');
                outputText.classList.add('hidden');
                
                // Add to usage stats
                addToUsageStats(functionName);
                
                // Reset process button
                processBtn.innerHTML = '<i class="fas fa-play mr-2"></i>Process';
                processBtn.disabled = false;
                
                return;
                
            case 'qr-code':
                const qrInput = document.getElementById('qrCodeInput').value;
                const qrSize = parseInt(document.getElementById('qrCodeSize').value) || 200;
                const qrErrorCorrection = document.getElementById('qrCodeErrorCorrection').value || 'M';
                
                if (!qrInput) {
                    showToast('Please enter text to generate QR code!', 'error');
                    return;
                }
                
                generateQRCode(qrInput, qrSize, qrErrorCorrection);
                
                // QR code is handled differently
                // Add to usage stats
                addToUsageStats(functionName);
                
                // Reset process button
                processBtn.innerHTML = '<i class="fas fa-play mr-2"></i>Process';
                processBtn.disabled = false;
                
                return;
                
            case 'file-checksum':
                if (!fileDropZone.files || !fileDropZone.files[0]) {
                    showToast('Please select a file first!', 'error');
                    return;
                }
                
                calculateFileChecksum(fileDropZone.files[0]);
                
                // File checksum is handled asynchronously
                // Reset process button is handled in the callback
                return;
                
            default:
                result = 'Function not implemented yet.';
                break;
        }
        
        // Update output (default: plain text in textarea)
        if (typeof result === 'string') {
            outputText.value = result;
        } else {
            outputText.value = String(result ?? '');
        }
        updateCharCount();
        outputText.classList.remove('html-content');
        outputText.classList.remove('hidden');
        if (outputHtml) outputHtml.classList.add('hidden');
        
        // Add to recent functions
        addToRecentFunctions(functionName);
        
        // Add to all results if it's not already there
        addToAllResults(functionName, input, result);
        
        // Add to usage stats
        addToUsageStats(functionName);
        
        showToast('Processing complete!');
        
    } catch (error) {
        console.error('Processing error:', error);
        showToast(error.message || 'Error processing your request!', 'error');
    } finally {
        // Reset process button
        processBtn.innerHTML = '<i class="fas fa-play mr-2"></i>Process';
        processBtn.disabled = false;
    }
}

// Helper functions for processing
function stringToHex(str) {
    let hex = '';
    for (let i = 0; i < str.length; i++) {
        const charCode = str.charCodeAt(i);
        hex += charCode.toString(16).padStart(2, '0');
    }
    return hex;
}

function hexToString(hex) {
    hex = hex.replace(/\s+/g, ''); // Remove whitespace
    const hexArray = hex.match(/.{1,2}/g) || [];
    let str = '';
    for (let i = 0; i < hexArray.length; i++) {
        str += String.fromCharCode(parseInt(hexArray[i], 16));
    }
    return str;
}

function stringToBinary(str) {
    return str.split('').map(char => {
        return char.charCodeAt(0).toString(2).padStart(8, '0');
    }).join(' ');
}

function binaryToString(binary) {
    binary = binary.replace(/\s+/g, ''); // Remove whitespace
    const binaryArray = binary.match(/.{1,8}/g) || [];
    let str = '';
    for (let i = 0; i < binaryArray.length; i++) {
        str += String.fromCharCode(parseInt(binaryArray[i], 2));
    }
    return str;
}

function generateRandomString(length, charsetType, excludeSimilar = false, excludeAmbiguous = false) {
    let charset = '';
    
    // Define character sets
    const upperChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    const lowerChars = 'abcdefghijklmnopqrstuvwxyz';
    const numberChars = '0123456789';
    const hexChars = '0123456789abcdef';
    const similarChars = 'iIlL1oO0';
    const ambiguousChars = ['{','}','[',']','(',')','/','"','\'','`',',',';',':','.', '>', '<'];
    
    switch (charsetType) {
        case 'alphanumeric':
            charset = upperChars + lowerChars + numberChars;
            break;
        case 'alphabetic':
            charset = upperChars + lowerChars;
            break;
        case 'numeric':
            charset = numberChars;
            break;
        case 'hex':
            charset = hexChars;
            break;
        case 'custom':
            charset = document.getElementById('customCharsetInput').value;
            if (!charset) {
                showToast('Please enter a custom character set!', 'error');
                return '';
            }
            break;
    }
    
    // Remove similar/ambiguous characters if requested
    if (excludeSimilar) {
        for (const char of similarChars) {
            charset = charset.replace(new RegExp(char, 'g'), '');
        }
    }
    
    if (excludeAmbiguous) {
        for (const ch of ambiguousChars) {
            // Remove each ambiguous character without using regex to avoid escaping pitfalls
            charset = charset.split(ch).join('');
        }
    }
    
    if (charset.length === 0) {
        showToast('Character set is empty after applying filters!', 'error');
        return '';
    }
    
    let result = '';
    const charsetLength = charset.length;
    
    // Use crypto.getRandomValues for better randomness if available
    if (window.crypto && window.crypto.getRandomValues) {
        const values = new Uint32Array(length);
        window.crypto.getRandomValues(values);
        for (let i = 0; i < length; i++) {
            result += charset.charAt(values[i] % charsetLength);
        }
    } else {
        for (let i = 0; i < length; i++) {
            result += charset.charAt(Math.floor(Math.random() * charsetLength));
        }
    }
    
    return result;
}

function generatePassword() {
    const length = parseInt(document.getElementById('passwordLength').value) || 16;
    const options = {
        uppercase: document.getElementById('includeUppercase').checked,
        lowercase: document.getElementById('includeLowercase').checked,
        numbers: document.getElementById('includeNumbers').checked,
        symbols: document.getElementById('includeSymbols').checked,
        excludeSimilar: document.getElementById('excludeSimilarChars').checked,
        requireAllTypes: document.getElementById('requireAllTypes').checked,
        memorable: document.getElementById('memorablePassword')?.checked || false
    };
    
    // Check if at least one character type is selected
    if (!options.uppercase && !options.lowercase && !options.numbers && !options.symbols) {
        showToast('Please select at least one character type!', 'error');
        return '';
    }
    
    // Generate memorable password
    if (options.memorable) {
        return generateMemorablePassword(length);
    }
    
    // Define character sets
    let charset = '';
    const upperChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    const lowerChars = 'abcdefghijklmnopqrstuvwxyz';
    const numberChars = '0123456789';
    const symbolChars = '!@#$%^&*()-_=+[]{}|;:,./<>?';
    const similarChars = 'iIlL1oO0';
    
    // Build charset based on options
    if (options.uppercase) charset += upperChars;
    if (options.lowercase) charset += lowerChars;
    if (options.numbers) charset += numberChars;
    if (options.symbols) charset += symbolChars;
    
    // Remove similar characters if requested
    if (options.excludeSimilar) {
        for (const char of similarChars) {
            charset = charset.replace(new RegExp(char, 'g'), '');
        }
    }
    
    // Generate password
    let password = '';
    
    // Ensure at least one of each required type if specified
    if (options.requireAllTypes) {
        if (options.uppercase) {
            password += upperChars.charAt(Math.floor(Math.random() * upperChars.length));
        }
        if (options.lowercase) {
            password += lowerChars.charAt(Math.floor(Math.random() * lowerChars.length));
        }
        if (options.numbers) {
            password += numberChars.charAt(Math.floor(Math.random() * numberChars.length));
        }
        if (options.symbols) {
            password += symbolChars.charAt(Math.floor(Math.random() * symbolChars.length));
        }
    }
    
    // Fill remaining length with random characters
    const remainingLength = length - password.length;
    
    // Use crypto.getRandomValues for better randomness if available
    if (window.crypto && window.crypto.getRandomValues) {
        const values = new Uint32Array(remainingLength);
        window.crypto.getRandomValues(values);
        for (let i = 0; i < remainingLength; i++) {
            password += charset.charAt(values[i] % charset.length);
        }
    } else {
        for (let i = 0; i < remainingLength; i++) {
            password += charset.charAt(Math.floor(Math.random() * charset.length));
        }
    }
    
    // Shuffle the password to mix the required characters randomly
    if (options.requireAllTypes && password.length > 1) {
        password = shuffleString(password);
    }
    
    return password;
}

function generateMemorablePassword(targetLength) {
    // List of common words (this is a small sample, you'd want a larger dictionary in production)
    const words = [
        'apple', 'banana', 'orange', 'grape', 'lemon', 'peach', 'cherry', 'pear', 'plum', 'melon',
        'house', 'car', 'road', 'tree', 'river', 'mountain', 'ocean', 'forest', 'desert', 'sky',
        'book', 'pen', 'paper', 'desk', 'chair', 'table', 'phone', 'computer', 'keyboard', 'mouse',
        'dog', 'cat', 'bird', 'fish', 'horse', 'tiger', 'lion', 'elephant', 'monkey', 'bear',
        'happy', 'sad', 'angry', 'calm', 'quiet', 'loud', 'fast', 'slow', 'hot', 'cold'
    ];
    
    // Generate a password by concatenating words
    let password = '';
    let capitalizeNext = true;
    
    while (password.length < targetLength) {
        // Get a random word
        const word = words[Math.floor(Math.random() * words.length)];
        
        // Capitalize first letter or after a delimiter
        if (capitalizeNext) {
            password += word.charAt(0).toUpperCase() + word.slice(1);
            capitalizeNext = false;
        } else {
            password += word;
        }
        
        // Add a delimiter if we need more words
        if (password.length < targetLength - 1) {
            // Use various delimiters
            const delimiters = '.-_!@#$%&*';
            const delimiter = delimiters.charAt(Math.floor(Math.random() * delimiters.length));
            password += delimiter;
            capitalizeNext = true;
        }
    }
    
    // Truncate to exact length if needed
    if (password.length > targetLength) {
        password = password.slice(0, targetLength);
    }
    
    // Add a random number if password is too short
    if (password.length < targetLength) {
        const numberToAdd = Math.floor(Math.random() * 100);
        password += numberToAdd;
    }
    
    return password;
}

function shuffleString(str) {
    const array = str.split('');
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
    return array.join('');
}

function generateUUID() {
    // Use crypto.getRandomValues for better randomness if available
    if (window.crypto && window.crypto.getRandomValues) {
        return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
            (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
        );
    }
    
    // Fallback to Math.random()
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        const r = Math.random() * 16 | 0;
        const v = c === 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

function compareHash(input, hashToCompare, algorithm) {
    // Normalize the hashes (remove whitespace, convert to lowercase)
    hashToCompare = hashToCompare.replace(/\s+/g, '').toLowerCase();
    
    let calculatedHash;
    
    if (algorithm === 'auto') {
        // Auto-detect based on length
        switch (hashToCompare.length) {
            case 32: // MD5
                calculatedHash = CryptoJS.MD5(input).toString();
                algorithm = 'MD5';
                break;
            case 40: // SHA-1
                calculatedHash = CryptoJS.SHA1(input).toString();
                algorithm = 'SHA-1';
                break;
            case 64: // SHA-256
                calculatedHash = CryptoJS.SHA256(input).toString();
                algorithm = 'SHA-256';
                break;
            case 128: // SHA-512
                calculatedHash = CryptoJS.SHA512(input).toString();
                algorithm = 'SHA-512';
                break;
            default:
                // Try multiple algorithms
                if (CryptoJS.MD5(input).toString() === hashToCompare) {
                    return 'Match found: MD5 ?';
                }
                if (CryptoJS.SHA1(input).toString() === hashToCompare) {
                    return 'Match found: SHA-1 ?';
                }
                if (CryptoJS.SHA256(input).toString() === hashToCompare) {
                    return 'Match found: SHA-256 ?';
                }
                if (CryptoJS.SHA512(input).toString() === hashToCompare) {
                    return 'Match found: SHA-512 ?';
                }
                if (CryptoJS.SHA3(input).toString() === hashToCompare) {
                    return 'Match found: SHA-3 ?';
                }
                if (CryptoJS.RIPEMD160(input).toString() === hashToCompare) {
                    return 'Match found: RIPEMD-160 ?';
                }
                
                return 'No match found for any common hash algorithm ?';
        }
    } else {
        // Use specified algorithm
        switch (algorithm) {
            case 'md5':
                calculatedHash = CryptoJS.MD5(input).toString();
                algorithm = 'MD5';
                break;
            case 'sha1':
                calculatedHash = CryptoJS.SHA1(input).toString();
                algorithm = 'SHA-1';
                break;
            case 'sha256':
                calculatedHash = CryptoJS.SHA256(input).toString();
                algorithm = 'SHA-256';
                break;
            case 'sha512':
                calculatedHash = CryptoJS.SHA512(input).toString();
                algorithm = 'SHA-512';
                break;
            case 'sha3':
                calculatedHash = CryptoJS.SHA3(input).toString();
                algorithm = 'SHA-3';
                break;
            default:
                calculatedHash = CryptoJS.SHA256(input).toString();
                algorithm = 'SHA-256';
                break;
        }
    }
    
    const matches = calculatedHash.toLowerCase() === hashToCompare;
    
    if (matches) {
        return `Hash matches! Algorithm: ${algorithm} ?`;
    } else {
        return `Hash does not match! Algorithm: ${algorithm} ?\n\nCalculated: ${calculatedHash}\nProvided: ${hashToCompare}`;
    }
}

function calculateFileChecksum(file) {
    const reader = new FileReader();
    
    // Show loading state
    outputText.value = 'Calculating checksums...';
    
    reader.onload = function(e) {
        const wordArray = CryptoJS.lib.WordArray.create(e.target.result);
        
        // Calculate multiple hash types
        const md5 = CryptoJS.MD5(wordArray).toString();
        const sha1 = CryptoJS.SHA1(wordArray).toString();
        const sha256 = CryptoJS.SHA256(wordArray).toString();
        const sha512 = CryptoJS.SHA512(wordArray).toString();
        
        // Format file size
        const fileSize = formatFileSize(file.size);
        
        // Display results
        outputText.value = `File: ${file.name} (${fileSize})\n\n` +
                          `MD5: ${md5}\n` +
                          `SHA-1: ${sha1}\n` +
                          `SHA-256: ${sha256}\n` +
                          `SHA-512: ${sha512}`;
        
        // Update character count
        updateCharCount();
        
        // Add to all results
        addToAllResults('file-checksum', `File: ${file.name}`, outputText.value);
        
        // Add to usage stats
        addToUsageStats('file-checksum');
        
        showToast('File checksum calculated!');
        
        // Reset process button
        processBtn.innerHTML = '<i class="fas fa-play mr-2"></i>Process';
        processBtn.disabled = false;
    };
    
    reader.onerror = function() {
        outputText.value = 'Error reading file';
        showToast('Error reading file!', 'error');
        
        // Reset process button
        processBtn.innerHTML = '<i class="fas fa-play mr-2"></i>Process';
        processBtn.disabled = false;
    };
    
    reader.readAsArrayBuffer(file);
}

function formatFileSize(bytes) {
    if (bytes === 0) return '0 Bytes';
    
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

// Initialize QR Code functionality
function initializeQRCode() {
    const qrCodeInput = document.getElementById('qrCodeInput');
    const qrCodeOutput = document.getElementById('qrCodeOutput');
    const qrCodeSize = document.getElementById('qrCodeSize');
    const qrCodeErrorCorrection = document.getElementById('qrCodeErrorCorrection');
    const downloadQrCodeBtn = document.getElementById('downloadQrCodeBtn');
    
    if (!qrCodeInput || !qrCodeOutput) return;
    
    // Generate QR code on input change
    qrCodeInput.addEventListener('input', () => {
        if (qrCodeInput.value.trim()) {
            const size = parseInt(qrCodeSize.value) || 200;
            const errorCorrection = qrCodeErrorCorrection.value || 'M';
            generateQRCode(qrCodeInput.value, size, errorCorrection);
            downloadQrCodeBtn.disabled = false;
        } else {
            qrCodeOutput.innerHTML = `
                <div class="text-gray-400 dark:text-gray-500 text-center">
                    <i class="fas fa-qrcode text-4xl mb-2"></i>
                    <p>QR code will appear here</p>
                </div>
            `;
            downloadQrCodeBtn.disabled = true;
        }
    });
    
    // Update QR code when size changes
    qrCodeSize.addEventListener('change', () => {
        if (qrCodeInput.value.trim()) {
            const size = parseInt(qrCodeSize.value) || 200;
            const errorCorrection = qrCodeErrorCorrection.value || 'M';
            generateQRCode(qrCodeInput.value, size, errorCorrection);
        }
    });
    
    // Update QR code when error correction changes
    qrCodeErrorCorrection.addEventListener('change', () => {
        if (qrCodeInput.value.trim()) {
            const size = parseInt(qrCodeSize.value) || 200;
            const errorCorrection = qrCodeErrorCorrection.value || 'M';
            generateQRCode(qrCodeInput.value, size, errorCorrection);
        }
    });
    
    // Download QR code
    downloadQrCodeBtn.addEventListener('click', () => {
        const canvas = document.querySelector('#qrCodeOutput canvas');
        if (!canvas) {
            showToast('No QR code to download!', 'error');
            return;
        }
        
        const link = document.createElement('a');
        link.download = 'qrcode.png';
        link.href = canvas.toDataURL('image/png');
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        
        showToast('QR code downloaded!');
    });
}

function generateQRCode(text, size = 200, errorCorrectionLevel = 'M') {
    const qrCodeOutput = document.getElementById('qrCodeOutput');
    
    if (!qrCodeOutput) return;
    
    // Clear previous QR code
    qrCodeOutput.innerHTML = '';
    
    // Generate new QR code
    try {
        QRCode.toCanvas(qrCodeOutput, text, {
            width: size,
            margin: 1,
            color: {
                dark: document.documentElement.classList.contains('dark') ? '#FFFFFF' : '#000000',
                light: document.documentElement.classList.contains('dark') ? '#111827' : '#FFFFFF'
            },
            errorCorrectionLevel: errorCorrectionLevel
        }, function(error) {
            if (error) {
                console.error(error);
                qrCodeOutput.innerHTML = `
                    <div class="text-red-500 text-center">
                        <i class="fas fa-exclamation-circle text-4xl mb-2"></i>
                        <p>Error generating QR code</p>
                    </div>
                `;
                showToast('Error generating QR code!', 'error');
            }
        });
    } catch (error) {
        console.error(error);
        qrCodeOutput.innerHTML = `
            <div class="text-red-500 text-center">
                <i class="fas fa-exclamation-circle text-4xl mb-2"></i>
                <p>Error generating QR code</p>
            </div>
        `;
        showToast('Error generating QR code!', 'error');
    }
}

// Initialize Regex Tester functionality
function initializeRegexTester() {
    const regexPattern = document.getElementById('regexPattern');
    const regexFlags = document.getElementById('regexFlags');
    const regexTestString = document.getElementById('regexTestString');
    
    if (!regexPattern || !regexFlags || !regexTestString) return;
    
    // Live preview for regex tester
    const updateRegexPreview = () => {
        if (regexPattern.value && regexTestString.value) {
            const result = testRegex(regexPattern.value, regexFlags.value, regexTestString.value);
            outputHtml.innerHTML = result;
            outputHtml.classList.remove('hidden');
            outputText.classList.add('hidden');
        }
    };
    
    regexPattern.addEventListener('input', updateRegexPreview);
    regexFlags.addEventListener('input', updateRegexPreview);
    regexTestString.addEventListener('input', updateRegexPreview);
}

function testRegex(pattern, flags, testString) {
    try {
        const regex = new RegExp(pattern, flags);
        
        // Find all matches
        const matches = [];
        let match;
        while ((match = regex.exec(testString)) !== null) {
            // Avoid infinite loops
            if (match.index === regex.lastIndex) {
                regex.lastIndex++;
            }
            
            matches.push({
                match: match[0],
                index: match.index,
                groups: match.slice(1)
            });
            
            // Break if global flag is not set
            if (!flags.includes('g')) break;
        }
        
        // Prepare result HTML
        let resultHtml = `<div class="p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg mb-4">
            <h3 class="font-medium text-blue-800 dark:text-blue-300 mb-2">Regex Information</h3>
            <p class="text-gray-700 dark:text-gray-300">Pattern: <code class="bg-gray-100 dark:bg-gray-700 p-1 rounded">${escapeHtml(pattern)}</code></p>
            <p class="text-gray-700 dark:text-gray-300">Flags: <code class="bg-gray-100 dark:bg-gray-700 p-1 rounded">${escapeHtml(flags)}</code></p>
            <p class="text-gray-700 dark:text-gray-300">Matches: <span class="font-medium">${matches.length}</span></p>
        </div>`;
        
        if (matches.length > 0) {
            resultHtml += `<div class="overflow-x-auto">
                <table class="w-full text-sm text-left text-gray-500 dark:text-gray-400">
                    <thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
                        <tr>
                            <th scope="col" class="px-6 py-3">#</th>
                            <th scope="col" class="px-6 py-3">Match</th>
                            <th scope="col" class="px-6 py-3">Index</th>
                            <th scope="col" class="px-6 py-3">Groups</th>
                        </tr>
                    </thead>
                    <tbody>`;
            
            matches.forEach((match, index) => {
                resultHtml += `<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700">
                    <td class="px-6 py-4">${index + 1}</td>
                    <td class="px-6 py-4 font-medium text-gray-900 dark:text-white">${escapeHtml(match.match)}</td>
                    <td class="px-6 py-4">${match.index}</td>
                    <td class="px-6 py-4">${match.groups.length > 0 ? match.groups.map(g => `<span class="inline-block bg-gray-100 dark:bg-gray-700 px-2 py-1 rounded mr-1">${escapeHtml(g)}</span>`).join('') : '<span class="text-gray-400">No groups</span>'}</td>
                </tr>`;
            });
            
            resultHtml += `</tbody></table></div>`;
            
            // Highlighted text
            resultHtml += `<div class="mt-4 p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
                <h3 class="font-medium text-gray-800 dark:text-gray-200 mb-2">Highlighted Matches</h3>
                <div class="bg-white dark:bg-gray-700 p-3 rounded border dark:border-gray-600 whitespace-pre-wrap">`;
            
            // Highlight matches in the text
            let lastIndex = 0;
            let highlightedText = '';
            
            // Sort matches by index
            const sortedMatches = [...matches].sort((a, b) => a.index - b.index);
            
            sortedMatches.forEach(match => {
                // Add text before match
                highlightedText += escapeHtml(testString.slice(lastIndex, match.index));
                
                // Add highlighted match
                highlightedText += `<span class="bg-yellow-200 dark:bg-yellow-700">${escapeHtml(match.match)}</span>`;
                
                // Update last index
                lastIndex = match.index + match.match.length;
            });
            
            // Add remaining text
            highlightedText += escapeHtml(testString.slice(lastIndex));
            
            resultHtml += highlightedText + '</div></div>';
        } else {
            resultHtml += `<div class="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
                <p class="text-gray-700 dark:text-gray-300">No matches found.</p>
            </div>`;
        }
        
        return resultHtml;
    } catch (error) {
        return `<div class="p-4 bg-red-50 dark:bg-red-900/20 rounded-lg">
            <h3 class="font-medium text-red-800 dark:text-red-300 mb-2">Error</h3>
            <p class="text-gray-700 dark:text-gray-300">${error.message}</p>
        </div>`;
    }
}

// Initialize Diff Checker functionality
function initializeDiffChecker() {
    const diffOriginalText = document.getElementById('diffOriginalText');
    const diffModifiedText = document.getElementById('diffModifiedText');
    const diffInlineBtn = document.getElementById('diffInlineBtn');
    const diffSideBySideBtn = document.getElementById('diffSideBySideBtn');
    
    if (!diffOriginalText || !diffModifiedText || !diffInlineBtn || !diffSideBySideBtn) return;
    
    // Calculate diff on button click
    diffInlineBtn.addEventListener('click', () => {
        const result = calculateDiff(diffOriginalText.value, diffModifiedText.value, 'inline');
        outputHtml.innerHTML = result;
        outputHtml.classList.remove('hidden');
        outputText.classList.add('hidden');
    });
    
    diffSideBySideBtn.addEventListener('click', () => {
        const result = calculateDiff(diffOriginalText.value, diffModifiedText.value, 'sideBySide');
        outputHtml.innerHTML = result;
        outputHtml.classList.remove('hidden');
        outputText.classList.add('hidden');
    });
}

function calculateDiff(originalText, modifiedText, viewType = 'inline') {
    // Simple diff algorithm (character by character)
    function simpleDiff(oldStr, newStr) {
        const result = [];
        let i = 0, j = 0;
        
        while (i < oldStr.length || j < newStr.length) {
            if (i < oldStr.length && j < newStr.length && oldStr[i] === newStr[j]) {
                result.push({ type: 'common', value: oldStr[i] });
                i++;
                j++;
            } else {
                const oldRemaining = oldStr.substr(i);
                const newRemaining = newStr.substr(j);
                
                // Look for the next common character
                let nextCommonIndex = -1;
                for (let k = 0; k < oldRemaining.length; k++) {
                    const index = newRemaining.indexOf(oldRemaining[k]);
                    if (index !== -1) {
                        nextCommonIndex = index;
                        break;
                    }
                }
                
                if (nextCommonIndex === -1) {
                    // No more common characters, remove all remaining old and add all remaining new
                    while (i < oldStr.length) {
                        result.push({ type: 'removed', value: oldStr[i] });
                        i++;
                    }
                    while (j < newStr.length) {
                        result.push({ type: 'added', value: newStr[j] });
                        j++;
                    }
                } else {
                    // Remove characters until the next common one
                    while (i < oldStr.length && oldStr[i] !== newRemaining[nextCommonIndex]) {
                        result.push({ type: 'removed', value: oldStr[i] });
                        i++;
                    }
                    
                    // Add characters until the next common one
                    for (let k = 0; k < nextCommonIndex; k++) {
                        result.push({ type: 'added', value: newRemaining[k] });
                        j++;
                    }
                }
            }
        }
        
        // Group consecutive same-type characters
        const grouped = [];
        let current = { type: result[0]?.type, value: '' };
        
        for (const char of result) {
            if (char.type === current.type) {
                current.value += char.value;
            } else {
                if (current.value) grouped.push({ ...current });
                current = { type: char.type, value: char.value };
            }
        }
        
        if (current.value) grouped.push(current);
        
        return grouped;
    }
    
    // Process line by line
    const oldLines = originalText.split('\n');
    const newLines = modifiedText.split('\n');
    
    // Generate HTML based on view type
    if (viewType === 'inline') {
        let html = `<div class="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
            <h3 class="font-medium text-gray-800 dark:text-gray-200 mb-2">Inline Diff</h3>
            <div class="bg-white dark:bg-gray-700 p-3 rounded border dark:border-gray-600">`;
        
        for (let i = 0; i < Math.max(oldLines.length, newLines.length); i++) {
            const oldLine = i < oldLines.length ? oldLines[i] : '';
            const newLine = i < newLines.length ? newLines[i] : '';
            
            if (oldLine === newLine) {
                html += `<div class="diff-line">${escapeHtml(oldLine)}</div>`;
            } else {
                const diff = simpleDiff(oldLine, newLine);
                html += '<div class="diff-line">';
                
                for (const part of diff) {
                    if (part.type === 'common') {
                        html += escapeHtml(part.value);
                    } else if (part.type === 'removed') {
                        html += `<span class="bg-red-100 dark:bg-red-900/50 line-through">${escapeHtml(part.value)}</span>`;
                    } else if (part.type === 'added') {
                        html += `<span class="bg-green-100 dark:bg-green-900/50">${escapeHtml(part.value)}</span>`;
                    }
                }
                
                html += '</div>';
            }
        }
        
        html += '</div></div>';
        return html;
    } else {
        // Side by side view
        let html = `<div class="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
            <h3 class="font-medium text-gray-800 dark:text-gray-200 mb-2">Side by Side Diff</h3>
            <div class="grid grid-cols-2 gap-4">
                <div class="bg-white dark:bg-gray-700 p-3 rounded border dark:border-gray-600">
                    <h4 class="text-sm font-medium mb-2 text-gray-500 dark:text-gray-400">Original</h4>`;
        
        // Original text
        for (let i = 0; i < oldLines.length; i++) {
            const line = oldLines[i];
            if (i < newLines.length && line === newLines[i]) {
                html += `<div class="diff-line">${escapeHtml(line)}</div>`;
            } else {
                html += `<div class="diff-line bg-red-100 dark:bg-red-900/30">${escapeHtml(line)}</div>`;
            }
        }
        
        html += '</div><div class="bg-white dark:bg-gray-700 p-3 rounded border dark:border-gray-600">';
        html += '<h4 class="text-sm font-medium mb-2 text-gray-500 dark:text-gray-400">Modified</h4>';
        
        // Modified text
        for (let i = 0; i < newLines.length; i++) {
            const line = newLines[i];
            if (i < oldLines.length && line === oldLines[i]) {
                html += `<div class="diff-line">${escapeHtml(line)}</div>`;
            } else {
                html += `<div class="diff-line bg-green-100 dark:bg-green-900/30">${escapeHtml(line)}</div>`;
            }
        }
        
        html += '</div></div></div>';
        return html;
    }
}

// Helper function to escape HTML
function escapeHtml(unsafe) {
    return unsafe
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
}

// Recent functions functionality
function initializeRecentFunctions() {
    // Load from local storage
    loadRecentFunctions();
}

function addToRecentFunctions(functionName) {
    // Get existing recent functions
    const recentFunctions = JSON.parse(localStorage.getItem('recentFunctions') || '[]');
    
    // Remove if already exists
    const index = recentFunctions.indexOf(functionName);
    if (index > -1) {
        recentFunctions.splice(index, 1);
    }
    
    // Add to beginning
    recentFunctions.unshift(functionName);
    
    // Limit to 5 recent functions
    if (recentFunctions.length > 5) {
        recentFunctions.pop();
    }
    
    // Save to local storage
    localStorage.setItem('recentFunctions', JSON.stringify(recentFunctions));
    
    // Update display
    updateRecentFunctionsDisplay(recentFunctions);
}

function loadRecentFunctions() {
    const recentFunctions = JSON.parse(localStorage.getItem('recentFunctions') || '[]');
    updateRecentFunctionsDisplay(recentFunctions);
}

function updateRecentFunctionsDisplay(functions) {
    if (!recentFunctionsList) return;
    
    if (functions.length === 0) {
        recentFunctionsList.innerHTML = '<li class="italic text-gray-500 dark:text-gray-400 text-sm">No recent functions</li>';
        return;
    }
    
    recentFunctionsList.innerHTML = '';
    functions.forEach(func => {
        const li = document.createElement('li');
        li.innerHTML = `<a href="#" class="recent-function hover:text-blue-600 transition-colors duration-300" data-function="${func}">${formatFunctionName(func)}</a>`;
        recentFunctionsList.appendChild(li);
    });
    
    // Add event listeners
    document.querySelectorAll('.recent-function').forEach(link => {
        link.addEventListener('click', (e) => {
            e.preventDefault();
            const functionName = link.getAttribute('data-function');
            
            // Set the tool selector value
            toolSelector.value = functionName;
            
            // Trigger change event to update UI
            const event = new Event('change');
            toolSelector.dispatchEvent(event);
        });
    });
}

// Favorites functionality
function initializeFavorites() {
    // Load from local storage
    loadFavorites();
    
    // Update favorite button state for current tool
    if (currentFunction) {
        updateFavoriteButtonState(currentFunction);
    }
}

function loadFavorites() {
    const favorites = JSON.parse(localStorage.getItem('favorites') || '[]');
    updateFavoritesDisplay(favorites);
}

function updateFavoritesDisplay(favorites) {
    if (!favoritesList) return;
    
    if (favorites.length === 0) {
        favoritesList.innerHTML = '<li class="italic text-gray-500 dark:text-gray-400 text-sm">No favorites yet</li>';
        return;
    }
    
    favoritesList.innerHTML = '';
    favorites.forEach(func => {
        const li = document.createElement('li');
        li.className = 'flex items-center justify-between';
        li.innerHTML = `
            <a href="#" class="favorite-function hover:text-blue-600 transition-colors duration-300" data-function="${func}">${formatFunctionName(func)}</a>
            <button class="remove-favorite text-gray-400 hover:text-red-500" data-function="${func}">
                <i class="fas fa-times"></i>
            </button>
        `;
        favoritesList.appendChild(li);
    });
    
    // Add event listeners
    document.querySelectorAll('.favorite-function').forEach(link => {
        link.addEventListener('click', (e) => {
            e.preventDefault();
            const functionName = link.getAttribute('data-function');
            
            // Set the tool selector value
            toolSelector.value = functionName;
            
            // Trigger change event to update UI
            const event = new Event('change');
            toolSelector.dispatchEvent(event);
        });
    });
    
    document.querySelectorAll('.remove-favorite').forEach(btn => {
        btn.addEventListener('click', (e) => {
            e.preventDefault();
            const functionName = btn.getAttribute('data-function');
            toggleFavorite(functionName);
        });
    });
}

function updateFavoriteButtonState(functionName) {
    if (!favoriteBtn) return;
    
    const favorites = JSON.parse(localStorage.getItem('favorites') || '[]');
    const isFavorite = favorites.includes(functionName);
    
    if (isFavorite) {
        favoriteBtn.innerHTML = '<i class="fas fa-star text-yellow-500"></i>';
        favoriteBtn.title = 'Remove from Favorites';
    } else {
        favoriteBtn.innerHTML = '<i class="far fa-star"></i>';
        favoriteBtn.title = 'Add to Favorites';
    }
    
    // Update data attribute
    favoriteBtn.setAttribute('data-function', functionName);
}

function toggleFavorite(functionNameParam) {
    // Get function name from parameter or button
    const functionName = typeof functionNameParam === 'string' 
        ? functionNameParam 
        : (favoriteBtn ? favoriteBtn.getAttribute('data-function') : currentFunction);
    
    if (!functionName) return;
    
    const favorites = JSON.parse(localStorage.getItem('favorites') || '[]');
    const index = favorites.indexOf(functionName);
    
    if (index > -1) {
        // Remove from favorites
        favorites.splice(index, 1);
        showToast(`Removed ${formatFunctionName(functionName)} from favorites`);
    } else {
        // Add to favorites
        favorites.push(functionName);
        showToast(`Added ${formatFunctionName(functionName)} to favorites`);
    }
    
    // Save to local storage
    localStorage.setItem('favorites', JSON.stringify(favorites));
    
    // Update displays
    updateFavoritesDisplay(favorites);
    updateFavoriteButtonState(functionName);
}

function formatFunctionName(name) {
    return name
        .split('-')
        .map(word => word.charAt(0).toUpperCase() + word.slice(1))
        .join(' ');
}

// Initialize character counter
function initializeCharCount() {
    if (inputText) {
        inputText.addEventListener('input', updateCharCount);
    }
    
    if (outputText) {
        outputText.addEventListener('input', updateCharCount);
    }
    
    // Initial update
    updateCharCount();
}

function updateCharCount() {
    if (inputCharCount && inputText) {
        inputCharCount.textContent = inputText.value.length;
    }
    
    if (outputCharCount && outputText) {
        outputCharCount.textContent = outputText.value.length;
    }
}

// Tool information update
function updateToolInfo(functionName, mode = null) {
    if (!toolInfo) return;
    
    const isDecoding = mode === 'decode' || (modeSwitch && modeSwitch.checked);
    
    // Clear previous content
    toolInfo.innerHTML = '';
    
    // Create info content based on function
    switch (functionName) {
        case 'md5':
            toolInfo.innerHTML = `
                <h4 class="font-semibold mb-2">MD5 (Message Digest Algorithm 5)</h4>
                <p class="mb-3">MD5 is a widely used cryptographic hash function that produces a 128-bit (16-byte) hash value. However, it is no longer considered secure for cryptographic purposes due to vulnerabilities.</p>
                <div class="bg-yellow-50 dark:bg-yellow-900/20 p-3 rounded-lg">
                    <p class="text-yellow-800 dark:text-yellow-200 font-medium">?? Warning: MD5 is not collision-resistant and should not be used for security-critical applications.</p>
                </div>
            `;
            break;
        case 'sha256':
            toolInfo.innerHTML = `
                <h4 class="font-semibold mb-2">SHA-256 (Secure Hash Algorithm 256-bit)</h4>
                <p class="mb-3">SHA-256 is a cryptographic hash function that generates a 256-bit (32-byte) hash value. It's part of the SHA-2 family designed by the NSA and is widely used in security applications and protocols.</p>
                <p>Use cases include:</p>
                <ul class="list-disc ml-5 mb-3">
                    <li>Digital signatures</li>
                    <li>SSL certificate validation</li>
                    <li>Password storage (with proper salting)</li>
                    <li>Data integrity verification</li>
                </ul>
            `;
            break;
        case 'base64':
            const actionText = isDecoding ? 'decode' : 'encode';
            toolInfo.innerHTML = `
                <h4 class="font-semibold mb-2">Base64 ${isDecoding ? 'Decoding' : 'Encoding'}</h4>
                <p class="mb-3">Base64 is a binary-to-text encoding scheme that represents binary data in an ASCII string format by translating it into a radix-64 representation.</p>
                <p>Toggle the switch to ${isDecoding ? 'encode' : 'decode'} instead.</p>
                <div class="bg-blue-50 dark:bg-blue-900/20 p-3 rounded-lg mt-3">
                    <p class="text-blue-800 dark:text-blue-200 font-medium">?? Note: Base64 is not encryption. It's an encoding format that can be easily reversed.</p>
                </div>
            `;
            break;
        case 'aes':
            toolInfo.innerHTML = `
                <h4 class="font-semibold mb-2">AES (Advanced Encryption Standard) ${isDecoding ? 'Decryption' : 'Encryption'}</h4>
                <p class="mb-3">AES is a symmetric encryption algorithm widely adopted as a standard by governments and organizations around the world. It encrypts data in blocks of 128 bits using cryptographic keys of 128, 192, or 256 bits.</p>
                <p class="mb-3">This implementation uses AES-256 with the key you provide to ${isDecoding ? 'decrypt' : 'encrypt'} your data.</p>
                <div class="bg-blue-50 dark:bg-blue-900/20 p-3 rounded-lg">
                    <p class="text-blue-800 dark:text-blue-200 font-medium">?? Your encryption key should be strong and kept secure. Anyone with the key can decrypt your data.</p>
                </div>
            `;
            break;
        case 'hmac':
            toolInfo.innerHTML = `
                <h4 class="font-semibold mb-2">HMAC (Hash-based Message Authentication Code)</h4>
                <p class="mb-3">HMAC is a specific type of message authentication code (MAC) involving a cryptographic hash function and a secret cryptographic key. It provides a way to verify both the data integrity and authenticity of a message.</p>
                <p class="mb-3">This implementation uses HMAC-SHA256 by default, providing a 256-bit output.</p>
            `;
            break;
        case 'random-string':
            toolInfo.innerHTML = `
                <h4 class="font-semibold mb-2">Random String Generator</h4>
                <p class="mb-3">Generate random strings with customizable length and character sets. Useful for creating random identifiers, test data, or other random string needs.</p>
                <p>Choose the length and character set type, then click "Process" to generate.</p>
            `;
            break;
        case 'password-generator':
            toolInfo.innerHTML = `
                <h4 class="font-semibold mb-2">Secure Password Generator</h4>
                <p class="mb-3">Generate strong, secure passwords with customizable options. The generated passwords use cryptographically secure random values.</p>
                <p class="mb-3">Select the desired length and character types to include, then click "Process" to generate a password.</p>
                <div class="bg-green-50 dark:bg-green-900/20 p-3 rounded-lg">
                    <p class="text-green-800 dark:text-green-200 font-medium">?? Strong passwords should be at least 12 characters long and include a mix of uppercase, lowercase, numbers, and special characters.</p>
                </div>
            `;
            break;
        case 'qr-code':
            toolInfo.innerHTML = `
                <h4 class="font-semibold mb-2">QR Code Generator</h4>
                <p class="mb-3">Create QR codes for text, URLs, contact information, or any other data. QR codes can be scanned by smartphones and other devices with cameras.</p>
                <p class="mb-3">Enter the data you want to encode, adjust the size and error correction level, then generate your QR code.</p>
                <div class="bg-blue-50 dark:bg-blue-900/20 p-3 rounded-lg">
                    <p class="text-blue-800 dark:text-blue-200 font-medium">?? Higher error correction levels make the QR code more resistant to damage but require more space.</p>
                </div>
            `;
            break;
        case 'diff-checker':
            toolInfo.innerHTML = `
                <h4 class="font-semibold mb-2">Text Diff Checker</h4>
                <p class="mb-3">Compare two texts and highlight the differences between them. Useful for comparing code versions, documents, or any text that has changed.</p>
                <p class="mb-3">Enter the original and modified text, then choose between inline or side-by-side view.</p>
            `;
            break;
        case 'regex-tester':
            toolInfo.innerHTML = `
                <h4 class="font-semibold mb-2">Regular Expression Tester</h4>
                <p class="mb-3">Test and debug regular expressions with real-time highlighting of matches. Includes detailed information about each match, including groups and positions.</p>
                <p class="mb-3">Enter your regex pattern, flags, and test string to see the results.</p>
                <div class="bg-blue-50 dark:bg-blue-900/20 p-3 rounded-lg">
                    <p class="text-blue-800 dark:text-blue-200 font-medium">?? Common flags: g (global), i (case-insensitive), m (multiline), s (dotall), u (unicode)</p>
                </div>
            `;
            break;
        default:
            toolInfo.innerHTML = `
                <p class="text-gray-600 dark:text-gray-300">Select a cryptographic function from the dropdown or sidebar to get started. Input your text and click "Process" to see the results.</p>
            `;
    }
}

// Update related tools based on current function
function updateRelatedTools(functionName) {
    if (!relatedTools) return;
    
    // Define related tools mapping
    const relatedToolsMap = {
        'md5': ['sha1', 'sha256', 'hash-compare'],
        'sha1': ['md5', 'sha256', 'hash-compare'],
        'sha256': ['md5', 'sha512', 'hash-compare'],
        'sha512': ['sha256', 'sha3', 'hash-compare'],
        'base64': ['url', 'hex', 'binary'],
        'url': ['base64', 'html', 'hex'],
        'hex': ['base64', 'binary', 'url'],
        'binary': ['hex', 'base64', 'url'],
        'aes': ['des', 'tripledes', 'rabbit'],
        'des': ['aes', 'tripledes', 'rabbit'],
        'tripledes': ['aes', 'des', 'rabbit'],
        'password-generator': ['random-string', 'uuid', 'hmac'],
        'random-string': ['password-generator', 'uuid', 'base64'],
        'qr-code': ['base64', 'url', 'json'],
        'diff-checker': ['regex-tester', 'json', 'file-checksum'],
        'regex-tester': ['diff-checker', 'url', 'html']
    };
    
    // Default related tools if not in map
    const defaultRelated = ['md5', 'base64', 'sha256'];
    
    // Get related tools for current function
    const related = relatedToolsMap[functionName] || defaultRelated;
    
    // Generate HTML for related tools
    relatedTools.innerHTML = '';
    
    related.forEach(tool => {
        const div = document.createElement('div');
        div.className = 'p-4 border rounded-lg shadow-sm bg-gray-50 dark:bg-gray-700 hover:shadow-md transition-shadow duration-300 zoom-on-hover cursor-pointer';
        div.setAttribute('data-function', tool);
        
        // Get icon for tool
        let icon = 'fas fa-tools';
        if (tool.includes('hash')) icon = 'fas fa-hashtag';
        else if (tool.includes('base64') || tool.includes('url') || tool.includes('hex') || tool.includes('binary')) icon = 'fas fa-exchange-alt';
        else if (tool.includes('aes') || tool.includes('des') || tool.includes('crypt')) icon = 'fas fa-key';
        else if (tool.includes('password')) icon = 'fas fa-shield-alt';
        else if (tool.includes('random') || tool.includes('uuid')) icon = 'fas fa-dice';
        else if (tool.includes('qr')) icon = 'fas fa-qrcode';
        else if (tool.includes('diff')) icon = 'fas fa-code-branch';
        else if (tool.includes('regex')) icon = 'fas fa-search';
        else if (tool.includes('file')) icon = 'fas fa-file';
        
        div.innerHTML = `
            <div class="flex items-center mb-2">
                <i class="${icon} text-blue-600 dark:text-blue-400 mr-3"></i>
                <h4 class="font-medium text-gray-800 dark:text-white">${formatFunctionName(tool)}</h4>
            </div>
            <p class="text-sm text-gray-600 dark:text-gray-300">${getToolDescription(tool)}</p>
        `;
        
        relatedTools.appendChild(div);
        
        // Add click event
        div.addEventListener('click', () => {
            toolSelector.value = tool;
            const event = new Event('change');
            toolSelector.dispatchEvent(event);
        });
    });
}

function getToolDescription(tool) {
    switch (tool) {
        case 'md5': return 'Generate MD5 hash from text input';
        case 'sha1': return 'Generate SHA-1 hash from text input';
        case 'sha256': return 'Generate SHA-256 hash from text input';
        case 'sha512': return 'Generate SHA-512 hash from text input';
        case 'base64': return 'Convert text to/from Base64 encoding';
        case 'url': return 'Encode/decode URL components';
        case 'hex': return 'Convert text to/from hexadecimal';
        case 'binary': return 'Convert text to/from binary';
        case 'aes': return 'Encrypt/decrypt data using AES algorithm';
        case 'des': return 'Encrypt/decrypt data using DES algorithm';
        case 'tripledes': return 'Encrypt/decrypt data using Triple DES';
        case 'rabbit': return 'Encrypt/decrypt data using Rabbit cipher';
        case 'password-generator': return 'Generate secure random passwords';
        case 'random-string': return 'Generate random strings with custom options';
        case 'uuid': return 'Generate random UUIDs (v4)';
        case 'hash-compare': return 'Compare hash values of different inputs';
        case 'qr-code': return 'Generate QR codes from text or URLs';
        case 'diff-checker': return 'Compare and highlight differences between texts';
        case 'regex-tester': return 'Test and debug regular expressions';
        case 'file-checksum': return 'Calculate file hash checksums (MD5, SHA-256, etc.)';
        case 'json': return 'Format, validate, and transform JSON data';
        case 'html': return 'Encode/decode HTML entities';
        default: return 'Process text with this cryptographic tool';
    }
}

// Usage statistics functionality
function initializeStats() {
    // Load stats from local storage
    const stats = JSON.parse(localStorage.getItem('usageStats') || '{}');
    
    // Display stats if we have data
    if (Object.keys(stats).length > 0) {
        displayStats(stats);
    }
}

function addToUsageStats(functionName) {
    // Get existing stats
    const stats = JSON.parse(localStorage.getItem('usageStats') || '{}');
    
    // Update stats for this function
    if (!stats[functionName]) {
        stats[functionName] = {
            count: 0,
            lastUsed: null
        };
    }
    
    stats[functionName].count++;
    stats[functionName].lastUsed = new Date().toISOString();
    
    // Save to local storage
    localStorage.setItem('usageStats', JSON.stringify(stats));
    
    // Update display
    displayStats(stats);
}

function displayStats(stats) {
    // Update chart if it exists
    if (usageStatsChart) {
        // Convert stats to arrays for chart
        const labels = [];
        const data = [];
        
        // Sort by usage count (descending)
        const sortedFunctions = Object.entries(stats)
            .sort((a, b) => b[1].count - a[1].count)
            .slice(0, 10); // Only show top 10
        
        sortedFunctions.forEach(([func, stat]) => {
            labels.push(formatFunctionName(func));
            data.push(stat.count);
        });
        
        // Determine colors based on dark mode
        const isDark = document.documentElement.classList.contains('dark');
        const textColor = isDark ? '#e2e8f0' : '#4a5568';
        const gridColor = isDark ? '#374151' : '#e2e8f0';
        const barColor = isDark ? 'rgba(59, 130, 246, 0.8)' : 'rgba(59, 130, 246, 0.6)';
        const hoverColor = isDark ? 'rgba(96, 165, 250, 0.9)' : 'rgba(59, 130, 246, 0.8)';
        
        // Create or update chart
        if (chartInstance) {
            // Update existing chart
            chartInstance.data.labels = labels;
            chartInstance.data.datasets[0].data = data;
            chartInstance.update();
        } else {
            // Create new chart
            chartInstance = new Chart(usageStatsChart, {
                type: 'bar',
                data: {
                    labels: labels,
                    datasets: [{
                        label: 'Usage Count',
                        data: data,
                        backgroundColor: barColor,
                        hoverBackgroundColor: hoverColor,
                        borderWidth: 0,
                        borderRadius: 4,
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            display: false,
                        },
                        tooltip: {
                            callbacks: {
                                label: function(context) {
                                    return `Used ${context.raw} times`;
                                }
                            }
                        }
                    },
                    scales: {
                        x: {
                            grid: {
                                display: false,
                                color: gridColor
                            },
                            ticks: {
                                color: textColor
                            }
                        },
                        y: {
                            beginAtZero: true,
                            grid: {
                                color: gridColor
                            },
                            ticks: {
                                precision: 0,
                                color: textColor
                            }
                        }
                    }
                }
            });
        }
        
        // Update table view
        if (statsTableBody) {
            statsTableBody.innerHTML = '';
            
            sortedFunctions.forEach(([func, stat]) => {
                const tr = document.createElement('tr');
                tr.className = 'bg-white border-b dark:bg-gray-800 dark:border-gray-700';
                
                const lastUsedDate = stat.lastUsed 
                    ? new Date(stat.lastUsed).toLocaleString() 
                    : 'Never';
                
                tr.innerHTML = `
                    <td class="px-6 py-4 font-medium text-gray-900 dark:text-white">${formatFunctionName(func)}</td>
                    <td class="px-6 py-4">${stat.count}</td>
                    <td class="px-6 py-4">${lastUsedDate}</td>
                `;
                
                statsTableBody.appendChild(tr);
            });
        }
    }
}

// File drop zone functionality
function initializeFileDropZone() {
    const fileInput = document.getElementById('file-input');
    
    if (!fileDropZone || !fileInput) return;
    
    // File input change
    fileInput.addEventListener('change', (e) => {
        handleFileSelect(e);
    });
    
    // Drag and drop handlers
    fileDropZone.addEventListener('dragover', (e) => {
        e.preventDefault();
        e.stopPropagation();
        fileDropZone.classList.add('border-blue-500', 'bg-blue-50', 'dark:bg-blue-900/20');
    });
    
    fileDropZone.addEventListener('dragleave', (e) => {
        e.preventDefault();
        e.stopPropagation();
        fileDropZone.classList.remove('border-blue-500', 'bg-blue-50', 'dark:bg-blue-900/20');
    });
    
    fileDropZone.addEventListener('drop', (e) => {
        e.preventDefault();
        e.stopPropagation();
        fileDropZone.classList.remove('border-blue-500', 'bg-blue-50', 'dark:bg-blue-900/20');
        
        if (e.dataTransfer.files.length) {
            handleFileSelect({ target: { files: e.dataTransfer.files } });
        }
    });
}

function handleFileSelect(e) {
    const file = e.target.files[0];
    if (!file) return;
    
    // Store file in drop zone
    fileDropZone.files = e.target.files;
    
    // Show file info
    inputText.value = `File: ${file.name} (${formatFileSize(file.size)})`;
    updateCharCount();
    
    // Process file based on current function
    if (toolSelector.value === 'file-checksum') {
        calculateFileChecksum(file);
    }
}

// Live preview functionality
function initializeLivePreview() {
    let debounceTimeout;
    
    inputText.addEventListener('input', () => {
        // Clear any existing timeout
        clearTimeout(debounceTimeout);
        
        // Set a new timeout to process after user stops typing
        debounceTimeout = setTimeout(() => {
            const selectedFunction = toolSelector.value;
            
            // Only process automatically for simple functions
            const autoProcessFunctions = [
                'md5', 'sha1', 'sha256', 'sha512', 'base64', 'url', 'hex', 'binary'
            ];
            
            if (autoProcessFunctions.includes(selectedFunction)) {
                processCurrentFunction();
            }
        }, 500);
    });
}

// Search functionality
function initializeSearch() {
    if (!toolSearch) return;
    
    toolSearch.addEventListener('input', () => {
        const searchTerm = toolSearch.value.toLowerCase();
        
        // Filter sidebar links
        document.querySelectorAll('#sidebar .tool-link').forEach(link => {
            const toolName = link.textContent.toLowerCase();
            const li = link.closest('li');
            
            if (toolName.includes(searchTerm)) {
                li.classList.remove('hidden');
            } else {
                li.classList.add('hidden');
            }
        });
        
        // Show/hide section headers based on visible items
        document.querySelectorAll('#sidebar h3').forEach(header => {
            const nextUl = header.nextElementSibling;
            if (nextUl && nextUl.tagName === 'UL') {
                const hasVisibleItems = Array.from(nextUl.querySelectorAll('li')).some(li => !li.classList.contains('hidden'));
                
                if (hasVisibleItems || searchTerm === '') {
                    header.classList.remove('hidden');
                } else {
                    header.classList.add('hidden');
                }
            }
        });
    });
}

// URL parameters for direct tool access
function updateUrlWithTool(functionName) {
    const url = new URL(window.location);
    url.searchParams.set('tool', functionName);
    window.history.replaceState({}, '', url);
}

function checkUrlParameters() {
    const urlParams = new URLSearchParams(window.location.search);
    const tool = urlParams.get('tool');
    
    if (tool) {
        // Check if tool exists in options
        const optionExists = Array.from(toolSelector.options).some(option => option.value === tool);
        
        if (optionExists) {
            // Set the tool selector
            toolSelector.value = tool;
            
            // Trigger change event
            const event = new Event('change');
            toolSelector.dispatchEvent(event);
        }
    }
}

// All results functionality
function addToAllResults(functionName, input, result) {
    // Show the section if hidden
    allResultsSection.classList.remove('hidden');
    
    // Create a unique ID for this result
    const resultId = `result-${Date.now()}`;
    
    // Create new result item
    const resultItem = document.createElement('div');
    resultItem.className = 'result-item bg-gray-50 dark:bg-gray-700 p-4 rounded-lg';
    resultItem.setAttribute('data-function', functionName);
    resultItem.setAttribute('id', resultId);
    
    // Truncate input for display
    const displayInput = input.length > 50 ? input.substring(0, 47) + '...' : input;
    
    // Truncate result for display
    const displayResult = result.length > 100 ? result.substring(0, 97) + '...' : result;
    
    resultItem.innerHTML = `
        <div class="flex justify-between items-center mb-2">
            <h4 class="font-semibold dark:text-white flex items-center">
                ${formatFunctionName(functionName)}
                <span class="ml-2 text-xs text-gray-500 dark:text-gray-400">${new Date().toLocaleTimeString()}</span>
            </h4>
            <div class="flex gap-2">
                <button class="expand-result-btn text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400" title="Expand/Collapse" data-expanded="false">
                    <i class="fas fa-chevron-down"></i>
                </button>
                <button class="copy-result-btn text-gray-500 hover:text-blue-600 dark:text-gray-400 dark:hover:text-blue-400" title="Copy Result">
                    <i class="fas fa-copy"></i>
                </button>
                <button class="remove-result-btn text-gray-500 hover:text-red-600 dark:text-gray-400 dark:hover:text-red-400" title="Remove Result">
                    <i class="fas fa-times"></i>
                </button>
            </div>
        </div>
        <div class="result-summary">
            <div class="grid grid-cols-1 sm:grid-cols-2 gap-2 text-sm">
                <div class="text-gray-600 dark:text-gray-400 break-all">
                    <span class="font-medium">Input:</span> ${escapeHtml(displayInput)}
                </div>
                <div class="text-gray-700 dark:text-gray-300 break-all">
                    <span class="font-medium">Result:</span> ${escapeHtml(displayResult)}
                </div>
            </div>
        </div>
        <div class="result-details mt-3 hidden">
            <div class="grid grid-cols-1 gap-3">
                <div>
                    <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Input:</label>
                    <div class="bg-white dark:bg-gray-800 p-2 rounded border dark:border-gray-600 break-all">
                        ${escapeHtml(input)}
                    </div>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Result:</label>
                    <div class="bg-white dark:bg-gray-800 p-2 rounded border dark:border-gray-600 break-all">
                        ${escapeHtml(result)}
                    </div>
                </div>
            </div>
        </div>
    `;
    
    // Add to container (at the top)
    allResultsContainer.insertBefore(resultItem, allResultsContainer.firstChild);
    
    // Add event listeners
    resultItem.querySelector('.copy-result-btn').addEventListener('click', () => {
        copyToClipboard(result);
        showToast(`${formatFunctionName(functionName)} result copied to clipboard!`);
    });
    
    resultItem.querySelector('.remove-result-btn').addEventListener('click', () => {
        resultItem.remove();
        
        // Hide section if no results left
        if (allResultsContainer.children.length === 0) {
            allResultsSection.classList.add('hidden');
        }
    });
    
    resultItem.querySelector('.expand-result-btn').addEventListener('click', (e) => {
        const btn = e.currentTarget;
        const isExpanded = btn.getAttribute('data-expanded') === 'true';
        const details = resultItem.querySelector('.result-details');
        
        if (isExpanded) {
            // Collapse
            details.classList.add('hidden');
            btn.setAttribute('data-expanded', 'false');
            btn.querySelector('i').classList.remove('fa-chevron-up');
            btn.querySelector('i').classList.add('fa-chevron-down');
        } else {
            // Expand
            details.classList.remove('hidden');
            btn.setAttribute('data-expanded', 'true');
            btn.querySelector('i').classList.remove('fa-chevron-down');
            btn.querySelector('i').classList.add('fa-chevron-up');
        }
    });
    
    // Limit to 10 results
    if (allResultsContainer.children.length > 10) {
        allResultsContainer.removeChild(allResultsContainer.lastChild);
    }
}

// Toast notification system
function showToast(message, type = 'success') {
    const toastContainer = document.getElementById('toast-container');
    
    // Create toast element
    const toast = document.createElement('div');
    toast.className = `flex items-center p-4 mb-4 rounded-lg shadow-lg text-sm ${
        type === 'success' ? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' :
        type === 'error' ? 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200' :
        type === 'warning' ? 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200' :
        'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200'
    } opacity-0 transform translate-y-2 transition-all duration-300`;
    
    // Set icon based on type
    const icon = 
        type === 'success' ? 'fas fa-check-circle' :
        type === 'error' ? 'fas fa-exclamation-circle' :
        type === 'warning' ? 'fas fa-exclamation-triangle' :
        'fas fa-info-circle';
    
    toast.innerHTML = `
        <div class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 rounded-lg ${
            type === 'success' ? 'bg-green-200 text-green-600 dark:bg-green-800 dark:text-green-200' :
            type === 'error' ? 'bg-red-200 text-red-600 dark:bg-red-800 dark:text-red-200' :
            type === 'warning' ? 'bg-yellow-200 text-yellow-600 dark:bg-yellow-800 dark:text-yellow-200' :
            'bg-blue-200 text-blue-600 dark:bg-blue-800 dark:text-blue-200'
        } mr-3">
            <i class="${icon}"></i>
        </div>
        <div class="ml-3 text-sm font-normal">${message}</div>
        <button type="button" class="ml-auto -mx-1.5 -my-1.5 rounded-lg p-1.5 inline-flex h-8 w-8 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none" data-dismiss-target="#toast-success" aria-label="Close">
            <i class="fas fa-times"></i>
        </button>
    `;
    
    // Add to container
    toastContainer.appendChild(toast);
    
    // Animate in
    setTimeout(() => {
        toast.classList.remove('opacity-0', 'translate-y-2');
    }, 10);
    
    // Close button
    const closeBtn = toast.querySelector('button');
    closeBtn.addEventListener('click', () => {
        closeToast(toast);
    });
    
    // Auto close after 5 seconds
    setTimeout(() => {
        closeToast(toast);
    }, 5000);
}

function closeToast(toast) {
    toast.classList.add('opacity-0', 'translate-y-2');
    setTimeout(() => {
        toast.remove();
    }, 300);
}

// Initialize keyboard shortcuts
function initializeKeyboardShortcuts() {
    document.addEventListener('keydown', (e) => {
        // Ctrl+Enter to process
        if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
            e.preventDefault();
            processCurrentFunction();
        }
        
        // Ctrl+/ to focus search
        if ((e.ctrlKey || e.metaKey) && e.key === '/') {
            e.preventDefault();
            if (toolSearch) {
                toolSearch.focus();
            }
        }
        
        // Esc to clear input
        if (e.key === 'Escape') {
            // Only clear if input is focused
            if (document.activeElement === inputText) {
                inputText.value = '';
                updateCharCount();
            }
        }
        
        // Shift+S to toggle sidebar
        if (e.shiftKey && e.key === 'S') {
            e.preventDefault();
            toggleSidebar();
        }
        
        // Shift+D to toggle dark mode
        if (e.shiftKey && e.key === 'D') {
            e.preventDefault();
            darkModeToggle.click();
        }
        
        // Alt+1 through Alt+5 for quick tools
        if (e.altKey && e.key >= '1' && e.key <= '5') {
            e.preventDefault();
            const index = parseInt(e.key) - 1;
            const quickButtons = document.querySelectorAll('.quick-tool-btn');
            if (index < quickButtons.length) {
                quickButtons[index].click();
            }
        }
    });
}
    </script>
</body>
</html>
How to use robots.txt parser
  1. 1
    Paste your input

    Enter the value at the top — domain, IP, URL, email, ASN, hash, whatever fits this tool. The smart input auto-detects type.

  2. 2
    Click "Inspect"

    host.tools issues real probes (DNS, HTTP, TCP, TLS, WHOIS where applicable) and renders the result in milliseconds.

  3. 3
    Open the API tab

    Every web tool has a sibling /api/v1/http/robots JSON endpoint with the same payload. One copy-as-curl click and you're scripting it.

Why this matters

Headers are how the modern web declares its security posture. Auditing them is the highest-ROI thing you can do this week.

API equivalent
/api/v1/http/robots?q=https%3A%2F%2Fcrypt.tools
curl -s '/api/v1/http/robots?q=https%3A%2F%2Fcrypt.tools'
Embed this tool
<iframe src="/http/robots?q={INPUT}&embed=1"
  width="100%" height="600" frameborder="0"></iframe>

Drop into any HTML page. The embed=1 flag hides nav and footer.

FAQ · robots.txt parser

Common questions

Is robots.txt parser free?
Yes — every tool is free on the web with a 200/hour rate limit per IP. The matching API endpoint /api/v1/http/robots is free up to 100 requests/hour, no key required.
Where does the data come from?
Real-time probes against authoritative sources (DNS root, RIRs, registries, the target server itself), plus partner data feeds from hostinfo.com (GeoIP/ASN) and hostcheck.com (reputation).
How fresh are the results?
Live by default. Cached for 5 minutes to make repeat queries instant; pass ?nocache=1 for a forced refresh.
Can I run this from the command line?
Yes — every tool ships with a copy-as-curl. There's also an official CLI: host.tools http robots YOUR_INPUT.
Can I monitor results over time?
Pro tier lets you schedule any tool to run every 1/5/15/60 min and alert on diff. See monitors.
host.tools Pro

Run robots.txt parser on a schedule. Get pinged when it changes.

Pro gets you bulk lookups, monitors, webhook alerts, history, exports and 10,000 API calls/day. $19/mo.

  • Schedule any tool — every 1, 5, 15, 60 min
  • Diff against last run, alert on change
  • Webhook + email + Slack + PagerDuty + OpsGenie
  • Bulk CSV upload, 1,000 inputs per job
  • Export results as CSV / NDJSON / Excel
  • 90-day history, comparison view