Einsatz Endzeit-Anzeige

Zeigt bei Verbands-Einsätzen das früheste Zufahrts-Ende als verschiebbares, Panel mit nebeneinander angeordneten Buttons und Farbschema.

// ==UserScript==
// @name         Einsatz Endzeit-Anzeige
// @namespace    HendrikStaufenbiel
// @version      1.3.4
// @description  Zeigt bei Verbands-Einsätzen das früheste Zufahrts-Ende als verschiebbares, Panel mit nebeneinander angeordneten Buttons und Farbschema. 
// @author       Hendrik
// @license      MIT 
// @match        https://www.leitstellenspiel.de/
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    if (window.hasRunEinsatzEndzeitScriptVerband) return;
    window.hasRunEinsatzEndzeitScriptVerband = true;

    const STORAGE_KEY = 'chaos_ignored_einsaetze_verband';
    const CHAOS_MODE_KEY = 'chaos_mode_activated';
    const OWN_MISSIONS_KEY = 'show_own_missions_over_10k';
    const POSITION_KEY = 'einsatz_endzeit_panel_position';

    const ignoredEinsaetze = new Set(JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]'));
    let chaosMode = JSON.parse(localStorage.getItem(CHAOS_MODE_KEY) || 'false');
    let showOwnMissions = JSON.parse(localStorage.getItem(OWN_MISSIONS_KEY) || 'false');
    const eingeklappteMissionen = new Set();

    let einsatzMitFruehestemEnde = null;
    let creditDisplay = null;

    function saveIgnored() {
        localStorage.setItem(STORAGE_KEY, JSON.stringify([...ignoredEinsaetze]));
    }

    function saveChaosMode() {
        localStorage.setItem(CHAOS_MODE_KEY, JSON.stringify(chaosMode));
    }

    function saveOwnMissionsSetting() {
        localStorage.setItem(OWN_MISSIONS_KEY, JSON.stringify(showOwnMissions));
    }

    function savePanelPosition(left, top) {
        localStorage.setItem(POSITION_KEY, JSON.stringify({ left, top }));
    }

    function loadPanelPosition() {
        const pos = localStorage.getItem(POSITION_KEY);
        if (pos) {
            try {
                return JSON.parse(pos);
            } catch {
                return null;
            }
        }
        return null;
    }

    function formatTime(timestamp) {
        const date = new Date(timestamp * 1000);
        const hours = date.getHours().toString().padStart(2, '0');
        const minutes = date.getMinutes().toString().padStart(2, '0');
        return `${hours}:${minutes}`;
    }

    function calculateOffset(avgCredits) {
        return chaosMode ? (avgCredits <= 4999 ? 1800 : 5400) : (avgCredits <= 4999 ? 3600 : 10800);
    }

    function verarbeiteEinsatzliste(container, isOwn = false) {
        if (!container) return { fruehesteZeit: Infinity, eintrag: null, gesamt: 0 };

        let fruehesteZeit = Infinity;
        let fruehesterEintrag = null;
        let gesamtCredits = 0;

        container.querySelectorAll('.missionSideBarEntry').forEach(entry => {
            const missionId = entry.getAttribute('mission_id');
            if (!missionId || ignoredEinsaetze.has(missionId)) return;

            const sortableRaw = entry.getAttribute('data-sortable-by');
            if (!sortableRaw) return;

            try {
                const sortableData = JSON.parse(sortableRaw.replace(/&quot;/g, '"'));
                const age = sortableData.age;
                const avgCredits = sortableData.average_credits;
                gesamtCredits += avgCredits;

                if (isOwn) {
                    if (avgCredits <= 10000 && !eingeklappteMissionen.has(missionId)) {
                        eingeklappteMissionen.add(missionId);
                        const collapseBtn = entry.querySelector('button.lssmv4-extendedCallList_collapsable-missions_btn');
                        if (collapseBtn) collapseBtn.click();
                    }
                    if (!showOwnMissions || avgCredits <= 10000) return;
                }

                const offset = calculateOffset(avgCredits);
                const endTimestamp = age + offset;

                if (endTimestamp < fruehesteZeit) {
                    fruehesteZeit = endTimestamp;
                    fruehesterEintrag = entry;
                }

                if (!entry.querySelector('.endzeit-anzeige')) {
                    const zeitAnzeige = document.createElement('div');
                    zeitAnzeige.className = 'endzeit-anzeige';
                    Object.assign(zeitAnzeige.style, {
                        marginLeft: '8px',
                        fontSize: 'smaller',
                        color: 'white',
                        backgroundColor: '#ff0000',
                        padding: '2px 6px',
                        borderRadius: '4px',
                        display: 'inline-block',
                        boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
                    });
                    zeitAnzeige.textContent = `Ende: ${formatTime(endTimestamp)}`;

                    zeitAnzeige.addEventListener('click', () => {
                        zeitAnzeige.style.display = 'none';
                        ignoredEinsaetze.add(missionId);
                        saveIgnored();
                        addEndTimes();
                    });

                    entry.querySelector('.panel-heading')?.appendChild(zeitAnzeige);
                }
            } catch (err) {
                console.error('Fehler beim Parsen:', err);
            }
        });

        return { fruehesteZeit, eintrag: fruehesterEintrag, gesamt: gesamtCredits };
    }

    function addEndTimes() {
        const allianceContainer = document.querySelector('#mission_list_alliance');
        const ownContainer = document.querySelector('#mission_list');

        const allianceResult = verarbeiteEinsatzliste(allianceContainer);
        const ownResult = showOwnMissions ? verarbeiteEinsatzliste(ownContainer, true) : { fruehesteZeit: Infinity, eintrag: null, gesamt: 0 };

        const result = allianceResult.fruehesteZeit < ownResult.fruehesteZeit ? allianceResult : ownResult;

        if (result.fruehesteZeit < Infinity) {
            einsatzMitFruehestemEnde = result.eintrag;
            updatePanel(formatTime(result.fruehesteZeit), allianceResult.gesamt);
        }
    }

    function createDraggablePanel() {
        const panel = document.createElement('div');
        panel.id = 'endzeit-panel';

        const pos = loadPanelPosition();
        const left = pos?.left ?? 100;
        const top = pos?.top ?? 100;

        Object.assign(panel.style, {
            position: 'absolute',
            top: `${top}px`,
            left: `${left}px`,
            zIndex: '9999',
            background: '#1e1e1e',
            color: '#fff',
            padding: '4px 6px',
            borderRadius: '6px',
            border: '2px solid #555',
            boxShadow: '0 0 6px rgba(0,0,0,0.5)',
            cursor: 'move',
            userSelect: 'none',
            display: 'flex',
            alignItems: 'center',
            gap: '6px',
            whiteSpace: 'nowrap',
            fontSize: '11px',
            fontWeight: '600'
        });

        panel.innerHTML = `
            <button id="btnNextEnd" title="Zur nächsten Endzeit springen">Nächste Endzeit</button>
            <button id="btnResetIgnored" title="Ignorierte Einsätze zurücksetzen">↺</button>
            <button id="btnToggleChaos" title="Chaostage an/aus">Chaostage: ${chaosMode ? 'AN' : 'AUS'}</button>
            <button id="btnOwnMissions" title="Eigene Einsätze > 15.000 Cr ein/aus">Eigene >10k: ${showOwnMissions ? 'AN' : 'AUS'}</button>
            <div id="creditDisplay" title="Gesamt-Credits" style="
                background:#2980b9;
                width:16px;
                height:16px;
                border-radius:50%;
                display:flex;
                justify-content:center;
                align-items:center;
                font-weight:bold;
                font-size:11px;
                cursor: default;
                user-select:none;
            ">ⓘ</div>
        `;

        document.body.appendChild(panel);

        // Styles für Buttons
        const btnNextEnd = document.getElementById('btnNextEnd');
        Object.assign(btnNextEnd.style, {
            backgroundColor: '#888888',
            color: '#ff0000',
            border: 'none',
            padding: '3px 8px',
            borderRadius: '5px',
            cursor: 'pointer',
            fontWeight: 'bold',
            boxShadow: '0 0 4px rgba(255,0,0,0.6)',
            fontSize: '11px'
        });

        const btnResetIgnored = document.getElementById('btnResetIgnored');
        Object.assign(btnResetIgnored.style, {
            backgroundColor: '#666',
            color: '#fff',
            border: 'none',
            padding: '3px 7px',
            borderRadius: '50%',
            cursor: 'pointer',
            fontWeight: 'bold',
            fontSize: '14px',
            lineHeight: '1',
            boxShadow: '0 0 4px rgba(255,255,255,0.4)',
            userSelect: 'none'
        });

        const btnToggleChaos = document.getElementById('btnToggleChaos');
        const updateChaosButton = () => {
            if (chaosMode) {
                btnToggleChaos.style.backgroundColor = '#e74c3c'; // rot
                btnToggleChaos.style.color = '#fff';
                btnToggleChaos.style.boxShadow = '0 0 6px rgba(231,76,60,0.8)';
            } else {
                btnToggleChaos.style.backgroundColor = '#27ae60'; // grün
                btnToggleChaos.style.color = '#fff';
                btnToggleChaos.style.boxShadow = '0 0 6px rgba(39,174,96,0.8)';
            }
        };
        updateChaosButton();
        btnToggleChaos.style.border = 'none';
        btnToggleChaos.style.padding = '3px 8px';
        btnToggleChaos.style.borderRadius = '5px';
        btnToggleChaos.style.cursor = 'pointer';
        btnToggleChaos.style.fontWeight = 'bold';
        btnToggleChaos.style.fontSize = '11px';

        const btnOwnMissions = document.getElementById('btnOwnMissions');
        Object.assign(btnOwnMissions.style, {
            backgroundColor: '#444',
            color: '#fff',
            border: 'none',
            padding: '3px 8px',
            borderRadius: '5px',
            cursor: 'pointer',
            fontWeight: 'bold',
            boxShadow: '0 0 4px rgba(0,0,0,0.5)',
            fontSize: '11px'
        });

        // Drag-Funktionalität
        let isDragging = false;
        let offsetX, offsetY;
        panel.addEventListener('mousedown', (e) => {
            if (e.target.tagName === 'BUTTON' || e.target.id === 'creditDisplay') return; // Buttons nicht draggable machen
            isDragging = true;
            offsetX = e.clientX - panel.getBoundingClientRect().left;
            offsetY = e.clientY - panel.getBoundingClientRect().top;
            e.preventDefault();
        });
        document.addEventListener('mousemove', (e) => {
            if (isDragging) {
                const newLeft = e.clientX - offsetX;
                const newTop = e.clientY - offsetY;
                panel.style.left = `${newLeft}px`;
                panel.style.top = `${newTop}px`;
            }
        });
        document.addEventListener('mouseup', () => {
            if (isDragging) {
                isDragging = false;
                // Position speichern
                const rect = panel.getBoundingClientRect();
                savePanelPosition(rect.left, rect.top);
            }
        });

        // Button Events
        btnNextEnd.addEventListener('click', () => {
            if (einsatzMitFruehestemEnde) {
                einsatzMitFruehestemEnde.scrollIntoView({ behavior: 'smooth', block: 'center' });
                const endzeitAnzeige = einsatzMitFruehestemEnde.querySelector('.endzeit-anzeige');
                if (endzeitAnzeige) {
                    endzeitAnzeige.classList.add('blink-animation');
                    setTimeout(() => endzeitAnzeige.classList.remove('blink-animation'), 5000);
                }
            }
        });

        btnResetIgnored.addEventListener('click', () => {
            ignoredEinsaetze.clear();
            saveIgnored();
            addEndTimes();
        });

        btnToggleChaos.addEventListener('click', () => {
            chaosMode = !chaosMode;
            btnToggleChaos.textContent = `Chaostage: ${chaosMode ? 'AN' : 'AUS'}`;
            updateChaosButton();
            saveChaosMode();
            addEndTimes();
        });

        btnOwnMissions.addEventListener('click', () => {
            showOwnMissions = !showOwnMissions;
            btnOwnMissions.textContent = `Eigene >10k: ${showOwnMissions ? 'AN' : 'AUS'}`;
            saveOwnMissionsSetting();
            addEndTimes();
        });

        creditDisplay = document.getElementById('creditDisplay');
    }

    function updatePanel(zeit, credits) {
        document.getElementById('btnNextEnd').textContent = `Nächste Endzeit: ${zeit}`;
        if (creditDisplay) {
            creditDisplay.title = `Gesamt-Credits: ${credits.toLocaleString()} Cr`;
        }
    }

    const style = document.createElement('style');
    style.textContent = `
        @keyframes blink {
            0% { background-color: yellow; }
            50% { background-color: red; }
            100% { background-color: yellow; }
        }
        .blink-animation {
            animation: blink 1s linear infinite;
        }
    `;
    document.head.appendChild(style);

    createDraggablePanel();
    setInterval(addEndTimes, 2000);
})();

