Modern USACO

Bringing USACO's UI into the 21st century

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name         Modern USACO
// @namespace    http://tampermonkey.net/
// @version      2026.1.1
// @description  Bringing USACO's UI into the 21st century
// @author       Earth1283
// @license      AGPLv3
// @match        http://www.usaco.org/*
// @match        https://www.usaco.org/*
// @match        http://usaco.org/*
// @match        https://usaco.org/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';
    // warning terrible css hacks ahead
    const welcomeCss = `
        /* Welcome Popup */
        #usaco-welcome-backdrop {
            display: flex;
            position: fixed;
            top: 0; left: 0; right: 0; bottom: 0;
            background: rgba(0, 0, 0, 0.6);
            backdrop-filter: blur(8px);
            z-index: 9999999;
            align-items: center;
            justify-content: center;
            opacity: 0;
            animation: fadeIn 0.3s forwards;
            font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
        }

        #usaco-welcome-modal {
            background: #1c1c1e;
            border: 1px solid rgba(255, 255, 255, 0.15);
            border-radius: 16px;
            padding: 32px;
            max-width: 500px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
            transform: scale(0.9);
            animation: popupScale 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
            color: #f2f2f7;
            display: flex !important;
            flex-direction: column !important;
            text-align: left !important;
            align-items: stretch !important;
            justify-content: flex-start !important;
        }

        #usaco-welcome-modal * {
            box-sizing: border-box !important;
            float: none !important;
        }

        #usaco-welcome-modal h2 {
            margin-top: 0;
            color: #ffffff;
            font-size: 1.8rem;
            border: none !important;
            padding-left: 0 !important;
            display: block !important;
            width: 100% !important;
            text-align: left !important;
            margin-bottom: 12px !important;
        }

        #usaco-welcome-modal p, #usaco-welcome-modal ul {
            font-size: 1.05rem;
            line-height: 1.6;
            margin-bottom: 20px;
            display: block !important;
            text-align: left !important;
        }

        #usaco-welcome-modal ul {
            padding-left: 20px;
        }

        #usaco-welcome-modal li {
            margin-bottom: 8px;
            display: list-item !important;
            text-align: left !important;
        }

        #btn-welcome-dismiss {
            background: #0a84ff !important;
            color: #ffffff !important;
            border: none !important;
            padding: 10px 20px !important;
            border-radius: 20px !important;
            font-family: inherit !important;
            font-weight: 600 !important;
            cursor: pointer !important;
            transition: all 0.25s ease !important;
            font-size: 0.95rem !important;
            display: inline-block !important;
            width: auto !important;
            margin: 0 !important;
            box-sizing: border-box !important;
            appearance: none !important;
            -webkit-appearance: none !important;
            line-height: normal !important;
            text-align: center !important;
            text-decoration: none !important;
            vertical-align: middle !important;
            outline: none !important;
            box-shadow: none !important;
        }
        #btn-welcome-dismiss:hover {
            background: #007aff !important;
            transform: scale(0.97) !important;
            opacity: 0.9 !important;
        }

        @keyframes popupScale {
            to { transform: scale(1); opacity: 1; }
        }
        @keyframes fadeIn {
            to { opacity: 1; }
        }
    `;
    const welcomeStyleSheet = document.createElement("style");
    welcomeStyleSheet.textContent = welcomeCss;
    document.head.appendChild(welcomeStyleSheet);
    // more terrible css hacks
    const css = `
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');

        :root {
            --bg-primary: #000000;
            --bg-secondary: #1c1c1e;
            --bg-panel: rgba(28, 28, 30, 0.75);
            --accent: #0a84ff;
            --highlight: #0a84ff;
            --text-main: #f2f2f7;
            --text-heading: #ffffff;
            --text-muted: #8e8e93;
            --font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
            --font-mono: "SF Mono", "Menlo", "Monaco", "Consolas", "JetBrains Mono", monospace;
            --border-subtle: rgba(255, 255, 255, 0.15);
            --shadow-elevation: 0 10px 40px rgba(0, 0, 0, 0.5);
            --transition-speed: 0.25s;
        }

        body {
            background: var(--bg-primary) !important;
            background-attachment: fixed !important;
            color: var(--text-main) !important;
            font-family: var(--font-ui) !important;
            margin: 0 !important;
            padding: 0 !important;
            min-height: 100vh;
            -webkit-font-smoothing: antialiased;
        }

        /* Base Layout */
        .shadow1 {
            background: none !important;
            border: none !important;
            box-shadow: none !important;
            max-width: 1000px !important;
            margin: 0 auto !important;
            padding: 20px !important;
        }

        /* Core Document Wrapper */
        .content {
            background: var(--bg-panel) !important;
            backdrop-filter: blur(12px) !important;
            -webkit-backdrop-filter: blur(12px) !important;
            border: 1px solid var(--border-subtle) !important;
            border-radius: 16px !important;
            padding: 32px !important;
            box-shadow: var(--shadow-elevation) !important;
            display: flex !important;
            flex-direction: column !important;
            gap: 20px !important;
        }

        /* Navbar */
        .navbar {
            background: var(--bg-panel) !important;
            backdrop-filter: blur(12px) !important;
            border: 1px solid var(--border-subtle) !important;
            border-radius: 12px !important;
            padding: 10px 20px !important;
            margin-top: -10px !important;
        }
        .navbar ul {
            display: flex !important;
            gap: 15px !important;
            list-style: none !important;
            padding: 0 !important;
            margin: 0 !important;
            flex-wrap: wrap !important;
        }
        .navbar li {
            margin: 0 !important;
            display: inline-block !important; /* fallback */
        }
        .navbar a {
            color: var(--text-heading) !important;
            text-decoration: none !important;
            padding: 8px 16px !important;
            border-radius: 8px !important;
            font-weight: 500 !important;
            transition: all var(--transition-speed) ease !important;
            display: block !important;
        }
        .navbar a:hover {
            background: var(--accent) !important;
            transform: translateY(-2px) !important;
        }

        /* Typography */
        h1, h2, h3, h4, h5, h6 {
            color: var(--text-heading) !important;
            font-weight: 600 !important;
        }

        a {
            color: var(--highlight) !important;
            text-decoration: none !important;
            transition: opacity var(--transition-speed) ease !important;
        }
        a:hover {
            opacity: 0.8 !important;
            text-decoration: underline !important;
        }

        /* Panels (Cards within document) */
        @keyframes fadeInUp {
            from { opacity: 0; transform: translateY(15px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .panel {
            background: none !important;
            backdrop-filter: none !important;
            -webkit-backdrop-filter: none !important;
            border: none !important;
            border-bottom: 1px solid var(--border-subtle) !important;
            border-radius: 0 !important;
            padding: 24px 0 !important;
            box-shadow: none !important;
            color: var(--text-main) !important;
            margin-bottom: 0 !important;
            animation: fadeInUp 0.5s ease forwards !important;
        }
        .panel:last-child {
            border-bottom: none !important;
        }
        .panel:hover {
            transform: none !important;
            box-shadow: none !important;
        }
        .panel h2 {
            border-left: 4px solid var(--highlight) !important;
            padding-left: 12px !important;
            margin-top: 0 !important;
            margin-bottom: 16px !important;
            background: none !important;
            border-bottom: none !important;
            font-size: 1.5rem !important;
        }

        /* Command Palette */
        #usaco-cmd-palette-backdrop {
            display: none;
            position: fixed;
            top: 0; left: 0; right: 0; bottom: 0;
            background: rgba(0, 0, 0, 0.4);
            backdrop-filter: blur(4px);
            z-index: 999998;
            align-items: flex-start;
            justify-content: center;
            padding-top: 15vh;
        }

        #usaco-cmd-palette {
            width: 100%;
            max-width: 600px;
            background: var(--bg-secondary);
            border: 1px solid var(--border-subtle);
            border-radius: 12px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
            overflow: hidden;
            display: flex;
            flex-direction: column;
            z-index: 999999;
            animation: paletteScale 0.15s cubic-bezier(0.16, 1, 0.3, 1) forwards;
            opacity: 0;
            transform: scale(0.96);
        }

        @keyframes paletteScale {
            to { opacity: 1; transform: scale(1); }
        }

        #usaco-cmd-input-wrapper {
            display: flex;
            align-items: center;
            padding: 16px;
            border-bottom: 1px solid var(--border-subtle);
        }

        #usaco-cmd-input {
            width: 100%;
            background: transparent !important;
            border: none !important;
            color: var(--text-heading) !important;
            font-size: 1.2rem !important;
            font-family: var(--font-ui) !important;
            outline: none !important;
            padding: 0 !important;
            box-shadow: none !important;
        }

        #usaco-cmd-results {
            max-height: 400px;
            overflow-y: auto;
            padding: 8px;
        }

        .usaco-cmd-item {
            padding: 12px 16px;
            color: var(--text-main) !important;
            border-radius: 8px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: space-between;
            text-decoration: none !important;
        }

        .usaco-cmd-item:hover, .usaco-cmd-item.selected {
            background: #0a84ff !important;
            color: #ffffff !important;
            text-decoration: none !important;
            opacity: 1 !important;
        }

        .usaco-cmd-item-title {
            font-weight: 500;
        }

        .usaco-cmd-item-shortcut {
            font-size: 0.8rem;
            color: var(--text-muted);
            background: rgba(255,255,255,0.1);
            padding: 2px 6px;
            border-radius: 4px;
        }

        .usaco-cmd-item.selected .usaco-cmd-item-shortcut {
            color: rgba(255,255,255,0.8);
        }

        /* History Panels */
        .historypanel {
            display: flex !important;
            align-items: center !important;
            padding: 16px 24px !important;
        }
        .historypanel > div:first-child {
            margin-right: 20px !important;
            padding-right: 0 !important;
        }
        .historypanel h1 {
            background: var(--accent) !important;
            color: #fff !important;
            padding: 12px 20px !important;
            border-radius: 12px !important;
            margin: 0 !important;
            font-size: 1.7rem !important;
            display: inline-block !important;
        }
        .historypanel > div:nth-child(2) {
            flex-grow: 1 !important;
        }

        /* Headers with Medals */
        h2 > img[src*="medal"] {
            vertical-align: middle !important;
            margin-right: 12px !important;
            filter: drop-shadow(0 2px 4px rgba(0,0,0,0.5));
        }

        /* Problem Page Elements */
        #last-status {
            background: var(--bg-panel) !important;
            backdrop-filter: blur(12px) !important;
            border: 1px solid var(--border-subtle) !important;
            border-left: 6px solid var(--accent) !important;
            border-radius: 12px !important;
            color: var(--text-main) !important;
            box-shadow: var(--shadow-elevation) !important;
        }
        #last-status.status-working { border-left-color: #f39c12 !important; }
        #last-status.status-error { border-left-color: #e74c3c !important; }
        #last-status.status-done { border-left-color: #2ecc71 !important; }

        .problem-text, .problem-text * {
            background-color: transparent !important;
        }
        div[style*="background-color:#FFF"], div[style*="background-color: #FFF"], div[style*="background-color: rgb(255, 255, 255)"], div[style*="background: white"], div[style*="background:white"] {
            background-color: transparent !important;
        }

        .problem-text {
            line-height: 1.7 !important;
            font-size: 1.1rem !important;
            color: var(--text-main) !important;
            background: none !important;
        }
        .problem-text pre {
            background: #0d0d1a !important;
            color: #a0a0b0 !important;
            font-family: var(--font-mono) !important;
            padding: 16px !important;
            border-radius: 8px !important;
            border: 1px solid var(--border-subtle) !important;
            overflow-x: auto !important;
        }
        .problem-text pre.in, .problem-text pre.out {
            color: #d4d4d4 !important;
        }

        /* Submission Form / General Form Controls */
        .submission {
            background: var(--bg-panel) !important;
            padding: 24px !important;
            border-radius: 16px !important;
            border: 1px solid var(--border-subtle) !important;
        }
        .field2 {
            margin-bottom: 16px !important;
        }
        select, input[type="file"], input[type="text"], input[type="password"] {
            background: rgba(0,0,0,0.2) !important;
            color: var(--text-heading) !important;
            border: 1px solid var(--border-subtle) !important;
            padding: 8px 12px !important;
            border-radius: 8px !important;
            font-family: var(--font-ui) !important;
        }
        select:focus, input:focus {
            outline: none !important;
            border-color: var(--accent) !important;
            box-shadow: 0 0 0 2px rgba(15, 52, 96, 0.5) !important;
        }
        select option {
            background: var(--bg-primary) !important;
            color: var(--text-heading) !important;
        }

        /* Buttons */
        button, input[type="button"], input[type="submit"] {
            background: var(--accent) !important;
            color: #ffffff !important;
            border: none !important;
            padding: 10px 20px !important;
            border-radius: 20px !important;
            font-family: var(--font-ui) !important;
            font-weight: 600 !important;
            cursor: pointer !important;
            transition: all var(--transition-speed) ease !important;
            font-size: 0.95rem !important;
        }
        button:hover, input[type="button"]:hover, input[type="submit"]:hover {
            background: #007aff !important;
            transform: scale(0.97) !important;
            opacity: 0.9;
        }

        button.btn-toggle-active {
            background: var(--accent) !important;
            color: white !important;
            border: none !important;
        }
        button.btn-toggle-inactive {
            background: rgba(255,255,255,0.08) !important;
            color: var(--text-main) !important;
            border: 1px solid var(--border-subtle) !important;
        }

        /* Layout Tweaks for right/left floated containers */
        /* Using structural selectors to override inline float styles */
        div[style*="float:left"], div[style*="float:right"] {
            float: none !important;
            position: static !important;
            right: auto !important;
            left: auto !important;
            top: auto !important;
            width: 100% !important;
            margin-bottom: 20px !important;
        }

        /* Clearfix removal */
        br[style*="clear:both"] {
            display: none !important;
        }

        /* Main layout grid - overriding inline styles for a modern CSS grid layout instead of floats */
        .content > div[style*="width:550px"], .content > div[style*="width:300px"] {
             /* Handled by script DOM modification, or we just let panels stack beautifully for now */
        }
    `;
    function injectCSS(gradual) {
        const styleSheet = document.createElement("style");
        document.head.appendChild(styleSheet);

        function showFinalBalloon() {
            const balloon = document.createElement('div');
            balloon.innerHTML = `
                <div style="font-weight: 600; font-size: 1.1rem; margin-bottom: 4px;">Welcome to 2026.</div>
                <div style="font-size: 0.95rem; color: #a0a0b0;">This is USACO. Good software deserves good presentation.</div>
            `;
            balloon.style.cssText = `
                position: fixed;
                bottom: 32px;
                right: 32px;
                background: rgba(28, 28, 30, 0.9);
                backdrop-filter: blur(12px);
                border: 1px solid rgba(255, 255, 255, 0.15);
                color: white;
                padding: 16px 20px;
                border-radius: 12px;
                box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
                z-index: 9999999;
                font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
                transform: translateY(20px);
                opacity: 0;
                transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);
            `;
            document.body.appendChild(balloon);

            // Trigger animation
            requestAnimationFrame(() => {
                balloon.style.transform = 'translateY(0)';
                balloon.style.opacity = '1';
            });

            // Fade out after 5 seconds
            setTimeout(() => {
                balloon.style.opacity = '0';
                balloon.style.transform = 'translateY(10px)';
                setTimeout(() => balloon.remove(), 500);
            }, 5000);
        }

        function playTrashAnimation() {
            const container = document.createElement('div');
            container.style.cssText = `
                position: fixed;
                bottom: 120px;
                left: 50%;
                transform: translateX(-50%);
                z-index: 9999999;
                pointer-events: none;
                display: flex;
                flex-direction: column;
                align-items: center;
                font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, sans-serif;
            `;

            const logo = document.createElement('img');
            logo.src = 'https://upload.wikimedia.org/wikipedia/commons/0/04/ChatGPT_logo.svg';
            logo.style.cssText = `
                width: 50px;
                height: 50px;
                background: white;
                border-radius: 50%;
                padding: 4px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
                position: absolute;
                bottom: 80px;
                transition: all 0.8s cubic-bezier(0.5, -0.5, 0.5, 1.5);
            `;

            const trash = document.createElement('div');
            trash.innerHTML = '🗑️';
            trash.style.cssText = `
                font-size: 64px;
                position: absolute;
                bottom: 0;
                transition: transform 0.2s;
            `;

            const text = document.createElement('div');
            text.innerText = "USACO disallows cheating";
            text.style.cssText = `
                position: absolute;
                bottom: -30px;
                color: #ff453a;
                font-weight: bold;
                font-size: 15px;
                white-space: nowrap;
                opacity: 0;
                transition: opacity 0.5s;
                text-shadow: 0 2px 4px rgba(0,0,0,0.5);
                background: rgba(0,0,0,0.7);
                padding: 4px 12px;
                border-radius: 12px;
            `;

            container.appendChild(logo);
            container.appendChild(trash);
            container.appendChild(text);
            document.body.appendChild(container);

            // Animation sequence
            setTimeout(() => {
                // throw into trash
                logo.style.transform = 'translateY(60px) scale(0) rotate(360deg)';
                logo.style.opacity = '0';
            }, 100);

            setTimeout(() => {
                text.style.opacity = '1';
                trash.style.transform = 'scale(1.2)';
            }, 800);

            setTimeout(() => {
                trash.style.transform = 'scale(1)';
            }, 1000);

            // Cleanup
            setTimeout(() => {
                container.style.transition = 'opacity 0.5s';
                container.style.opacity = '0';
                setTimeout(() => container.remove(), 500);
            }, 4000);
        }

        if (gradual) {
            // Create Loading Bar Element
            const loadingBarContainer = document.createElement('div');
            loadingBarContainer.style.cssText = `
                position: fixed;
                bottom: 32px;
                left: 50%;
                transform: translateX(-50%);
                background: rgba(28, 28, 30, 0.9);
                backdrop-filter: blur(12px);
                border: 1px solid rgba(255, 255, 255, 0.15);
                color: white;
                padding: 16px 24px;
                border-radius: 24px;
                box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
                z-index: 9999999;
                font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
                display: flex;
                flex-direction: column;
                gap: 12px;
                width: 300px;
                transition: opacity 0.5s ease;
            `;

            const loadingText = document.createElement('div');
            loadingText.style.cssText = "font-size: 0.95rem; font-weight: 500; text-align: center;";
            loadingText.innerText = "Updating Web Design to 1993...";

            // Setup Easter Egg
            const easterEggContainer = document.createElement('div');
            easterEggContainer.style.cssText = `
                position: fixed;
                bottom: 150px;
                left: 50%;
                transform: translateX(-50%);
                z-index: 9999998;
                pointer-events: none;
                display: flex;
                flex-direction: column;
                align-items: center;
                font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, sans-serif;
                opacity: 0;
                transition: opacity 0.3s;
            `;

            const logo = document.createElement('img');
            logo.src = 'https://upload.wikimedia.org/wikipedia/commons/0/04/ChatGPT_logo.svg';
            logo.style.cssText = `
                width: 50px;
                height: 50px;
                background: white;
                border-radius: 50%;
                padding: 4px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.3);
                position: absolute;
                bottom: 80px;
                transition: transform 0.8s cubic-bezier(0.5, -0.5, 0.5, 1.5), opacity 0.8s;
            `;

            const trash = document.createElement('div');
            trash.innerHTML = '🗑️';
            trash.style.cssText = `
                font-size: 64px;
                position: absolute;
                bottom: 0;
                transition: transform 0.2s;
            `;

            const easterText = document.createElement('div');
            easterText.innerText = "USACO disallows cheating";
            easterText.style.cssText = `
                position: absolute;
                bottom: -30px;
                color: #ff453a;
                font-weight: bold;
                font-size: 15px;
                white-space: nowrap;
                opacity: 0;
                transition: opacity 0.5s;
                text-shadow: 0 2px 4px rgba(0,0,0,0.5);
                background: rgba(0,0,0,0.7);
                padding: 4px 12px;
                border-radius: 12px;
            `;

            const progressBarTrack = document.createElement('div');
            progressBarTrack.style.cssText = "width: 100%; height: 6px; background: rgba(255,255,255,0.1); border-radius: 3px; overflow: hidden;";

            const progressBarFill = document.createElement('div');
            progressBarFill.style.cssText = "height: 100%; width: 0%; background: #0a84ff; transition: width 0.1s linear;";

            progressBarTrack.appendChild(progressBarFill);
            loadingBarContainer.appendChild(loadingText);
            loadingBarContainer.appendChild(progressBarTrack);
            document.body.appendChild(loadingBarContainer);

            easterEggContainer.appendChild(logo);
            easterEggContainer.appendChild(trash);
            easterEggContainer.appendChild(easterText);

            // Render it invisibly in DOM to preload image
            document.body.appendChild(easterEggContainer);


            const lines = css.split('\n');
            const totalLines = lines.length;
            const delay = 6500 / Math.max(totalLines, 1);
            let i = 0;

            const startYear = 1993; // Using 1993 as requested
            const endYear = 2026;

            let easterState = 0;

            const interval = setInterval(() => {
                if (i >= lines.length) {
                    clearInterval(interval);
                    loadingBarContainer.style.opacity = '0';
                    setTimeout(() => loadingBarContainer.remove(), 500);

                    easterEggContainer.style.opacity = '0';
                    setTimeout(() => easterEggContainer.remove(), 500);

                    showFinalBalloon();
                    return;
                }
                styleSheet.textContent += lines[i] + '\n';

                const progressPercentage = (i / totalLines) * 100;
                const currentYear = Math.floor(startYear + ((endYear - startYear) * (i / totalLines)));

                // Drive Easter Egg by year progression
                if (currentYear === 2021 && easterState === 0) {
                    easterState = 1;
                    easterEggContainer.style.opacity = '1';
                }
                if (currentYear === 2022 && easterState === 1) {
                    easterState = 2;
                    logo.style.transform = 'translateY(60px) scale(0) rotate(360deg)';
                    logo.style.opacity = '0';
                }
                if (currentYear >= 2023 && easterState === 2) {
                    easterState = 3;
                    trash.style.transform = 'scale(1.2)';
                    easterText.style.opacity = '1';
                    setTimeout(() => trash.style.transform = 'scale(1)', 200);
                }

                progressBarFill.style.width = progressPercentage + '%';
                loadingText.innerText = 'Updating Web Design to ' + currentYear + '...';

                i++;
            }, delay);
        } else {
            styleSheet.textContent = css;
        }
    }

    // Additional DOM manipulation for layout
    function modernizeDom() {
        // Find the main split layout on landing page
        const leftCol = document.querySelector('div[style*="width:550px"]');
        const rightCol = document.querySelector('div[style*="width:300px"]');

        if (leftCol && rightCol) {
            // Create a grid container
            const grid = document.createElement('div');
            grid.style.display = 'grid';
            grid.style.gridTemplateColumns = '2fr 1fr';
            grid.style.gap = '20px';
            grid.style.width = '100%';

            // Insert grid
            leftCol.parentNode.insertBefore(grid, leftCol);
            grid.appendChild(leftCol);
            grid.appendChild(rightCol);

            // Strip out width, float, left, top from inline styles
            leftCol.style.cssText = "";
            rightCol.style.cssText = "";

            // Fix sponsor wrapper
            const sponsors = document.querySelector('.sponsors');
            if (sponsors) {
                sponsors.style.cssText = "";
                // Move out of grid if it's there
                grid.parentNode.insertBefore(sponsors, grid.nextSibling);
            }
        }

        // Remove text alignments that break design
        document.querySelectorAll('[align="center"], [align="left"], [align="right"]').forEach(el => el.removeAttribute('align'));
    }

    function initCommandPalette() {
        const backdrop = document.createElement('div');
        backdrop.id = 'usaco-cmd-palette-backdrop';

        backdrop.innerHTML = `
                    <div id = "usaco-cmd-palette">
                <div id="usaco-cmd-input-wrapper">
                    <svg style="width: 20px; height: 20px; color: var(--text-muted); margin-right: 12px;" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
                    <input type="text" id="usaco-cmd-input" placeholder="Search USACO Pages or jump to links..." autocomplete="off" spellcheck="false"/>
                </div>
                <div id="usaco-cmd-results"></div>
            </div >
                `;
        document.body.appendChild(backdrop);

        const input = document.getElementById('usaco-cmd-input');
        const resultsContainer = document.getElementById('usaco-cmd-results');

        // Collect all links on page
        const pageLinks = Array.from(document.querySelectorAll('a')).map(a => ({
            title: a.innerText.trim() || a.href,
            url: a.href,
            type: 'Page Link'
        })).filter(l => l.title.length > 0 && !l.url.startsWith('javascript:'));

        // Define global hardcoded quick links
        const globalLinks = [
            { title: "USACO Home", url: "https://usaco.org/", type: "Global" },
            { title: "Contests", url: "https://usaco.org/index.php?page=contests", type: "Global" },
            { title: "Training Pages", url: "https://train.usaco.org/", type: "Global" },
            { title: "Log Out", url: "https://usaco.org/index.php?page=logout", type: "Global" }
        ];

        const allItems = [...globalLinks, ...pageLinks];
        let selectedIndex = 0;
        let currentResults = [];

        function closePalette() {
            backdrop.style.display = 'none';
            input.value = '';
            input.blur();
        }

        function renderResults(query = "") {
            query = query.toLowerCase();
            currentResults = allItems.filter(item =>
                item.title.toLowerCase().includes(query) || item.url.toLowerCase().includes(query)
            );

            // Remove duplicates by URL roughly
            const seen = new Set();
            currentResults = currentResults.filter(item => {
                const duplicate = seen.has(item.url);
                seen.add(item.url);
                return !duplicate;
            }).slice(0, 10); // show top 10 max

            if (currentResults.length === 0) {
                resultsContainer.innerHTML = '<div style="padding: 16px; color: var(--text-muted); text-align: center;">No results found.</div>';
                return;
            }

            resultsContainer.innerHTML = currentResults.map((item, index) => `
                <a href="${item.url}" class="usaco-cmd-item ${index === selectedIndex ? 'selected' : ''}" data-index="${index}">
                    <span class="usaco-cmd-item-title">${item.title}</span>
                    <span class="usaco-cmd-item-shortcut">${item.type}</span>
                </a>
                `).join('');

            // Add click listeners to items
            document.querySelectorAll('.usaco-cmd-item').forEach(el => {
                el.addEventListener('mouseenter', (e) => {
                    selectedIndex = parseInt(e.currentTarget.getAttribute('data-index'));
                    renderResults(input.value);
                });
                el.addEventListener('click', closePalette);
            });
        }

        backdrop.addEventListener('click', (e) => {
            if (e.target === backdrop) closePalette();
        });

        document.addEventListener('keydown', (e) => {
            if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
                e.preventDefault();
                backdrop.style.display = backdrop.style.display === 'flex' ? 'none' : 'flex';
                if (backdrop.style.display === 'flex') {
                    input.focus();
                    selectedIndex = 0;
                    renderResults();
                }
            }

            if (backdrop.style.display === 'flex') {
                if (e.key === 'Escape') closePalette();
                if (e.key === 'ArrowDown') { e.preventDefault(); selectedIndex = Math.min(selectedIndex + 1, currentResults.length - 1); renderResults(input.value); }
                if (e.key === 'ArrowUp') { e.preventDefault(); selectedIndex = Math.max(selectedIndex - 1, 0); renderResults(input.value); }
                if (e.key === 'Enter' && currentResults[selectedIndex]) {
                    e.preventDefault();
                    window.location.href = currentResults[selectedIndex].url;
                    closePalette();
                }
            }
        });

        input.addEventListener('input', (e) => {
            selectedIndex = 0;
            renderResults(e.target.value);
        });
    }

    function initMonacoEditor() {
        const form = document.querySelector('form.submission');
        if (!form) return;

        const fileInput = form.querySelector('input[name="sourcefile"]');
        const langSelect = form.querySelector('select[name="language"]');
        if (!fileInput || !langSelect) return;

        // Create editor container
        const editorContainer = document.createElement('div');
        editorContainer.id = "monaco-editor-container";
        editorContainer.style.width = "100%";
        editorContainer.style.height = "500px";
        editorContainer.style.marginTop = "10px";
        editorContainer.style.marginBottom = "20px";
        editorContainer.style.borderRadius = "8px";
        editorContainer.style.overflow = "hidden";
        editorContainer.style.border = "1px solid var(--border-subtle)";

        // Add tab toggle
        const toggleWrapper = document.createElement('div');
        toggleWrapper.innerHTML = `
                < div style = "display: flex; gap: 10px; margin-top: 20px; margin-bottom: 10px;" >
                <button type="button" id="btn-use-editor" class="btn-toggle-active">Use Editor</button>
                <button type="button" id="btn-use-file" class="btn-toggle-inactive">Upload File</button>
            </div >
                `;

        const fileInputParent = fileInput.parentNode;
        fileInputParent.parentNode.insertBefore(toggleWrapper, fileInputParent);

        // Hide file input initially
        fileInputParent.style.display = 'none';

        // Insert editor container
        toggleWrapper.parentNode.insertBefore(editorContainer, toggleWrapper.nextSibling);

        let editor = null;
        let useEditor = true;

        const btnEditor = document.getElementById('btn-use-editor');
        const btnFile = document.getElementById('btn-use-file');

        btnEditor.addEventListener('click', (e) => {
            useEditor = true;
            btnEditor.className = "btn-toggle-active";
            btnFile.className = "btn-toggle-inactive";

            editorContainer.style.display = 'block';
            fileInputParent.style.display = 'none';
        });

        btnFile.addEventListener('click', (e) => {
            useEditor = false;
            btnFile.className = "btn-toggle-active";
            btnEditor.className = "btn-toggle-inactive";

            editorContainer.style.display = 'none';
            fileInputParent.style.display = 'block';
        });

        // Load Monaco
        const script = document.createElement('script');
        script.src = 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.46.0/min/vs/loader.min.js';
        script.onload = () => {
            window.require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.46.0/min/vs' } });
            window.require(['vs/editor/editor.main'], function () {
                monaco.editor.defineTheme('usacoDark', {
                    base: 'vs-dark',
                    inherit: true,
                    rules: [{ background: '1c1c1e' }],
                    colors: {
                        'editor.background': '#1c1c1e',
                        'editor.lineHighlightBackground': '#2c2c2e',
                    }
                });

                // Add basic snippets/suggestions for common USACO languages since Monaco in browser
                // doesn't have a backend Language Server to provide rich standard-library intellisense.
                monaco.languages.registerCompletionItemProvider('cpp', {
                    provideCompletionItems: function (model, position) {
                        return {
                            suggestions: [
                                {
                                    label: 'boilerplate',
                                    kind: monaco.languages.CompletionItemKind.Snippet,
                                    insertText: '#include <iostream>\n#include <vector>\n#include <algorithm>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    $0\n    return 0;\n}',
                                    insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
                                    documentation: 'USACO C++ Boilerplate'
                                },
                                { label: 'cout', kind: monaco.languages.CompletionItemKind.Snippet, insertText: 'cout << $1 << "\\n";' },
                                { label: 'cin', kind: monaco.languages.CompletionItemKind.Snippet, insertText: 'cin >> $1;' },
                                { label: 'fori', kind: monaco.languages.CompletionItemKind.Snippet, insertText: 'for(int i = 0; i < $1; i++) {\n    $2\n}' }
                            ]
                        };
                    }
                });

                monaco.languages.registerCompletionItemProvider('java', {
                    provideCompletionItems: function (model, position) {
                        return {
                            suggestions: [
                                {
                                    label: 'boilerplate',
                                    kind: monaco.languages.CompletionItemKind.Snippet,
                                    insertText: 'import java.util.*;\nimport java.io.*;\n\npublic class Solution {\n    public static void main(String[] args) throws IOException {\n        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));\n        $0\n    }\n}',
                                    insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
                                    documentation: 'USACO Java Boilerplate'
                                },
                                { label: 'sout', kind: monaco.languages.CompletionItemKind.Snippet, insertText: 'System.out.println($1);' }
                            ]
                        };
                    }
                });

                monaco.languages.registerCompletionItemProvider('python', {
                    provideCompletionItems: function (model, position) {
                        return {
                            suggestions: [
                                {
                                    label: 'boilerplate',
                                    kind: monaco.languages.CompletionItemKind.Snippet,
                                    insertText: 'import sys\n\ndef main():\n    input = sys.stdin.read\n    data = input().split()\n    $0\n\nif __name__ == "__main__":\n    main()',
                                    insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
                                    documentation: 'USACO Python Boilerplate'
                                }
                            ]
                        };
                    }
                });

                function getMonacoLanguage(usacoLangStr) {
                    usacoLangStr = usacoLangStr.toLowerCase();
                    if (usacoLangStr.includes('c++')) return 'cpp';
                    if (usacoLangStr.includes('java')) return 'java';
                    if (usacoLangStr.includes('python')) return 'python';
                    if (usacoLangStr === 'c') return 'c';
                    return 'plaintext';
                }

                editor = monaco.editor.create(editorContainer, {
                    value: '// Select your language and type "boilerplate" to get started\\n',
                    language: getMonacoLanguage(langSelect.options[langSelect.selectedIndex].text),
                    theme: 'usacoDark',
                    automaticLayout: true,
                    fontSize: 14,
                    fontFamily: "var(--font-mono)",
                    minimap: { enabled: false },
                    scrollBeyondLastLine: false,
                    quickSuggestions: true,
                    suggestOnTriggerCharacters: true
                });

                langSelect.addEventListener('change', () => {
                    const newLang = getMonacoLanguage(langSelect.options[langSelect.selectedIndex].text);
                    monaco.editor.setModelLanguage(editor.getModel(), newLang);
                });
            });
        };
        document.head.appendChild(script);

        // Intercept form submission
        form.addEventListener('submit', (e) => {
            if (useEditor && editor) {
                const code = editor.getValue();
                const langText = langSelect.options[langSelect.selectedIndex].text.toLowerCase();
                let ext = ".txt";
                if (langText.includes("c++")) ext = ".cpp";
                else if (langText.includes("java")) ext = ".java";
                else if (langText.includes("python")) ext = ".py";
                else if (langText === "c") ext = ".c";

                const file = new File([code], "solution" + ext, { type: "text/plain" });

                // Polyfill for setting files using DataTransfer
                const dt = new DataTransfer();
                dt.items.add(file);
                fileInput.files = dt.files;
            }
        });
    }

    function initWelcomePopup() {
        if (localStorage.getItem('modernUsacoWelcomeShown')) {
            injectCSS(false);
            initAll();
            return;
        }

        const backdrop = document.createElement('div');
        backdrop.id = 'usaco-welcome-backdrop';

        backdrop.innerHTML = `
            <div id="usaco-welcome-modal">
                <h2>Welcome to Modern USACO! 🎉</h2>
                <p>It looks like this is your first time using the Modern USACO userscript. Here are a few key features to enhance your experience:</p>
                <ul>
                    <li><strong>Apple-inspired UI:</strong> A clean, fast, dark-mode continuous document layout.</li>
                    <li><strong>CMD+K / CTRL+K:</strong> A global command palette to quickly search and navigate to any page.</li>
                    <li><strong>Monaco Editor:</strong> A built-in code editor on problem pages with competitive programming boilerplate snippets.</li>
                </ul>
                <p style="font-size: 0.9rem; color: #8e8e93; background: rgba(255,255,255,0.05); padding: 12px; border-radius: 8px;">
                    🛡️ <strong>Privacy & Security:</strong> This script operates entirely locally on your machine. It does not collect data, has absolutely no telemetry, and will never compromise your setup or identity. It is completely open-source!
                </p>
                <div style="text-align: right !important; margin-top: 24px !important; display: block !important; width: 100% !important;">
                    <button id="btn-welcome-dismiss">Got it, let's go!</button>
                </div>
            </div>
        `;
        document.body.appendChild(backdrop);

        document.getElementById('btn-welcome-dismiss').addEventListener('click', () => {
            backdrop.style.opacity = '0';
            setTimeout(() => backdrop.remove(), 300);
            localStorage.setItem('modernUsacoWelcomeShown', 'true');
            injectCSS(true);
            initAll();
        });
    }

    // Run DOM manipulation when document is ready
    const initAll = () => { modernizeDom(); initCommandPalette(); initMonacoEditor(); };

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initWelcomePopup);
    } else {
        initWelcomePopup();
    }

})();