YouTube Plus4

YouTube tema, ozellik ve oynatici yoneticisi (reklam engelleme icermez)

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

Advertisement:

// ==UserScript==
// @name         YouTube Plus4
// @namespace    http://tampermonkey.net/
// @version      12001
// @description  YouTube tema, ozellik ve oynatici yoneticisi (reklam engelleme icermez)
// @author       Mustafa Hakan
// @match        *://*.youtube.com/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';
    let LANG  = localStorage.getItem('yt-lang')  || 'tr';
    let THEME = localStorage.getItem('yt-theme') || '__default__';
    function getFeature(key, def) {
        if (def === undefined) def = true;
        var v = localStorage.getItem('yt-feat-' + key);
        return v === null ? def : v === '1';
    }
    function setFeature(key, val) {
        localStorage.setItem('yt-feat-' + key, val ? '1' : '0');
    }
    function getSetting(key, def) {
        var v = localStorage.getItem('yt-set-' + key);
        return v === null ? def : v;
    }
    function setSetting(key, val) {
        localStorage.setItem('yt-set-' + key, val);
    }
    var T = {
        tr: {
            panelTitle:    'AYARLAR',
            themeSection:  'TEMA',
            featSection:   'OZELLIKLER',
            charSection:   'KARAKTER',
            trailSection:  'IZ (TRAIL) RENGI',
            shortcutSection: 'KISAYOLLAR',
            labelText:     'YT+',
            defaultTheme:  'YouTube Varsayilan',
            langBtn:       'Switch to English',
            shortcut:      'Ctrl + Shift + D',
            copied:        'Kopyalandi',
            noneTrail:     'Yok',
            features: {
                loop:        'Dongu Butonu',
                character:   'Karakter (Scrubber)',
                trail:       'Oynatma Cubugu Izi',
                label:       'YT+ Etiketi',
                scroll:      'Kaydirma ile Ses',
                pip:         'Picture-in-Picture',
                speed:       'Hiz Secici',
                cinema:      'Sinema Modu',
                timestamp:   'Zaman Damgasi Kopyala',
                autoQuality: 'Otomatik Maks. Kalite',
                subtitleStyle: 'Ozel Altyazi Stili',
                chapterJump: 'Bolum Atlama Tuslari',
                clipSave:    'Klip / Not Kaydet',
                miniPlayerDrag: 'Surukle-Birak Karakter',
            },
            characters: {
                snoopy:   'Snoopy',
                pikachu:  'Pikachu',
                kirby:    'Kirby',
                cat:      'Kedi',
                alien:    'Uzayli',
                rocket:   'Roket',
                ghost:    'Hayalet',
                star:     'Yildiz',
            },
            colors: {
                'Midnight':  'Gece Yarisi',
                'Obsidian':  'Obsidyen',
                'Slate':     'Arduvaz',
                'Forest':    'Orman',
                'Abyss':     'Derin Deniz',
                'Velvet':    'Kadife',
                'Espresso':  'Espresso',
                'Graphite':  'Grafit',
                'Steel':     'Celik',
                'Moss':      'Yosun',
                'Burgundy':  'Bordo',
                'Petroleum': 'Petrol',
                'Aurora':    'Kuzey Isigi',
                'Sand':      'Kum',
                'Rose':      'Gul Kurusu',
                'Ice':       'Buz',
            },
            shortcutsList: [
                ['Ctrl+Shift+D', 'Ayar panelini ac/kapat'],
                ['Ctrl+Shift+L', 'Donguyu ac/kapat'],
                ['Ctrl+Shift+C', 'Zaman damgasini kopyala'],
                ['Ctrl+Shift+,', 'Onceki bolume atla'],
                ['Ctrl+Shift+.', 'Sonraki bolume atla'],
                ['Ctrl+Shift+K', 'Bu anda not/klip kaydet'],
            ],
            clipSaved: 'Not kaydedildi',
            clipPanelTitle: 'KAYITLI NOTLAR',
            clipEmpty: 'Henuz not yok. Ctrl+Shift+K ile ekleyebilirsin.',
            clipDelete: 'Sil',
            clipGoto: 'Git',
        },
        en: {
            panelTitle:    'SETTINGS',
            themeSection:  'THEME',
            featSection:   'FEATURES',
            charSection:   'CHARACTER',
            trailSection:  'TRAIL COLOR',
            shortcutSection: 'SHORTCUTS',
            labelText:     'YT+',
            defaultTheme:  'YouTube Default',
            langBtn:       'Turkceye Gec',
            shortcut:      'Ctrl + Shift + D',
            copied:        'Copied',
            noneTrail:     'None',
            features: {
                loop:        'Loop Button',
                character:   'Character (Scrubber)',
                trail:       'Progress Bar Trail',
                label:       'YT+ Badge',
                scroll:      'Scroll to Volume',
                pip:         'Picture-in-Picture',
                speed:       'Speed Selector',
                cinema:      'Cinema Mode',
                timestamp:   'Copy Timestamp',
                autoQuality: 'Auto Max Quality',
                subtitleStyle: 'Custom Subtitle Style',
                chapterJump: 'Chapter Jump Keys',
                clipSave:    'Save Clip / Note',
                miniPlayerDrag: 'Draggable Character',
            },
            characters: {
                snoopy:   'Snoopy',
                pikachu:  'Pikachu',
                kirby:    'Kirby',
                cat:      'Cat',
                alien:    'Alien',
                rocket:   'Rocket',
                ghost:    'Ghost',
                star:     'Star',
            },
            colors: {
                'Midnight':  'Midnight',
                'Obsidian':  'Obsidian',
                'Slate':     'Slate',
                'Forest':    'Forest',
                'Abyss':     'Abyss',
                'Velvet':    'Velvet',
                'Espresso':  'Espresso',
                'Graphite':  'Graphite',
                'Steel':     'Steel',
                'Moss':      'Moss',
                'Burgundy':  'Burgundy',
                'Petroleum': 'Petroleum',
                'Aurora':    'Aurora',
                'Sand':      'Sand',
                'Rose':      'Rose',
                'Ice':       'Ice',
            },
            shortcutsList: [
                ['Ctrl+Shift+D', 'Toggle settings panel'],
                ['Ctrl+Shift+L', 'Toggle loop'],
                ['Ctrl+Shift+C', 'Copy timestamp'],
                ['Ctrl+Shift+,', 'Jump to previous chapter'],
                ['Ctrl+Shift+.', 'Jump to next chapter'],
                ['Ctrl+Shift+K', 'Save note/clip at current time'],
            ],
            clipSaved: 'Note saved',
            clipPanelTitle: 'SAVED NOTES',
            clipEmpty: 'No notes yet. Press Ctrl+Shift+K to add one.',
            clipDelete: 'Delete',
            clipGoto: 'Go to',
        }
    };
    var THEMES = {
        'Midnight':  ['#0d0d12', '#4a6fa5'],
        'Obsidian':  ['#0f0f0f', '#555555'],
        'Slate':     ['#1c2128', '#6e7c8c'],
        'Forest':    ['#0e1a12', '#3a6b45'],
        'Abyss':     ['#050d1a', '#1a4a7a'],
        'Velvet':    ['#160d1a', '#6b3a7a'],
        'Espresso':  ['#140e0b', '#7a4a30'],
        'Graphite':  ['#141414', '#4a4a4a'],
        'Steel':     ['#0f1418', '#3a5a6a'],
        'Moss':      ['#111a0f', '#4a6a30'],
        'Burgundy':  ['#14080a', '#6a2030'],
        'Petroleum': ['#091518', '#1a5a5a'],
        'Aurora':    ['#0a0f1a', '#2d7a6a'],
        'Sand':      ['#1a1710', '#8a7a50'],
        'Rose':      ['#1a0f12', '#8a4a5a'],
        'Ice':       ['#0f1520', '#5a8aaa'],
    };
    var TRAIL_COLORS = {
        'none':    null,
        'red':     '#ff0033',
        'orange':  '#ff8800',
        'gold':    '#ffd24a',
        'green':   '#3ddc84',
        'cyan':    '#3ad6e0',
        'blue':    '#4a90d9',
        'purple':  '#a14ad9',
        'pink':    '#ff5fa2',
        'rainbow': 'rainbow',
    };
    function getSVG(name) {
        var svgs = {
            snoopy: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="34" height="34">' +
                '<ellipse cx="10" cy="9" rx="4" ry="6" fill="#111" transform="rotate(-15,10,9)"/>' +
                '<ellipse cx="22" cy="8" rx="3.5" ry="5.5" fill="#111" transform="rotate(10,22,8)"/>' +
                '<ellipse cx="16" cy="16" rx="10" ry="9" fill="#f5f5f5"/>' +
                '<ellipse cx="16" cy="20" rx="6" ry="4" fill="#111"/>' +
                '<circle cx="12.5" cy="13.5" r="1.5" fill="#111"/>' +
                '<circle cx="19.5" cy="13.5" r="1.5" fill="#111"/>' +
                '<circle cx="13" cy="13" r="0.5" fill="#fff"/>' +
                '<circle cx="20" cy="13" r="0.5" fill="#fff"/>' +
                '<ellipse cx="16" cy="18.5" rx="2.5" ry="1.5" fill="#222"/>' +
                '<path d="M13.5 21.5 Q16 23 18.5 21.5" stroke="#f5f5f5" stroke-width="1.2" fill="none" stroke-linecap="round"/>' +
                '</svg>',
            pikachu: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="34" height="34">' +
                '<ellipse cx="16" cy="18" rx="12" ry="11" fill="#FFD700"/>' +
                '<ellipse cx="8" cy="8" rx="4" ry="7" fill="#FFD700" transform="rotate(-20,8,8)"/>' +
                '<ellipse cx="8" cy="5" rx="2" ry="3.5" fill="#111" transform="rotate(-20,8,5)"/>' +
                '<ellipse cx="24" cy="8" rx="4" ry="7" fill="#FFD700" transform="rotate(20,24,8)"/>' +
                '<ellipse cx="24" cy="5" rx="2" ry="3.5" fill="#111" transform="rotate(20,24,5)"/>' +
                '<circle cx="11.5" cy="15" r="2" fill="#111"/>' +
                '<circle cx="20.5" cy="15" r="2" fill="#111"/>' +
                '<circle cx="12" cy="14.3" r="0.7" fill="#fff"/>' +
                '<circle cx="21" cy="14.3" r="0.7" fill="#fff"/>' +
                '<ellipse cx="9" cy="20" rx="3" ry="2" fill="#FF6060" opacity="0.8"/>' +
                '<ellipse cx="23" cy="20" rx="3" ry="2" fill="#FF6060" opacity="0.8"/>' +
                '<path d="M13 22 Q16 24.5 19 22" stroke="#111" stroke-width="1.2" fill="none" stroke-linecap="round"/>' +
                '<ellipse cx="16" cy="21.5" rx="1.5" ry="1" fill="#FF8888"/>' +
                '</svg>',
            kirby: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="34" height="34">' +
                '<ellipse cx="16" cy="17" rx="13" ry="13" fill="#FFB7D5"/>' +
                '<ellipse cx="10" cy="23" rx="4" ry="3" fill="#FF85B3" transform="rotate(-20,10,23)"/>' +
                '<ellipse cx="22" cy="23" rx="4" ry="3" fill="#FF85B3" transform="rotate(20,22,23)"/>' +
                '<circle cx="12" cy="14" r="2.5" fill="#111"/>' +
                '<circle cx="20" cy="14" r="2.5" fill="#111"/>' +
                '<circle cx="12.7" cy="13" r="1" fill="#fff"/>' +
                '<circle cx="20.7" cy="13" r="1" fill="#fff"/>' +
                '<ellipse cx="12" cy="14" rx="1" ry="1.5" fill="#3a5af0" opacity="0.6"/>' +
                '<ellipse cx="20" cy="14" rx="1" ry="1.5" fill="#3a5af0" opacity="0.6"/>' +
                '<ellipse cx="16" cy="19.5" rx="2.5" ry="1.5" fill="#e0609a"/>' +
                '<path d="M13.5 22 Q16 24 18.5 22" stroke="#e0609a" stroke-width="1.5" fill="none" stroke-linecap="round"/>' +
                '</svg>',
            cat: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="34" height="34">' +
                '<polygon points="6,12 2,3 10,9" fill="#888"/>' +
                '<polygon points="26,12 30,3 22,9" fill="#888"/>' +
                '<ellipse cx="16" cy="18" rx="12" ry="11" fill="#aaa"/>' +
                '<ellipse cx="16" cy="18" rx="8" ry="7" fill="#eee"/>' +
                '<ellipse cx="12" cy="15" rx="2" ry="2.5" fill="#111"/>' +
                '<ellipse cx="20" cy="15" rx="2" ry="2.5" fill="#111"/>' +
                '<circle cx="12.7" cy="14" r="0.8" fill="#fff"/>' +
                '<circle cx="20.7" cy="14" r="0.8" fill="#fff"/>' +
                '<ellipse cx="16" cy="19" rx="1.5" ry="1" fill="#ffaaaa"/>' +
                '<path d="M13.5 21 Q16 23 18.5 21" stroke="#999" stroke-width="1.2" fill="none" stroke-linecap="round"/>' +
                '<line x1="6" y1="19" x2="1" y2="17" stroke="#888" stroke-width="0.8"/>' +
                '<line x1="6" y1="20" x2="1" y2="20" stroke="#888" stroke-width="0.8"/>' +
                '<line x1="6" y1="21" x2="1" y2="23" stroke="#888" stroke-width="0.8"/>' +
                '<line x1="26" y1="19" x2="31" y2="17" stroke="#888" stroke-width="0.8"/>' +
                '<line x1="26" y1="20" x2="31" y2="20" stroke="#888" stroke-width="0.8"/>' +
                '<line x1="26" y1="21" x2="31" y2="23" stroke="#888" stroke-width="0.8"/>' +
                '</svg>',
            alien: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="34" height="34">' +
                '<ellipse cx="16" cy="17" rx="11" ry="13" fill="#7aee88"/>' +
                '<ellipse cx="11" cy="14" rx="4.5" ry="3.5" fill="#111" opacity="0.85"/>' +
                '<ellipse cx="21" cy="14" rx="4.5" ry="3.5" fill="#111" opacity="0.85"/>' +
                '<ellipse cx="11" cy="14" rx="2.5" ry="2" fill="#6688ff"/>' +
                '<ellipse cx="21" cy="14" rx="2.5" ry="2" fill="#6688ff"/>' +
                '<circle cx="11.8" cy="13.3" r="0.9" fill="#fff"/>' +
                '<circle cx="21.8" cy="13.3" r="0.9" fill="#fff"/>' +
                '<path d="M12 22 Q16 20 20 22" stroke="#5acc66" stroke-width="1.5" fill="none" stroke-linecap="round"/>' +
                '<line x1="10" y1="4" x2="7" y2="1" stroke="#7aee88" stroke-width="1.5"/>' +
                '<circle cx="7" cy="1" r="1.5" fill="#aaffaa"/>' +
                '<line x1="22" y1="4" x2="25" y2="1" stroke="#7aee88" stroke-width="1.5"/>' +
                '<circle cx="25" cy="1" r="1.5" fill="#aaffaa"/>' +
                '</svg>',
            rocket: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="34" height="34">' +
                '<path d="M16 2 C10 8 8 16 8 22 L16 26 L24 22 C24 16 22 8 16 2Z" fill="#dde8ff"/>' +
                '<ellipse cx="16" cy="13" rx="4" ry="4" fill="#4a8aff"/>' +
                '<path d="M8 22 L4 28 L10 25Z" fill="#ff6030"/>' +
                '<path d="M24 22 L28 28 L22 25Z" fill="#ff6030"/>' +
                '<path d="M12 26 Q16 30 20 26" fill="#ff8050"/>' +
                '<circle cx="16" cy="13" r="2" fill="#cce0ff" opacity="0.7"/>' +
                '</svg>',
            ghost: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="34" height="34">' +
                '<path d="M6 26 V14 a10 10 0 0 1 20 0 V26 L22 22 L18 26 L14 22 L10 26 Z" fill="#f0f3ff" opacity="0.95"/>' +
                '<ellipse cx="12" cy="14" rx="2" ry="2.6" fill="#222"/>' +
                '<ellipse cx="20" cy="14" rx="2" ry="2.6" fill="#222"/>' +
                '<ellipse cx="16" cy="19" rx="2.2" ry="1.6" fill="#aab4e0" opacity="0.7"/>' +
                '</svg>',
            star: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="34" height="34">' +
                '<path d="M16 2 L20 12 L31 12.5 L22 19.5 L25 30 L16 23.5 L7 30 L10 19.5 L1 12.5 L12 12 Z" fill="#ffd84a"/>' +
                '<circle cx="13" cy="14.5" r="1.6" fill="#222"/>' +
                '<circle cx="19" cy="14.5" r="1.6" fill="#222"/>' +
                '<path d="M13 19 Q16 21.2 19 19" stroke="#222" stroke-width="1.3" fill="none" stroke-linecap="round"/>' +
                '</svg>',
        };
        return svgs[name] || svgs['snoopy'];
    }
    function isDefaultTheme(t) {
        return !t || t === '__default__' || !THEMES[t];
    }
    function applyTheme(themeName) {
        THEME = isDefaultTheme(themeName) ? '__default__' : themeName;
        localStorage.setItem('yt-theme', THEME);
        var s = document.getElementById('yt-custom-style');
        if (isDefaultTheme(THEME)) {
            if (s) s.remove();
            return;
        }
        var pair   = THEMES[THEME];
        var bg     = pair[0];
        var accent = pair[1];
        if (!s) {
            s = document.createElement('style');
            s.id = 'yt-custom-style';
            document.head.appendChild(s);
        }
        s.textContent = [
            'html, body, ytd-app, #content, #page-manager, ytd-browse, ytd-watch-flexy,',
            'ytd-search, ytd-two-column-browse-results-renderer, ytd-rich-grid-renderer,',
            '#primary, #secondary, ytd-mini-guide-renderer, ytd-guide-renderer,',
            '#guide-content, tp-yt-app-drawer, #contentContainer, ytd-masthead {',
            '    background-color: ' + bg + ' !important;',
            '    background-image: none !important;',
            '}',
            'ytd-rich-item-renderer, ytd-video-renderer, ytd-compact-video-renderer,',
            'ytd-playlist-renderer, ytd-shelf-renderer, ytd-item-section-renderer,',
            '#dismissible, ytd-comment-thread-renderer, ytd-comment-renderer {',
            '    background-color: transparent !important;',
            '}',
            'ytd-guide-entry-renderer:hover, ytd-mini-guide-entry-renderer:hover {',
            '    background-color: ' + accent + '22 !important;',
            '}',
            '.ytp-play-progress { background: ' + accent + ' !important; }',
            '.ytp-scrubber-button { background-color: ' + accent + ' !important; }',
            '#yt-loop-btn { opacity: 0.45; transition: opacity 0.2s; }',
            '#yt-loop-btn.yt-active { opacity: 1 !important; }',
            '#yt-loop-btn svg path, #yt-loop-btn svg polyline { stroke: ' + accent + ' !important; }',
            '#yt-pip-btn { opacity: 0.7; transition: opacity 0.2s; }',
            '#yt-pip-btn:hover { opacity: 1; }',
            '#yt-speed-select {',
            '    background: ' + bg + '; color: #fff; border: 1px solid ' + accent + '66;',
            '    border-radius: 4px; font-size: 11px; font-weight: 700; cursor: pointer;',
            '    padding: 2px 4px; margin: 0 4px;',
            '}',
        ].join('\n');
    }
    function addLabel() {
        if (!getFeature('label')) {
            var old = document.getElementById('yt-premium-label');
            if (old) old.remove();
            return;
        }
        if (document.getElementById('yt-premium-label')) return;
        var logo = document.querySelector('#logo, ytd-logo');
        if (!logo) return;
        var label = document.createElement('span');
        label.id = 'yt-premium-label';
        label.textContent = T[LANG].labelText;
        label.title = T[LANG].shortcut;
        label.style.cssText = [
            'color: #ffffff !important;',
            'font-size: 13px;',
            'font-weight: 800;',
            'font-style: italic;',
            'cursor: pointer;',
            'margin-left: 8px;',
            'letter-spacing: 0.3px;',
            'opacity: 0.92;',
            'transition: opacity 0.2s;',
            'background: none;',
            'border: none;',
            'padding: 0;',
            'text-shadow: 0 1px 6px rgba(0,0,0,0.7);',
        ].join('');
        label.onmouseenter = function () { label.style.opacity = '0.55'; };
        label.onmouseleave = function () { label.style.opacity = '0.92'; };
        label.onclick = function (e) { e.stopPropagation(); openPanel(); };
        logo.parentNode.insertBefore(label, logo.nextSibling);
    }
    var charPosRAF = null;
    var charDragOffset = null;
    function getPlayerEls() {
        return {
            player: document.querySelector('.html5-video-player, #movie_player'),
            scrubber: document.querySelector('.ytp-scrubber-button'),
            progressBar: document.querySelector('.ytp-progress-bar'),
            video: document.querySelector('video'),
        };
    }
    function positionCharacter() {
        var charEl = document.getElementById('yt-char-el');
        if (!charEl) return;
        if (charEl.getAttribute('data-dragging') === '1') return;
        var els = getPlayerEls();
        if (!els.player || !els.scrubber || !els.progressBar) return;
        var playerRect = els.player.getBoundingClientRect();
        var scRect     = els.scrubber.getBoundingClientRect();
        if (scRect.width === 0 && scRect.height === 0) return;
        var leftPx = scRect.left - playerRect.left + scRect.width / 2 - 17;
        var topPx  = scRect.top  - playerRect.top  - 44;
        charEl.style.left = leftPx + 'px';
        charEl.style.top  = topPx  + 'px';
    }
    function startCharLoop() {
        if (charPosRAF) return;
        function loop() {
            positionCharacter();
            charPosRAF = requestAnimationFrame(loop);
        }
        charPosRAF = requestAnimationFrame(loop);
    }
    function stopCharLoop() {
        if (charPosRAF) {
            cancelAnimationFrame(charPosRAF);
            charPosRAF = null;
        }
    }
    function makeCharDraggable(charEl) {
        charEl.style.pointerEvents = 'auto';
        charEl.style.cursor = 'grab';
        charEl.onmousedown = function (e) {
            if (!getFeature('miniPlayerDrag')) return;
            e.preventDefault();
            charEl.setAttribute('data-dragging', '1');
            charEl.style.cursor = 'grabbing';
            var els = getPlayerEls();
            var playerRect = els.player ? els.player.getBoundingClientRect() : { left: 0, top: 0 };
            var startLeft = parseFloat(charEl.style.left) || 0;
            var startTop  = parseFloat(charEl.style.top)  || 0;
            var startX = e.clientX, startY = e.clientY;
            function onMove(ev) {
                charEl.style.left = (startLeft + (ev.clientX - startX)) + 'px';
                charEl.style.top  = (startTop  + (ev.clientY - startY)) + 'px';
            }
            function onUp() {
                document.removeEventListener('mousemove', onMove);
                document.removeEventListener('mouseup', onUp);
                charEl.style.cursor = 'grab';
                setTimeout(function () { charEl.removeAttribute('data-dragging'); }, 600);
            }
            document.addEventListener('mousemove', onMove);
            document.addEventListener('mouseup', onUp);
        };
    }
    function injectCharacter() {
        var charKey = localStorage.getItem('yt-character') || 'snoopy';
        if (!getFeature('character')) {
            var old = document.getElementById('yt-char-el');
            if (old) old.remove();
            stopCharLoop();
            return;
        }
        var els = getPlayerEls();
        if (!els.player || !els.scrubber || !els.progressBar) return;
        var charEl = document.getElementById('yt-char-el');
        if (!charEl) {
            charEl = document.createElement('div');
            charEl.id = 'yt-char-el';
            charEl.innerHTML = getSVG(charKey);
            charEl.setAttribute('data-char', charKey);
            charEl.style.cssText = [
                'position: absolute;',
                'pointer-events: none;',
                'z-index: 2147483600;',
                'width: 36px;',
                'height: 36px;',
                'filter: drop-shadow(0 2px 6px rgba(0,0,0,0.95));',
                'will-change: left, top;',
            ].join('');
            els.player.style.overflow = 'visible';
            els.player.appendChild(charEl);
            makeCharDraggable(charEl);
        } else {
            var currentChar = charEl.getAttribute('data-char');
            if (currentChar !== charKey) {
                charEl.innerHTML = getSVG(charKey);
                charEl.setAttribute('data-char', charKey);
                makeCharDraggable(charEl);
            }
        }
        startCharLoop();
    }
    function ensureTrailEl() {
        var els = getPlayerEls();
        if (!els.progressBar) return null;
        var trail = els.progressBar.querySelector('#yt-trail-el');
        if (!trail) {
            trail = document.createElement('div');
            trail.id = 'yt-trail-el';
            trail.style.cssText = [
                'position: absolute;',
                'left: 0; top: 0; bottom: 0;',
                'pointer-events: none;',
                'z-index: 30;',
                'border-radius: 2px;',
                'transition: width 0.08s linear;',
            ].join('');
            els.progressBar.style.position = els.progressBar.style.position || 'relative';
            els.progressBar.appendChild(trail);
        }
        return trail;
    }
    function updateTrail() {
        var trail = document.getElementById('yt-trail-el');
        var trailKey = getSetting('trail-color', 'gold');
        if (!getFeature('trail') || trailKey === 'none') {
            if (trail) trail.remove();
            return;
        }
        var els = getPlayerEls();
        if (!els.video || !els.progressBar) return;
        trail = ensureTrailEl();
        if (!trail) return;
        var pct = els.video.duration ? (els.video.currentTime / els.video.duration) * 100 : 0;
        trail.style.width = pct + '%';
        if (trailKey === 'rainbow') {
            trail.style.background = 'linear-gradient(90deg, #ff0033, #ff8800, #ffd24a, #3ddc84, #3ad6e0, #4a90d9, #a14ad9, #ff5fa2)';
            trail.style.backgroundSize = (els.progressBar.offsetWidth || 600) + 'px 100%';
        } else {
            var color = TRAIL_COLORS[trailKey] || TRAIL_COLORS['gold'];
            trail.style.background = color;
            trail.style.boxShadow = '0 0 6px ' + color + 'aa';
        }
    }
    function addLoopButton() {
        if (!getFeature('loop')) {
            var existing = document.getElementById('yt-loop-btn');
            if (existing) existing.remove();
            return;
        }
        if (document.getElementById('yt-loop-btn')) return;
        var ctrl = document.querySelector('.ytp-right-controls');
        if (!ctrl) return;
        var btn = document.createElement('button');
        btn.id = 'yt-loop-btn';
        btn.className = 'ytp-button';
        btn.title = T[LANG].features.loop;
        btn.innerHTML = '<svg viewBox="0 0 24 24" width="22" height="22" fill="none" xmlns="http://www.w3.org/2000/svg">' +
            '<polyline points="17,1 21,5 17,9" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>' +
            '<path d="M3 11V9a4 4 0 0 1 4-4h14" stroke="#fff" stroke-width="2" stroke-linecap="round"/>' +
            '<polyline points="7,23 3,19 7,15" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>' +
            '<path d="M21 13v2a4 4 0 0 1-4 4H3" stroke="#fff" stroke-width="2" stroke-linecap="round"/>' +
            '</svg>';
        btn.style.cssText = 'display:flex;align-items:center;justify-content:center;width:36px;height:36px;';
        btn.onclick = function () { toggleLoop(); };
        ctrl.prepend(btn);
    }
    function toggleLoop() {
        var v = document.querySelector('video');
        if (!v) return;
        v.loop = !v.loop;
        var btn = document.getElementById('yt-loop-btn');
        if (btn) btn.classList.toggle('yt-active', v.loop);
    }
    function addPipButton() {
        if (!getFeature('pip')) {
            var existing = document.getElementById('yt-pip-btn');
            if (existing) existing.remove();
            return;
        }
        if (document.getElementById('yt-pip-btn')) return;
        var ctrl = document.querySelector('.ytp-right-controls');
        if (!ctrl) return;
        var btn = document.createElement('button');
        btn.id = 'yt-pip-btn';
        btn.className = 'ytp-button';
        btn.title = 'Picture-in-Picture';
        btn.innerHTML = '<svg viewBox="0 0 24 24" width="22" height="22" fill="none" xmlns="http://www.w3.org/2000/svg">' +
            '<rect x="2" y="4" width="20" height="14" rx="2" stroke="#fff" stroke-width="2"/>' +
            '<rect x="12" y="11" width="9" height="6" rx="1" fill="#fff"/>' +
            '</svg>';
        btn.style.cssText = 'display:flex;align-items:center;justify-content:center;width:36px;height:36px;';
        btn.onclick = function () {
            var v = document.querySelector('video');
            if (!v) return;
            if (document.pictureInPictureElement) {
                document.exitPictureInPicture().catch(function () {});
            } else if (document.pictureInPictureEnabled) {
                v.requestPictureInPicture().catch(function () {});
            }
        };
        ctrl.prepend(btn);
    }
    function addSpeedSelector() {
        if (!getFeature('speed')) {
            var existing = document.getElementById('yt-speed-select');
            if (existing) existing.remove();
            return;
        }
        if (document.getElementById('yt-speed-select')) return;
        var ctrl = document.querySelector('.ytp-right-controls');
        if (!ctrl) return;
        var sel = document.createElement('select');
        sel.id = 'yt-speed-select';
        sel.title = LANG === 'tr' ? 'Oynatma Hizi' : 'Playback Speed';
        var speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5, 3];
        var v = document.querySelector('video');
        var current = v ? v.playbackRate : 1;
        speeds.forEach(function (s) {
            var opt = document.createElement('option');
            opt.value = s;
            opt.textContent = s + 'x';
            if (s === current) opt.selected = true;
            sel.appendChild(opt);
        });
        sel.onclick = function (e) { e.stopPropagation(); };
        sel.onchange = function () {
            var vid = document.querySelector('video');
            if (vid) vid.playbackRate = parseFloat(sel.value);
        };
        ctrl.prepend(sel);
    }
    function applyCinemaMode() {
        var s = document.getElementById('yt-cinema-style');
        if (!getFeature('cinema')) {
            if (s) s.remove();
            return;
        }
        if (s) return;
        s = document.createElement('style');
        s.id = 'yt-cinema-style';
        s.textContent = [
            '#secondary { display: none !important; }',
            '#primary { max-width: 100% !important; }',
            'ytd-watch-flexy[theater] #primary-inner { max-width: 100% !important; }',
            '#below { max-width: 100% !important; }',
        ].join('\n');
        document.head.appendChild(s);
    }
    function formatTimestamp(t) {
        t = Math.floor(t);
        var h = Math.floor(t / 3600);
        var m = Math.floor((t % 3600) / 60);
        var s = t % 60;
        var mStr = h > 0 ? String(m).padStart(2, '0') : String(m);
        var sStr = String(s).padStart(2, '0');
        return (h > 0 ? h + ':' : '') + mStr + ':' + sStr;
    }
    function copyTimestamp() {
        var v = document.querySelector('video');
        if (!v) return;
        var t = Math.floor(v.currentTime);
        var ts = formatTimestamp(t);
        var url = window.location.href.split('&t=')[0].split('?t=')[0] + (window.location.href.indexOf('?') > -1 ? '&t=' : '?t=') + t + 's';
        navigator.clipboard.writeText(url).catch(function () {});
        var btn = document.getElementById('yt-ts-btn');
        if (btn) {
            var prevTitle = T[LANG].features.timestamp;
            btn.title = T[LANG].copied + ': ' + ts;
            setTimeout(function () { btn.title = prevTitle; }, 2000);
        }
        return ts;
    }
    function addTimestampButton() {
        if (!getFeature('timestamp')) {
            var existing = document.getElementById('yt-ts-btn');
            if (existing) existing.remove();
            return;
        }
        if (document.getElementById('yt-ts-btn')) return;
        var ctrl = document.querySelector('.ytp-right-controls');
        if (!ctrl) return;
        var btn = document.createElement('button');
        btn.id = 'yt-ts-btn';
        btn.className = 'ytp-button';
        btn.title = T[LANG].features.timestamp;
        btn.innerHTML = '<svg viewBox="0 0 24 24" width="22" height="22" fill="none" xmlns="http://www.w3.org/2000/svg">' +
            '<circle cx="12" cy="12" r="9" stroke="#fff" stroke-width="2"/>' +
            '<path d="M12 7v5l3 3" stroke="#fff" stroke-width="2" stroke-linecap="round"/>' +
            '</svg>';
        btn.style.cssText = 'display:flex;align-items:center;justify-content:center;width:36px;height:36px;opacity:0.7;transition:opacity 0.2s;';
        btn.onmouseenter = function () { btn.style.opacity = '1'; };
        btn.onmouseleave = function () { btn.style.opacity = '0.7'; };
        btn.onclick = function () { copyTimestamp(); };
        ctrl.prepend(btn);
    }
    var scrollEnabled = false;
    function enableScrollVolume() {
        if (!getFeature('scroll')) { scrollEnabled = false; return; }
        if (scrollEnabled) return;
        var player = document.querySelector('.html5-video-player');
        if (!player) return;
        scrollEnabled = true;
        player.addEventListener('wheel', function (e) {
            if (!getFeature('scroll')) return;
            var v = document.querySelector('video');
            if (!v) return;
            e.preventDefault();
            var delta = e.deltaY < 0 ? 0.05 : -0.05;
            v.volume = Math.min(1, Math.max(0, v.volume + delta));
        }, { passive: false });
    }
    var qualityTriedFor = null;
    function applyAutoQuality() {
        if (!getFeature('autoQuality')) return;
        var player = document.getElementById('movie_player');
        if (!player || typeof player.getAvailableQualityLevels !== 'function') return;
        var videoId = (new URLSearchParams(location.search)).get('v') || location.pathname;
        if (qualityTriedFor === videoId) return;
        var levels = player.getAvailableQualityLevels();
        if (levels && levels.length) {
            try {
                player.setPlaybackQualityRange(levels[0], levels[0]);
                qualityTriedFor = videoId;
            } catch (e) {  }
        }
    }
    function applySubtitleStyle() {
        var s = document.getElementById('yt-subtitle-style');
        if (!getFeature('subtitleStyle')) {
            if (s) s.remove();
            return;
        }
        if (s) return;
        s = document.createElement('style');
        s.id = 'yt-subtitle-style';
        s.textContent = [
            '.ytp-caption-segment {',
            '    background-color: rgba(0,0,0,0.55) !important;',
            '    color: #ffffff !important;',
            '    font-size: 105% !important;',
            '    padding: 2px 6px !important;',
            '    border-radius: 4px !important;',
            '    text-shadow: none !important;',
            '}',
            '.caption-window { bottom: 8% !important; }',
        ].join('\n');
        document.head.appendChild(s);
    }
    function getChapterMarkers() {
        return Array.prototype.slice.call(document.querySelectorAll('.ytp-chapter-hover-container, .ytp-progress-bar-padding .ytp-chapter-title'));
    }
    function getChapterTimesFromMarkers() {
        var bar = document.querySelector('.ytp-progress-bar');
        if (!bar) return [];
        var markers = bar.querySelectorAll('.ytp-chapter-hover-container');
        var dur = (document.querySelector('video') || {}).duration || 0;
        if (!markers.length || !dur) return [];
        var barWidth = bar.getBoundingClientRect().width || 1;
        var times = [0];
        markers.forEach(function (m) {
            var left = parseFloat(m.style.left) || 0;
            var pct = left / barWidth;
            times.push(pct * dur);
        });
        return times.sort(function (a, b) { return a - b; });
    }
    function jumpChapter(direction) {
        if (!getFeature('chapterJump')) return;
        var v = document.querySelector('video');
        if (!v) return;
        var times = getChapterTimesFromMarkers();
        if (!times.length) {
            v.currentTime = Math.max(0, v.currentTime + direction * 10);
            return;
        }
        var cur = v.currentTime;
        if (direction > 0) {
            var next = times.find(function (t) { return t > cur + 0.5; });
            v.currentTime = next !== undefined ? next : v.duration;
        } else {
            var prevTimes = times.filter(function (t) { return t < cur - 0.5; });
            v.currentTime = prevTimes.length ? prevTimes[prevTimes.length - 1] : 0;
        }
    }
    function getVideoId() {
        return (new URLSearchParams(location.search)).get('v') || location.href;
    }
    function getNotesForVideo(videoId) {
        try {
            var raw = localStorage.getItem('yt-notes-' + videoId);
            return raw ? JSON.parse(raw) : [];
        } catch (e) { return []; }
    }
    function saveNoteForVideo(videoId, note) {
        var notes = getNotesForVideo(videoId);
        notes.push(note);
        localStorage.setItem('yt-notes-' + videoId, JSON.stringify(notes));
    }
    function deleteNoteForVideo(videoId, index) {
        var notes = getNotesForVideo(videoId);
        notes.splice(index, 1);
        localStorage.setItem('yt-notes-' + videoId, JSON.stringify(notes));
    }
    function quickSaveNote() {
        if (!getFeature('clipSave')) return;
        var v = document.querySelector('video');
        if (!v) return;
        var videoId = getVideoId();
        var t = Math.floor(v.currentTime);
        saveNoteForVideo(videoId, { t: t, label: formatTimestamp(t), created: Date.now() });
        flashToast(T[LANG].clipSaved + ' (' + formatTimestamp(t) + ')');
    }
    function flashToast(text) {
        var old = document.getElementById('yt-toast');
        if (old) old.remove();
        var toast = document.createElement('div');
        toast.id = 'yt-toast';
        toast.textContent = text;
        toast.style.cssText = [
            'position:fixed;bottom:24px;left:50%;transform:translateX(-50%);',
            'background:#0d0d14;color:#fff;font-size:12px;font-weight:700;',
            'padding:9px 16px;border-radius:8px;z-index:2147483647;',
            'border:1px solid #2a2a3a;box-shadow:0 8px 24px rgba(0,0,0,0.6);',
            'opacity:0;transition:opacity 0.2s;',
        ].join('');
        document.body.appendChild(toast);
        requestAnimationFrame(function () { toast.style.opacity = '1'; });
        setTimeout(function () {
            toast.style.opacity = '0';
            setTimeout(function () { toast.remove(); }, 250);
        }, 1800);
    }
    function mk(tag, style, text) {
        var e = document.createElement(tag);
        if (style) e.style.cssText = style;
        if (text !== undefined) e.textContent = text;
        return e;
    }
    function secLabel(text) {
        return mk('div', 'color:#3a3a55;font-size:9px;font-weight:900;letter-spacing:2px;text-transform:uppercase;margin:12px 0 6px 2px;', text);
    }
    function buildToggle(active) {
        var wrap  = mk('div', 'display:flex;align-items:center;flex-shrink:0;');
        var track = mk('div', 'width:32px;height:17px;border-radius:9px;background:' + (active ? '#4a90d9' : '#2a2a3a') + ';position:relative;transition:background 0.2s;');
        track.className = 'yt-toggle-track';
        var thumb = mk('div', 'position:absolute;top:2px;left:2px;width:13px;height:13px;border-radius:50%;background:#fff;transform:' + (active ? 'translateX(15px)' : 'translateX(0)') + ';transition:transform 0.2s;box-shadow:0 1px 3px rgba(0,0,0,0.5);');
        thumb.className = 'yt-toggle-thumb';
        track.appendChild(thumb);
        wrap.appendChild(track);
        return wrap;
    }
    function openNotesPanel() {
        var existingSettings = document.getElementById('yt-settings-panel');
        if (existingSettings) existingSettings.remove();
        var existing = document.getElementById('yt-notes-panel');
        if (existing) { existing.remove(); return; }
        var videoId = getVideoId();
        var notes = getNotesForVideo(videoId);
        var p = mk('div', [
            'position:fixed;top:58px;right:14px;',
            'background:#0d0d14;border:1px solid #1e1e2e;border-radius:14px;',
            'padding:14px 14px 12px;z-index:2147483647;width:280px;max-height:70vh;',
            'overflow-y:auto;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;',
            'box-shadow:0 16px 48px rgba(0,0,0,0.85);user-select:none;',
        ].join(''));
        p.id = 'yt-notes-panel';
        var header = mk('div', 'display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;');
        header.appendChild(mk('span', 'color:#fff;font-size:11px;font-weight:900;letter-spacing:2px;', T[LANG].clipPanelTitle));
        var closeBtn = mk('span', 'color:#333;font-size:16px;cursor:pointer;line-height:1;padding:2px 4px;', 'x');
        closeBtn.onclick = function () { p.remove(); };
        header.appendChild(closeBtn);
        p.appendChild(header);
        if (!notes.length) {
            p.appendChild(mk('div', 'color:#555;font-size:11px;text-align:center;padding:18px 6px;line-height:1.5;', T[LANG].clipEmpty));
        } else {
            notes.slice().reverse().forEach(function (note, revIdx) {
                var realIdx = notes.length - 1 - revIdx;
                var row = mk('div', 'display:flex;align-items:center;justify-content:space-between;padding:7px 9px;border-radius:8px;background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.06);margin-bottom:5px;');
                row.appendChild(mk('span', 'color:#aaa;font-size:11px;font-weight:700;', note.label));
                var btnWrap = mk('div', 'display:flex;gap:6px;');
                var gotoBtn = mk('span', 'color:#4a90d9;font-size:10px;font-weight:700;cursor:pointer;', T[LANG].clipGoto);
                gotoBtn.onclick = function () {
                    var v = document.querySelector('video');
                    if (v) v.currentTime = note.t;
                };
                var delBtn = mk('span', 'color:#777;font-size:10px;font-weight:700;cursor:pointer;', T[LANG].clipDelete);
                delBtn.onclick = function () {
                    deleteNoteForVideo(videoId, realIdx);
                    p.remove();
                    openNotesPanel();
                };
                btnWrap.appendChild(gotoBtn);
                btnWrap.appendChild(delBtn);
                row.appendChild(btnWrap);
                p.appendChild(row);
            });
        }
        document.body.appendChild(p);
        requestAnimationFrame(function () {
            document.addEventListener('mousedown', function outsideClick(e) {
                if (!p.contains(e.target)) {
                    p.remove();
                    document.removeEventListener('mousedown', outsideClick);
                }
            });
        });
    }
    function openPanel() {
        var existingNotes = document.getElementById('yt-notes-panel');
        if (existingNotes) existingNotes.remove();
        var existing = document.getElementById('yt-settings-panel');
        if (existing) { existing.remove(); return; }
        var p = mk('div', [
            'position:fixed;top:58px;right:14px;',
            'background:#0d0d14;',
            'border:1px solid #1e1e2e;',
            'border-radius:14px;',
            'padding:14px 14px 12px;',
            'z-index:2147483647;',
            'width:300px;',
            'max-height:88vh;',
            'overflow-y:auto;',
            'font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;',
            'box-shadow:0 16px 48px rgba(0,0,0,0.85),0 0 0 1px rgba(255,255,255,0.04);',
            'user-select:none;',
            'scrollbar-width:thin;scrollbar-color:#222 transparent;',
        ].join(''));
        p.id = 'yt-settings-panel';
        var header = mk('div', 'display:flex;align-items:center;justify-content:space-between;margin-bottom:4px;');
        header.appendChild(mk('span', 'color:#fff;font-size:11px;font-weight:900;letter-spacing:2px;', T[LANG].panelTitle));
        var closeBtn = mk('span', 'color:#333;font-size:16px;cursor:pointer;line-height:1;padding:2px 4px;', 'x');
        closeBtn.onmouseenter = function () { closeBtn.style.color = '#aaa'; };
        closeBtn.onmouseleave = function () { closeBtn.style.color = '#333'; };
        closeBtn.onclick = function () { p.remove(); };
        header.appendChild(closeBtn);
        p.appendChild(header);
        p.appendChild(secLabel(T[LANG].themeSection));
        var themeGrid = mk('div', 'display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-bottom:4px;');
        var isDefActive = isDefaultTheme(THEME);
        var defCard = mk('div',
            'grid-column:span 2;padding:8px 12px;border-radius:8px;cursor:pointer;text-align:center;font-size:10px;font-weight:700;letter-spacing:0.5px;' +
            'border:1px solid ' + (isDefActive ? 'rgba(255,255,255,0.3)' : 'rgba(255,255,255,0.07)') + ';' +
            'background:' + (isDefActive ? 'rgba(255,255,255,0.09)' : 'rgba(255,255,255,0.02)') + ';' +
            'color:' + (isDefActive ? '#fff' : '#444') + ';',
            T[LANG].defaultTheme
        );
        defCard.onclick = function () { applyTheme('__default__'); p.remove(); };
        themeGrid.appendChild(defCard);
        Object.keys(THEMES).forEach(function (key) {
            var pair   = THEMES[key];
            var bg     = pair[0];
            var accent = pair[1];
            var isAct  = key === THEME;
            var name   = (T[LANG].colors && T[LANG].colors[key]) || key;
            var card = mk('div',
                'display:flex;align-items:center;gap:8px;padding:7px 10px;border-radius:8px;cursor:pointer;' +
                'border:1px solid ' + (isAct ? accent + 'aa' : 'rgba(255,255,255,0.06)') + ';' +
                'background:' + (isAct ? bg + 'dd' : 'rgba(255,255,255,0.025)') + ';' +
                'transition:border-color 0.15s;'
            );
            var preview = mk('div',
                'width:20px;height:20px;border-radius:50%;flex-shrink:0;' +
                'background:conic-gradient(' + bg + ' 0deg 180deg,' + accent + ' 180deg 360deg);' +
                'border:1px solid rgba(255,255,255,0.12);'
            );
            var lbl = mk('span', 'font-size:10px;font-weight:700;color:' + (isAct ? '#fff' : '#555') + ';', name);
            card.appendChild(preview);
            card.appendChild(lbl);
            card.onclick = function () { applyTheme(key); p.remove(); };
            themeGrid.appendChild(card);
        });
        p.appendChild(themeGrid);
        p.appendChild(secLabel(T[LANG].charSection));
        var currentChar = localStorage.getItem('yt-character') || 'snoopy';
        var charGrid = mk('div', 'display:grid;grid-template-columns:repeat(4,1fr);gap:5px;margin-bottom:4px;');
        var charKeys = ['snoopy', 'pikachu', 'kirby', 'cat', 'alien', 'rocket', 'ghost', 'star'];
        charKeys.forEach(function (ck) {
            var isAct = ck === currentChar;
            var card = mk('div',
                'display:flex;flex-direction:column;align-items:center;gap:4px;padding:7px 3px;border-radius:8px;cursor:pointer;' +
                'border:1px solid ' + (isAct ? 'rgba(255,255,255,0.35)' : 'rgba(255,255,255,0.07)') + ';' +
                'background:' + (isAct ? 'rgba(255,255,255,0.09)' : 'rgba(255,255,255,0.02)') + ';'
            );
            var svgWrap = mk('div', 'width:30px;height:30px;display:flex;align-items:center;justify-content:center;');
            svgWrap.innerHTML = getSVG(ck);
            var name = mk('span', 'font-size:8px;font-weight:700;color:' + (isAct ? '#fff' : '#444') + ';white-space:nowrap;', T[LANG].characters[ck]);
            card.appendChild(svgWrap);
            card.appendChild(name);
            card.onclick = function () {
                localStorage.setItem('yt-character', ck);
                var old = document.getElementById('yt-char-el');
                if (old) old.remove();
                p.remove();
                openPanel();
            };
            charGrid.appendChild(card);
        });
        p.appendChild(charGrid);
        p.appendChild(secLabel(T[LANG].trailSection));
        var trailGrid = mk('div', 'display:grid;grid-template-columns:repeat(5,1fr);gap:5px;margin-bottom:4px;');
        var currentTrail = getSetting('trail-color', 'gold');
        Object.keys(TRAIL_COLORS).forEach(function (key) {
            var isAct = key === currentTrail;
            var swatch;
            if (key === 'none') {
                swatch = mk('div', 'width:22px;height:22px;border-radius:50%;border:1px dashed #555;display:flex;align-items:center;justify-content:center;color:#555;font-size:11px;', 'x');
            } else if (key === 'rainbow') {
                swatch = mk('div', 'width:22px;height:22px;border-radius:50%;background:conic-gradient(red,orange,yellow,green,cyan,blue,violet,red);');
            } else {
                swatch = mk('div', 'width:22px;height:22px;border-radius:50%;background:' + TRAIL_COLORS[key] + ';');
            }
            var card = mk('div',
                'display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 2px;border-radius:8px;cursor:pointer;' +
                'border:1px solid ' + (isAct ? 'rgba(255,255,255,0.35)' : 'rgba(255,255,255,0.07)') + ';' +
                'background:' + (isAct ? 'rgba(255,255,255,0.09)' : 'rgba(255,255,255,0.02)') + ';'
            );
            card.appendChild(swatch);
            card.onclick = function () {
                setSetting('trail-color', key);
                updateTrail();
                p.remove();
                openPanel();
            };
            trailGrid.appendChild(card);
        });
        p.appendChild(trailGrid);
        p.appendChild(secLabel(T[LANG].featSection));
        var featKeys = ['loop', 'character', 'trail', 'label', 'scroll', 'pip', 'speed', 'cinema', 'timestamp', 'autoQuality', 'subtitleStyle', 'chapterJump', 'clipSave', 'miniPlayerDrag'];
        var featContainer = mk('div', 'display:flex;flex-direction:column;gap:4px;margin-bottom:8px;');
        featKeys.forEach(function (key) {
            var row = mk('div',
                'display:flex;align-items:center;justify-content:space-between;' +
                'padding:8px 10px;border-radius:8px;cursor:pointer;' +
                'background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.055);' +
                'transition:background 0.15s;'
            );
            row.onmouseenter = function () { row.style.background = 'rgba(255,255,255,0.06)'; };
            row.onmouseleave = function () { row.style.background = 'rgba(255,255,255,0.03)'; };
            var name = mk('span', 'font-size:11px;font-weight:600;color:#aaa;', T[LANG].features[key]);
            var toggle = buildToggle(getFeature(key));
            row.appendChild(name);
            row.appendChild(toggle);
            row.onclick = function () {
                var newVal = !getFeature(key);
                setFeature(key, newVal);
                toggle.querySelector('.yt-toggle-thumb').style.transform = newVal ? 'translateX(15px)' : 'translateX(0)';
                toggle.querySelector('.yt-toggle-track').style.background = newVal ? '#4a90d9' : '#2a2a3a';
                applyFeatures();
            };
            featContainer.appendChild(row);
        });
        p.appendChild(featContainer);
        p.appendChild(secLabel(T[LANG].shortcutSection));
        var scWrap = mk('div', 'display:flex;flex-direction:column;gap:3px;margin-bottom:6px;');
        T[LANG].shortcutsList.forEach(function (pair) {
            var row = mk('div', 'display:flex;align-items:center;justify-content:space-between;padding:4px 6px;');
            row.appendChild(mk('span', 'font-size:10px;color:#666;', pair[1]));
            row.appendChild(mk('span', 'font-size:9px;font-weight:800;color:#4a90d9;letter-spacing:0.3px;', pair[0]));
            scWrap.appendChild(row);
        });
        p.appendChild(scWrap);
        var notesRow = mk('div',
            'display:flex;align-items:center;justify-content:center;' +
            'padding:8px 10px;border-radius:8px;cursor:pointer;margin-bottom:6px;' +
            'background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.055);' +
            'font-size:11px;font-weight:700;color:#555;letter-spacing:0.5px;',
            T[LANG].clipPanelTitle
        );
        notesRow.onmouseenter = function () { notesRow.style.color = '#aaa'; };
        notesRow.onmouseleave = function () { notesRow.style.color = '#555'; };
        notesRow.onclick = function () { p.remove(); openNotesPanel(); };
        p.appendChild(notesRow);
        var divider = mk('div', 'border-top:1px solid #191926;margin-bottom:8px;');
        p.appendChild(divider);
        var langRow = mk('div',
            'display:flex;align-items:center;justify-content:center;' +
            'padding:8px 10px;border-radius:8px;cursor:pointer;' +
            'background:rgba(255,255,255,0.03);border:1px solid rgba(255,255,255,0.055);' +
            'font-size:11px;font-weight:700;color:#555;letter-spacing:0.5px;',
            T[LANG].langBtn
        );
        langRow.onmouseenter = function () { langRow.style.color = '#aaa'; };
        langRow.onmouseleave = function () { langRow.style.color = '#555'; };
        langRow.onclick = function () {
            localStorage.setItem('yt-lang', LANG === 'tr' ? 'en' : 'tr');
            location.reload();
        };
        p.appendChild(langRow);
        var hint = mk('div', 'text-align:center;color:#252535;font-size:9px;font-weight:700;margin-top:8px;letter-spacing:1px;', T[LANG].shortcut);
        p.appendChild(hint);
        document.body.appendChild(p);
        requestAnimationFrame(function () {
            document.addEventListener('mousedown', function outsideClick(e) {
                if (!p.contains(e.target) && e.target.id !== 'yt-premium-label') {
                    p.remove();
                    document.removeEventListener('mousedown', outsideClick);
                }
            });
        });
    }
    function applyFeatures() {
        addLabel();
        addLoopButton();
        addPipButton();
        addSpeedSelector();
        addTimestampButton();
        applyCinemaMode();
        applySubtitleStyle();
        enableScrollVolume();
        if (!getFeature('character')) {
            var ch = document.getElementById('yt-char-el');
            if (ch) ch.remove();
            stopCharLoop();
        }
        if (!getFeature('trail')) {
            var tr = document.getElementById('yt-trail-el');
            if (tr) tr.remove();
        }
    }
    function isTypingTarget(el) {
        if (!el) return false;
        var tag = el.tagName ? el.tagName.toLowerCase() : '';
        if (tag === 'input' || tag === 'textarea' || tag === 'select') return true;
        if (el.isContentEditable) return true;
        return false;
    }
    document.addEventListener('keydown', function (e) {
        if (!(e.ctrlKey && e.shiftKey)) return;
        if (isTypingTarget(e.target)) return;
        var key = e.key.toLowerCase();
        if (key === 'd') {
            e.preventDefault();
            openPanel();
        } else if (key === 'l') {
            e.preventDefault();
            toggleLoop();
        } else if (key === 'c') {
            e.preventDefault();
            copyTimestamp();
        } else if (key === ',') {
            e.preventDefault();
            jumpChapter(-1);
        } else if (key === '.') {
            e.preventDefault();
            jumpChapter(1);
        } else if (key === 'k') {
            e.preventDefault();
            quickSaveNote();
        }
    });
    function init() {
        applyTheme(THEME);
        applyFeatures();
        injectCharacter();
    }
    setTimeout(init, 1200);
    setInterval(function () {
        injectCharacter();
        addLabel();
        addLoopButton();
        addPipButton();
        addSpeedSelector();
        addTimestampButton();
        applyCinemaMode();
        applySubtitleStyle();
        enableScrollVolume();
        applyAutoQuality();
        updateTrail();
    }, 800);
    window.addEventListener('resize', positionCharacter);
    document.addEventListener('fullscreenchange', function () {
        setTimeout(positionCharacter, 50);
    });
    document.addEventListener('timeupdate', function (e) {
        if (e.target && e.target.tagName === 'VIDEO') {
            updateTrail();
        }
    }, true);
    new MutationObserver(function () {
        setTimeout(function () {
            addLabel();
            addLoopButton();
            addPipButton();
            addSpeedSelector();
            addTimestampButton();
            injectCharacter();
            applySubtitleStyle();
            applyAutoQuality();
        }, 400);
    }).observe(document.body, { childList: true, subtree: false });
})();