// ==UserScript==
// @name         Einsatz Endzeit-Anzeige
// @namespace    HendrikStaufenbiel
// @version      1.3.4
// @description  Zeigt bei Verbands-Einsätzen das früheste Zufahrts-Ende als verschiebbares, sehr kompaktes Panel mit nebeneinander angeordneten Buttons und Farbschema. Speichert Panelposition im localStorage.
// @author       Hendrik
// @match        https://www.leitstellenspiel.de/
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    if (window.hasRunEinsatzEndzeitScriptVerband) return;
    window.hasRunEinsatzEndzeitScriptVerband = true;

    const STORAGE_KEY = 'chaos_ignored_einsaetze_verband';
    const CHAOS_MODE_KEY = 'chaos_mode_activated';
    const OWN_MISSIONS_KEY = 'show_own_missions_over_10k';
    const POSITION_KEY = 'einsatz_endzeit_panel_position';

    const ignoredEinsaetze = new Set(JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]'));
    let chaosMode = JSON.parse(localStorage.getItem(CHAOS_MODE_KEY) || 'false');
    let showOwnMissions = JSON.parse(localStorage.getItem(OWN_MISSIONS_KEY) || 'false');
    const eingeklappteMissionen = new Set();

    let einsatzMitFruehestemEnde = null;
    let creditDisplay = null;

    function saveIgnored() {
        localStorage.setItem(STORAGE_KEY, JSON.stringify([...ignoredEinsaetze]));
    }

    function saveChaosMode() {
        localStorage.setItem(CHAOS_MODE_KEY, JSON.stringify(chaosMode));
    }

    function saveOwnMissionsSetting() {
        localStorage.setItem(OWN_MISSIONS_KEY, JSON.stringify(showOwnMissions));
    }

    function savePanelPosition(left, top) {
        localStorage.setItem(POSITION_KEY, JSON.stringify({ left, top }));
    }

    function loadPanelPosition() {
        const pos = localStorage.getItem(POSITION_KEY);
        if (pos) {
            try {
                return JSON.parse(pos);
            } catch {
                return null;
            }
        }
        return null;
    }

    function formatTime(timestamp) {
        const date = new Date(timestamp * 1000);
        const hours = date.getHours().toString().padStart(2, '0');
        const minutes = date.getMinutes().toString().padStart(2, '0');
        return `${hours}:${minutes}`;
    }

    function calculateOffset(avgCredits) {
        return chaosMode ? (avgCredits <= 4999 ? 1800 : 5400) : (avgCredits <= 4999 ? 3600 : 10800);
    }

    function verarbeiteEinsatzliste(container, isOwn = false) {
        if (!container) return { fruehesteZeit: Infinity, eintrag: null, gesamt: 0 };

        let fruehesteZeit = Infinity;
        let fruehesterEintrag = null;
        let gesamtCredits = 0;

        container.querySelectorAll('.missionSideBarEntry').forEach(entry => {
            const missionId = entry.getAttribute('mission_id');
            if (!missionId || ignoredEinsaetze.has(missionId)) return;

            const sortableRaw = entry.getAttribute('data-sortable-by');
            if (!sortableRaw) return;

            try {
                const sortableData = JSON.parse(sortableRaw.replace(/&quot;/g, '"'));
                const age = sortableData.age;
                const avgCredits = sortableData.average_credits;
                gesamtCredits += avgCredits;

                if (isOwn) {
                    if (avgCredits <= 10000 && !eingeklappteMissionen.has(missionId)) {
                        eingeklappteMissionen.add(missionId);
                        const collapseBtn = entry.querySelector('button.lssmv4-extendedCallList_collapsable-missions_btn');
                        if (collapseBtn) collapseBtn.click();
                    }
                    if (!showOwnMissions || avgCredits <= 10000) return;
                }

                const offset = calculateOffset(avgCredits);
                const endTimestamp = age + offset;

                if (endTimestamp < fruehesteZeit) {
                    fruehesteZeit = endTimestamp;
                    fruehesterEintrag = entry;
                }

                if (!entry.querySelector('.endzeit-anzeige')) {
                    const zeitAnzeige = document.createElement('div');
                    zeitAnzeige.className = 'endzeit-anzeige';
                    Object.assign(zeitAnzeige.style, {
                        marginLeft: '8px',
                        fontSize: 'smaller',
                        color: 'white',
                        backgroundColor: '#ff0000',
                        padding: '2px 6px',
                        borderRadius: '4px',
                        display: 'inline-block',
                        boxShadow: '0 0 4px rgba(0, 0, 0, 0.3)'
                    });
                    zeitAnzeige.textContent = `Ende: ${formatTime(endTimestamp)}`;

                    zeitAnzeige.addEventListener('click', () => {
                        zeitAnzeige.style.display = 'none';
                        ignoredEinsaetze.add(missionId);
                        saveIgnored();
                        addEndTimes();
                    });

                    entry.querySelector('.panel-heading')?.appendChild(zeitAnzeige);
                }
            } catch (err) {
                console.error('Fehler beim Parsen:', err);
            }
        });

        return { fruehesteZeit, eintrag: fruehesterEintrag, gesamt: gesamtCredits };
    }

    function addEndTimes() {
        const allianceContainer = document.querySelector('#mission_list_alliance');
        const ownContainer = document.querySelector('#mission_list');

        const allianceResult = verarbeiteEinsatzliste(allianceContainer);
        const ownResult = showOwnMissions ? verarbeiteEinsatzliste(ownContainer, true) : { fruehesteZeit: Infinity, eintrag: null, gesamt: 0 };

        const result = allianceResult.fruehesteZeit < ownResult.fruehesteZeit ? allianceResult : ownResult;

        if (result.fruehesteZeit < Infinity) {
            einsatzMitFruehestemEnde = result.eintrag;
            updatePanel(formatTime(result.fruehesteZeit), allianceResult.gesamt);
        }
    }

    function createDraggablePanel() {
        const panel = document.createElement('div');
        panel.id = 'endzeit-panel';

        const pos = loadPanelPosition();
        const left = pos?.left ?? 100;
        const top = pos?.top ?? 100;

        Object.assign(panel.style, {
            position: 'absolute',
            top: `${top}px`,
            left: `${left}px`,
            zIndex: '9999',
            background: '#1e1e1e',
            color: '#fff',
            padding: '4px 6px',
            borderRadius: '6px',
            border: '2px solid #555',
            boxShadow: '0 0 6px rgba(0,0,0,0.5)',
            cursor: 'move',
            userSelect: 'none',
            display: 'flex',
            alignItems: 'center',
            gap: '6px',
            whiteSpace: 'nowrap',
            fontSize: '11px',
            fontWeight: '600'
        });

        panel.innerHTML = `
            <button id="btnNextEnd" title="Zur nächsten Endzeit springen">Nächste Endzeit</button>
            <button id="btnResetIgnored" title="Ignorierte Einsätze zurücksetzen">↺</button>
            <button id="btnToggleChaos" title="Chaostage an/aus">Chaostage: ${chaosMode ? 'AN' : 'AUS'}</button>
            <button id="btnOwnMissions" title="Eigene Einsätze > 15.000 Cr ein/aus">Eigene >10k: ${showOwnMissions ? 'AN' : 'AUS'}</button>
            <div id="creditDisplay" title="Gesamt-Credits" style="
                background:#2980b9;
                width:16px;
                height:16px;
                border-radius:50%;
                display:flex;
                justify-content:center;
                align-items:center;
                font-weight:bold;
                font-size:11px;
                cursor: default;
                user-select:none;
            ">ⓘ</div>
        `;

        document.body.appendChild(panel);

        // Styles für Buttons
        const btnNextEnd = document.getElementById('btnNextEnd');
        Object.assign(btnNextEnd.style, {
            backgroundColor: '#888888',
            color: '#ff0000',
            border: 'none',
            padding: '3px 8px',
            borderRadius: '5px',
            cursor: 'pointer',
            fontWeight: 'bold',
            boxShadow: '0 0 4px rgba(255,0,0,0.6)',
            fontSize: '11px'
        });

        const btnResetIgnored = document.getElementById('btnResetIgnored');
        Object.assign(btnResetIgnored.style, {
            backgroundColor: '#666',
            color: '#fff',
            border: 'none',
            padding: '3px 7px',
            borderRadius: '50%',
            cursor: 'pointer',
            fontWeight: 'bold',
            fontSize: '14px',
            lineHeight: '1',
            boxShadow: '0 0 4px rgba(255,255,255,0.4)',
            userSelect: 'none'
        });

        const btnToggleChaos = document.getElementById('btnToggleChaos');
        const updateChaosButton = () => {
            if (chaosMode) {
                btnToggleChaos.style.backgroundColor = '#e74c3c'; // rot
                btnToggleChaos.style.color = '#fff';
                btnToggleChaos.style.boxShadow = '0 0 6px rgba(231,76,60,0.8)';
            } else {
                btnToggleChaos.style.backgroundColor = '#27ae60'; // grün
                btnToggleChaos.style.color = '#fff';
                btnToggleChaos.style.boxShadow = '0 0 6px rgba(39,174,96,0.8)';
            }
        };
        updateChaosButton();
        btnToggleChaos.style.border = 'none';
        btnToggleChaos.style.padding = '3px 8px';
        btnToggleChaos.style.borderRadius = '5px';
        btnToggleChaos.style.cursor = 'pointer';
        btnToggleChaos.style.fontWeight = 'bold';
        btnToggleChaos.style.fontSize = '11px';

        const btnOwnMissions = document.getElementById('btnOwnMissions');
        Object.assign(btnOwnMissions.style, {
            backgroundColor: '#444',
            color: '#fff',
            border: 'none',
            padding: '3px 8px',
            borderRadius: '5px',
            cursor: 'pointer',
            fontWeight: 'bold',
            boxShadow: '0 0 4px rgba(0,0,0,0.5)',
            fontSize: '11px'
        });

        // Drag-Funktionalität
        let isDragging = false;
        let offsetX, offsetY;
        panel.addEventListener('mousedown', (e) => {
            if (e.target.tagName === 'BUTTON' || e.target.id === 'creditDisplay') return; // Buttons nicht draggable machen
            isDragging = true;
            offsetX = e.clientX - panel.getBoundingClientRect().left;
            offsetY = e.clientY - panel.getBoundingClientRect().top;
            e.preventDefault();
        });
        document.addEventListener('mousemove', (e) => {
            if (isDragging) {
                const newLeft = e.clientX - offsetX;
                const newTop = e.clientY - offsetY;
                panel.style.left = `${newLeft}px`;
                panel.style.top = `${newTop}px`;
            }
        });
        document.addEventListener('mouseup', () => {
            if (isDragging) {
                isDragging = false;
                // Position speichern
                const rect = panel.getBoundingClientRect();
                savePanelPosition(rect.left, rect.top);
            }
        });

        // Button Events
        btnNextEnd.addEventListener('click', () => {
            if (einsatzMitFruehestemEnde) {
                einsatzMitFruehestemEnde.scrollIntoView({ behavior: 'smooth', block: 'center' });
                const endzeitAnzeige = einsatzMitFruehestemEnde.querySelector('.endzeit-anzeige');
                if (endzeitAnzeige) {
                    endzeitAnzeige.classList.add('blink-animation');
                    setTimeout(() => endzeitAnzeige.classList.remove('blink-animation'), 5000);
                }
            }
        });

        btnResetIgnored.addEventListener('click', () => {
            ignoredEinsaetze.clear();
            saveIgnored();
            addEndTimes();
        });

        btnToggleChaos.addEventListener('click', () => {
            chaosMode = !chaosMode;
            btnToggleChaos.textContent = `Chaostage: ${chaosMode ? 'AN' : 'AUS'}`;
            updateChaosButton();
            saveChaosMode();
            addEndTimes();
        });

        btnOwnMissions.addEventListener('click', () => {
            showOwnMissions = !showOwnMissions;
            btnOwnMissions.textContent = `Eigene >10k: ${showOwnMissions ? 'AN' : 'AUS'}`;
            saveOwnMissionsSetting();
            addEndTimes();
        });

        creditDisplay = document.getElementById('creditDisplay');
    }

    function updatePanel(zeit, credits) {
        document.getElementById('btnNextEnd').textContent = `Nächste Endzeit: ${zeit}`;
        if (creditDisplay) {
            creditDisplay.title = `Gesamt-Credits: ${credits.toLocaleString()} Cr`;
        }
    }

    const style = document.createElement('style');
    style.textContent = `
        @keyframes blink {
            0% { background-color: yellow; }
            50% { background-color: red; }
            100% { background-color: yellow; }
        }
        .blink-animation {
            animation: blink 1s linear infinite;
        }
    `;
    document.head.appendChild(style);

    createDraggablePanel();
    setInterval(addEndTimes, 2000);
})();