🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

YouTube All-in-One: Premium Logo, HD, Downloader & Telegram (Stable)

Combines Premium Logo, HD quality lock, Native Downloader, Settings Menu, and replaces "Thanks" with a Telegram link. Fixed freezing issues.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==UserScript==
// @name         YouTube All-in-One: Premium Logo, HD, Downloader & Telegram (Stable)
// @name:ru      YouTube Всё-в-одном: Premium Лого, HD, Скачивание и Телеграм (Стабильный)
// @namespace    electroknight22_youhou_premium_logo_telegram_v13
// @version      2025.1.13
// @description  Combines Premium Logo, HD quality lock, Native Downloader, Settings Menu, and replaces "Thanks" with a Telegram link. Fixed freezing issues.
// @description:ru Исправлены фризы и ошибки 500. Меняет лого на Premium, фиксирует HD (без спама), добавляет скачивание и ссылку на Telegram.
// @author       Evreu1pro
// @match        *://www.youtube.com/*
// @match        *://m.youtube.com/*
// @match        *://www.youtube-nocookie.com/*
// @exclude      *://www.youtube.com/live_chat*
// @grant        GM_addStyle
// @run-at       document-idle
// @license      MIT
// @icon         https://www.youtube.com/s/desktop/2731d6a3/img/favicon_48x48.png
// ==/UserScript==

(function () {
    'use strict';

    // ==========================================
    // ЧАСТЬ 1: ПРЕМИУМ ЛОГОТИП (CSS)
    // ==========================================
    const premiumLogoCSS = `
        #logo-container .logo, .footer-logo-icon, #logo-icon, #logo-icon-container {
            width: 98px !important; margin-left: 5px; margin-right: 5px;
            content: url("data:image/svg+xml,%3Csvg xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:cc='http://creativecommons.org/ns%23' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns%23' xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg' id='SVGRoot' version='1.1' viewBox='0 0 846 174' height='80px' width='391px'%3E%3Cdefs id='defs855'%3E%3Cstyle id='style2' /%3E%3C/defs%3E%3Cg id='layer1'%3E%3Cg transform='translate(0,0.36)' data-name='Layer 2' id='Layer_2'%3E%3Cg data-name='Layer 1' id='Layer_1-2'%3E%3Cpath style='fill:%23ff0000' id='path6' d='M 242.88,27.11 A 31.07,31.07 0 0 0 220.95,5.18 C 201.6,0 124,0 124,0 124,0 46.46,0 27.11,5.18 A 31.07,31.07 0 0 0 5.18,27.11 C 0,46.46 0,86.82 0,86.82 c 0,0 0,40.36 5.18,59.71 a 31.07,31.07 0 0 0 21.93,21.93 c 19.35,5.18 96.92,5.18 96.92,5.18 0,0 77.57,0 96.92,-5.18 a 31.07,31.07 0 0 0 21.93,-21.93 c 5.18,-19.35 5.18,-59.71 5.18,-59.71 0,0 0,-40.36 -5.18,-59.71 z' /%3E%3Cpath style='fill:%23ffffff' id='path8' d='M 99.22,124.03 163.67,86.82 99.22,49.61 Z' /%3E%3Cpath style='fill:%23282828' id='path10' d='m 358.29,55.1 v 6 c 0,30 -13.3,47.53 -42.39,47.53 h -4.43 v 52.5 H 287.71 V 12.36 H 318 c 27.7,0 40.29,11.71 40.29,42.74 z m -25,2.13 c 0,-21.64 -3.9,-26.78 -17.38,-26.78 h -4.43 v 60.48 h 4.08 c 12.77,0 17.74,-9.22 17.74,-29.26 z m 81.22,-6.56 -1.24,28.2 c -10.11,-2.13 -18.45,-0.53 -22.17,6 v 76.26 H 367.52 V 52.44 h 18.8 L 388.45,76 h 0.89 c 2.48,-17.2 10.46,-25.89 20.75,-25.89 a 22.84,22.84 0 0 1 4.42,0.56 z M 441.64,115 v 5.5 c 0,19.16 1.06,25.72 9.22,25.72 7.8,0 9.58,-6 9.75,-18.44 l 21.1,1.24 c 1.6,23.41 -10.64,33.87 -31.39,33.87 -25.18,0 -32.63,-16.49 -32.63,-46.46 v -19 c 0,-31.57 8.34,-47 33.34,-47 25.18,0 31.57,13.12 31.57,45.93 V 115 Z m 0,-22.35 v 7.8 h 17.91 V 92.7 c 0,-20 -1.42,-25.72 -9,-25.72 -7.58,0 -8.91,5.86 -8.91,25.72 z M 604.45,79 v 82.11 H 580 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8.16,2.48 -10.82,7.09 a 35.59,35.59 0 0 1 0.18,4.43 v 82.11 H 537.24 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8,2.48 -10.64,6.92 v 86.72 H 494.5 V 52.44 h 19.33 L 516,66.28 h 0.35 c 5.5,-10.46 14.37,-16.14 24.83,-16.14 10.29,0 16.14,5.14 18.8,14.37 5.68,-9.4 14.19,-14.37 23.94,-14.37 14.86,0 20.53,10.64 20.53,28.86 z m 12.24,-54.4 c 0,-11.71 4.26,-15.07 13.3,-15.07 9.22,0 13.3,3.9 13.3,15.07 0,12.06 -4.08,15.08 -13.3,15.08 -9.04,-0.01 -13.3,-3.02 -13.3,-15.08 z m 1.42,27.84 h 23.41 v 108.72 h -23.41 z m 103.39,0 v 108.72 h -19.15 l -2.13,-13.3 h -0.53 c -5.5,10.64 -13.48,15.07 -23.41,15.07 -14.54,0 -21.11,-9.22 -21.11,-29.26 V 52.44 h 24.47 v 79.81 c 0,9.58 2,13.48 6.92,13.48 A 12.09,12.09 0 0 0 697,138.81 V 52.44 Z M 845.64,79 v 82.11 H 821.17 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8.16,2.48 -10.82,7.09 A 35.59,35.59 0 0 1 802.9,79 v 82.11 H 778.43 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8,2.48 -10.64,6.92 v 86.72 H 735.69 V 52.44 H 755 l 2.13,13.83 h 0.35 c 5.5,-10.46 14.37,-16.14 24.83,-16.14 10.29,0 16.14,5.14 18.8,14.37 5.68,-9.4 14.19,-14.37 23.94,-14.37 14.95,0.01 20.59,10.65 20.59,28.87 z' /%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E") !important;
        }
        html[dark] #logo-icon, html[dark] #logo-icon-container {
            width: 98px !important;
            content: url("data:image/svg+xml,%3Csvg xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:cc='http://creativecommons.org/ns%23' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns%23' xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg' id='SVGRoot' version='1.1' viewBox='0 0 846 174' height='24px' width='98px'%3E%3Cdefs id='defs855'%3E%3Cstyle id='style2' /%3E%3C/defs%3E%3Cg id='layer1'%3E%3Cg transform='translate(0,0.36)' data-name='Layer 2' id='Layer_2'%3E%3Cg data-name='Layer 1' id='Layer_1-2'%3E%3Cpath style='fill:%23ff0000' id='path6' d='M 242.88,27.11 A 31.07,31.07 0 0 0 220.95,5.18 C 201.6,0 124,0 124,0 124,0 46.46,0 27.11,5.18 A 31.07,31.07 0 0 0 5.18,27.11 C 0,46.46 0,86.82 0,86.82 c 0,0 0,40.36 5.18,59.71 a 31.07,31.07 0 0 0 21.93,21.93 c 19.35,5.18 96.92,5.18 96.92,5.18 0,0 77.57,0 96.92,-5.18 a 31.07,31.07 0 0 0 21.93,-21.93 c 5.18,-19.35 5.18,-59.71 5.18,-59.71 0,0 0,-40.36 -5.18,-59.71 z' /%3E%3Cpath style='fill:%23ffffff' id='path8' d='M 99.22,124.03 163.67,86.82 99.22,49.61 Z' /%3E%3Cpath style='fill:%23ffffff' id='path10' d='m 358.29,55.1 v 6 c 0,30 -13.3,47.53 -42.39,47.53 h -4.43 v 52.5 H 287.71 V 12.36 H 318 c 27.7,0 40.29,11.71 40.29,42.74 z m -25,2.13 c 0,-21.64 -3.9,-26.78 -17.38,-26.78 h -4.43 v 60.48 h 4.08 c 12.77,0 17.74,-9.22 17.74,-29.26 z m 81.22,-6.56 -1.24,28.2 c -10.11,-2.13 -18.45,-0.53 -22.17,6 v 76.26 H 367.52 V 52.44 h 18.8 L 388.45,76 h 0.89 c 2.48,-17.2 10.46,-25.89 20.75,-25.89 a 22.84,22.84 0 0 1 4.42,0.56 z M 441.64,115 v 5.5 c 0,19.16 1.06,25.72 9.22,25.72 7.8,0 9.58,-6 9.75,-18.44 l 21.1,1.24 c 1.6,23.41 -10.64,33.87 -31.39,33.87 -25.18,0 -32.63,-16.49 -32.63,-46.46 v -19 c 0,-31.57 8.34,-47 33.34,-47 25.18,0 31.57,13.12 31.57,45.93 V 115 Z m 0,-22.35 v 7.8 h 17.91 V 92.7 c 0,-20 -1.42,-25.72 -9,-25.72 -7.58,0 -8.91,5.86 -8.91,25.72 z M 604.45,79 v 82.11 H 580 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8.16,2.48 -10.82,7.09 a 35.59,35.59 0 0 1 0.18,4.43 v 82.11 H 537.24 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8,2.48 -10.64,6.92 v 86.72 H 494.5 V 52.44 h 19.33 L 516,66.28 h 0.35 c 5.5,-10.46 14.37,-16.14 24.83,-16.14 10.29,0 16.14,5.14 18.8,14.37 5.68,-9.4 14.19,-14.37 23.94,-14.37 14.86,0 20.53,10.64 20.53,28.86 z m 12.24,-54.4 c 0,-11.71 4.26,-15.07 13.3,-15.07 9.22,0 13.3,3.9 13.3,15.07 0,12.06 -4.08,15.08 -13.3,15.08 -9.04,-0.01 -13.3,-3.02 -13.3,-15.08 z m 1.42,27.84 h 23.41 v 108.72 h -23.41 z m 103.39,0 v 108.72 h -19.15 l -2.13,-13.3 h -0.53 c -5.5,10.64 -13.48,15.07 -23.41,15.07 -14.54,0 -21.11,-9.22 -21.11,-29.26 V 52.44 h 24.47 v 79.81 c 0,9.58 2,13.48 6.92,13.48 A 12.09,12.09 0 0 0 697,138.81 V 52.44 Z M 845.64,79 v 82.11 H 821.17 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8.16,2.48 -10.82,7.09 A 35.59,35.59 0 0 1 802.9,79 v 82.11 H 778.43 V 80.82 c 0,-8.87 -2.31,-13.3 -7.63,-13.3 -4.26,0 -8,2.48 -10.64,6.92 v 86.72 H 735.69 V 52.44 H 755 l 2.13,13.83 h 0.35 c 5.5,-10.46 14.37,-16.14 24.83,-16.14 10.29,0 16.14,5.14 18.8,14.37 5.68,-9.4 14.19,-14.37 23.94,-14.37 14.95,0.01 20.59,10.65 20.59,28.87 z' /%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E") !important;
        }
    `;

    if (typeof GM_addStyle === 'function') {
        GM_addStyle(premiumLogoCSS);
    } else {
        const style = document.createElement('style');
        style.textContent = premiumLogoCSS;
        document.head.append(style);
    }

    // ==========================================
    // ЧАСТЬ 2: ХРАНИЛИЩЕ И УТИЛИТЫ
    // ==========================================
    const PREF_KEY = 'yt_target_quality_v13';

    const Storage = {
        get: (key, def) => localStorage.getItem(key) || def,
        set: (key, val) => localStorage.setItem(key, val)
    };

    const safeEmpty = (element) => {
        while (element.firstChild) element.removeChild(element.firstChild);
    };

    const createSVG = (dPath) => {
        const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        svg.setAttribute("height", "24");
        svg.setAttribute("width", "24");
        svg.setAttribute("viewBox", "0 0 24 24");
        svg.setAttribute("fill", "currentColor");
        const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
        path.setAttribute("d", dPath);
        svg.appendChild(path);
        return svg;
    };

    const createElem = (tag, className, text = null) => {
        const el = document.createElement(tag);
        if (className) el.className = className;
        if (text) el.textContent = text;
        return el;
    };

    const ICONS_PATHS = {
        pin: "M16,12V4H17V2H7V4H8V12L6,14V16H11.5V22H12.5V16H18V14L16,12Z",
        check: "M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z",
        back: "M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z",
        download: "M17 18v1H6v-1h11zm-.5-6.6-.7-.7-3.8 3.7V4h-1v10.4l-3.8-3.8-.7.7 5 5 5-4.9z",
        telegram: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4.64 6.8c-.15 1.58-.8 5.42-1.13 7.19-.14.75-.42 1-.68 1.03-.58.05-1.02-.38-1.58-.75-.88-.58-1.38-.94-2.23-1.5-.99-.65-.35-1.01.22-1.59.15-.15 2.71-2.48 2.76-2.69.01-.03.01-.14-.07-.2-.08-.06-.19-.04-.27-.02-.12.02-1.96 1.25-5.54 3.69-.52.36-1 .53-1.42.52-.47-.01-1.37-.26-2.03-.48-.82-.27-1.47-.42-1.42-.88.03-.24.29-.48.79-.74 3.08-1.34 5.15-2.23 6.21-2.66 2.95-1.23 3.56-1.43 3.97-1.43.09 0 .28.02.41.12.13.1.16.23.17.38z",
        thanks: "M16.25 2"
    };

    const I18N = {
        'en': { download: 'Download', quality: 'Preferred Quality', scripts: 'Scripts' },
        'ru': { download: 'Скачать', quality: 'Качество видео', scripts: 'Скрипты' },
        'de': { download: 'Herunterladen', quality: 'Videoqualität', scripts: 'Skripte' },
        'es': { download: 'Descargar', quality: 'Calidad preferida', scripts: 'Scripts' },
        'fr': { download: 'Télécharger', quality: 'Qualité préférée', scripts: 'Scripts' },
        'ja': { download: 'ダウンロード', quality: '希望する画質', scripts: 'スクリプト' },
        'zh': { download: '下载', quality: '首选画质', scripts: '脚本' },
        'uk': { download: 'Завантажити', quality: 'Бажана якість', scripts: 'Скрипти' }
    };

    function getLang() {
        const code = document.documentElement.lang || navigator.language || 'en';
        return I18N[code.split('-')[0]] || I18N['en'];
    }

    const QUALITY_LEVELS = {
        'highres': 'Max (4K/8K)',
        'hd2160': '2160p (4K)',
        'hd1440': '1440p (2K)',
        'hd1080': '1080p (HD)',
        'hd720': '720p',
        'large': '480p',
        'medium': '360p'
    };

    // ==========================================
    // ЧАСТЬ 3: МОДУЛЬ HD (БЕЗ ФРИЗОВ)
    // ==========================================
    let hasQualityBeenSet = false; // Флаг: ставили ли уже качество для этого видео

    function forceVideoQuality(isManual = false) {
        const player = document.getElementById('movie_player');
        if (!player || typeof player.setPlaybackQualityRange !== 'function') return;

        // Если автоматика уже сработала один раз, не трогаем плеер, чтобы не сбивать буфер
        if (!isManual && hasQualityBeenSet) return;

        try {
            const target = Storage.get(PREF_KEY, 'highres');
            const available = player.getAvailableQualityLevels();
            if (!available || !available.length) return;

            let targetQualityVal = (target === 'highres') ? available[0] : target;
            if (!available.includes(targetQualityVal)) targetQualityVal = available[0];

            const currentQuality = player.getPlaybackQuality();
            
            // Применяем только если отличается
            if (currentQuality !== targetQualityVal || isManual) {
                console.log(`[YouTube Script] Setting quality to: ${targetQualityVal}`);
                player.setPlaybackQualityRange(targetQualityVal, targetQualityVal);
                player.setPlaybackQuality(targetQualityVal);
                hasQualityBeenSet = true; 
            }
        } catch (e) {
            console.warn('[YouTube Script] Error setting quality', e);
        }
    }

    function initHDLogic() {
        // Сбрасываем флаг при смене видео
        let lastUrl = location.href;
        new MutationObserver(() => {
            const url = location.href;
            if (url !== lastUrl) {
                lastUrl = url;
                hasQualityBeenSet = false; // Новое видео - можно один раз поставить качество
            }
        }).observe(document, {subtree: true, childList: true});

        const observer = new MutationObserver(() => {
            const player = document.getElementById('movie_player');
            if (player) {
                if (!player.dataset.qualityLocked) {
                    player.addEventListener('onStateChange', (state) => {
                        // 1 = playing. Мы больше НЕ слушаем state === 3 (buffering), чтобы не вызывать петлю.
                        if (state === 1) {
                            setTimeout(() => forceVideoQuality(), 500);
                        }
                    });
                    player.dataset.qualityLocked = "true";
                }
                // Первая попытка при загрузке
                setTimeout(() => forceVideoQuality(), 1500);
            }
        });
        observer.observe(document.body, { childList: true, subtree: true });
    }

    // ==========================================
    // ЧАСТЬ 4: ИНТЕГРАЦИЯ В МЕНЮ
    // ==========================================
    function injectSettingsMenu() {
        document.addEventListener('click', (e) => {
            const settingsBtn = e.target.closest('.ytp-settings-button');
            if (settingsBtn) {
                setTimeout(addMenuItem, 50);
                setTimeout(addMenuItem, 500); 
            }
        }, true);
    }

    function addMenuItem() {
        const menu = document.querySelector('.ytp-settings-menu .ytp-panel-menu');
        if (!menu || document.getElementById('yt-pref-quality-item')) return;

        const lang = getLang();
        const currentVal = Storage.get(PREF_KEY, 'highres');
        const currentLabel = QUALITY_LEVELS[currentVal] || currentVal;

        const menuItem = createElem('div', 'ytp-menuitem');
        menuItem.id = 'yt-pref-quality-item';
        menuItem.setAttribute('role', 'menuitem');
        menuItem.setAttribute('tabindex', '0');

        const iconDiv = createElem('div', 'ytp-menuitem-icon');
        iconDiv.appendChild(createSVG(ICONS_PATHS.pin));

        const labelDiv = createElem('div', 'ytp-menuitem-label', lang.quality);
        const contentDiv = createElem('div', 'ytp-menuitem-content');
        const valueDiv = createElem('div', 'ytp-menuitem-value', currentLabel);
        contentDiv.appendChild(valueDiv);

        menuItem.appendChild(iconDiv);
        menuItem.appendChild(labelDiv);
        menuItem.appendChild(contentDiv);
        menuItem.onclick = () => openSubMenu(menu);

        if (menu.firstChild) menu.insertBefore(menuItem, menu.children[1] || menu.firstChild);
        else menu.appendChild(menuItem);
        
        const panel = menu.closest('.ytp-panel');
        if (panel) panel.style.height = ''; 
    }

    function openSubMenu(mainMenu) {
        const panel = mainMenu.closest('.ytp-panel');
        if (!panel) return;

        mainMenu.style.display = 'none';
        let subMenu = document.getElementById('yt-pref-quality-submenu');
        if (subMenu) safeEmpty(subMenu);
        else {
            subMenu = createElem('div', 'ytp-panel-menu');
            subMenu.id = 'yt-pref-quality-submenu';
            panel.appendChild(subMenu);
        }
        subMenu.style.display = 'block';

        const header = createElem('div', 'ytp-panel-header');
        header.style.cssText = 'padding: 10px 0; border-bottom: 1px solid rgba(255,255,255,0.1); display: flex; align-items: center; cursor: pointer;';
        
        const titleDiv = createElem('div', 'ytp-panel-title');
        titleDiv.style.display = 'flex'; titleDiv.style.alignItems = 'center';
        const backIconSpan = createElem('span');
        backIconSpan.style.marginRight = '10px';
        backIconSpan.appendChild(createSVG(ICONS_PATHS.back));
        titleDiv.appendChild(backIconSpan);
        titleDiv.appendChild(document.createTextNode(getLang().quality));
        header.appendChild(titleDiv);

        header.onclick = () => {
            subMenu.style.display = 'none'; mainMenu.style.display = 'block'; subMenu.remove();
            const currentVal = Storage.get(PREF_KEY, 'highres');
            const itemValue = document.querySelector('#yt-pref-quality-item .ytp-menuitem-value');
            if (itemValue) itemValue.textContent = QUALITY_LEVELS[currentVal];
        };
        subMenu.appendChild(header);

        const currentVal = Storage.get(PREF_KEY, 'highres');
        Object.keys(QUALITY_LEVELS).forEach(key => {
            const option = createElem('div', 'ytp-menuitem');
            option.setAttribute('role', 'menuitemradio'); option.setAttribute('tabindex', '0');
            const isChecked = currentVal === key;
            option.setAttribute('aria-checked', isChecked);
            const label = createElem('div', 'ytp-menuitem-label', QUALITY_LEVELS[key]);
            label.style.paddingLeft = '15px';
            const content = createElem('div', 'ytp-menuitem-content');
            if (isChecked) content.appendChild(createSVG(ICONS_PATHS.check));
            option.appendChild(label); option.appendChild(content);
            option.onclick = () => { 
                Storage.set(PREF_KEY, key); 
                forceVideoQuality(true); // Manual override
                header.click(); 
            };
            subMenu.appendChild(option);
        });
        panel.style.height = `${subMenu.scrollHeight}px`;
    }

    // ==========================================
    // ЧАСТЬ 5: МОДУЛЬ КНОПОК (СКАЧАТЬ И TELEGRAM)
    // ==========================================
    function getDownloadUrl() { return window.location.href.replace('youtube.com', 'addyoutube.com'); }

    function modifyButton(buttonElement, type) {
        const lang = getLang();
        buttonElement.onclick = (e) => {
            e.preventDefault(); e.stopPropagation();
            if (type === 'download') window.open(getDownloadUrl(), '_blank');
            if (type === 'telegram') window.open('https://t.me/gostibissi', '_blank');
        };

        const svg = buttonElement.querySelector('svg');
        if (svg) {
            safeEmpty(svg);
            const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
            path.setAttribute("d", type === 'download' ? ICONS_PATHS.download : ICONS_PATHS.telegram);
            path.setAttribute("fill", "currentColor");
            svg.appendChild(path);
        }

        const textSpan = buttonElement.querySelector('yt-formatted-string') || 
                         buttonElement.querySelector('.yt-spec-button-shape-next__button-text-content span');
        if (textSpan) textSpan.textContent = type === 'download' ? lang.download : lang.scripts;

        const tooltip = buttonElement.closest(type === 'download' ? 'ytd-download-button-renderer' : 'ytd-button-renderer, yt-button-view-model')?.querySelector('tp-yt-paper-tooltip');
        if (tooltip && tooltip.textContent) tooltip.textContent = type === 'download' ? lang.download : lang.scripts;

        const anchor = buttonElement.querySelector('a');
        if (anchor) { anchor.removeAttribute('href'); anchor.removeAttribute('target'); }
    }

    function processButtons() {
        // 1. Download Button
        const nativeDownload = document.querySelector('ytd-download-button-renderer');
        if (nativeDownload) {
            if (nativeDownload.dataset.replaced !== "true") {
                const originalButton = nativeDownload.querySelector('button');
                if (originalButton) {
                    const newButton = originalButton.cloneNode(true);
                    modifyButton(newButton, 'download');
                    originalButton.parentNode.replaceChild(newButton, originalButton);
                    nativeDownload.dataset.replaced = "true";
                }
            }
        } else {
            if (!document.getElementById('custom-download-btn')) createCustomButton('download');
        }

        // 2. Telegram Button (Replace Thanks or Add New)
        const buttonsContainer = document.querySelector('#top-level-buttons-computed');
        if (!buttonsContainer) return;
        
        let thanksButton = null;
        
        // ПОИСК: Ищем среди всех возможных контейнеров кнопок (включая новые view-model)
        const candidates = buttonsContainer.querySelectorAll('ytd-button-renderer, yt-button-view-model');
        
        for (const btn of candidates) {
            // Проверка по иконке
            const path = btn.querySelector('path');
            if (path && path.getAttribute('d') && path.getAttribute('d').startsWith(ICONS_PATHS.thanks)) {
                thanksButton = btn;
                break;
            }
        }

        if (thanksButton && thanksButton.dataset.replaced !== "true") {
            // Замена
            const newTelegram = thanksButton.cloneNode(true);
            const innerBtn = newTelegram.querySelector('button');
            if (innerBtn) modifyButton(innerBtn, 'telegram');
            
            thanksButton.parentNode.replaceChild(newTelegram, thanksButton);
            newTelegram.dataset.replaced = "true";
        } else if (!thanksButton && !document.getElementById('custom-telegram-btn')) {
            // Если кнопки Спасибо нет вообще, добавляем свою
            createCustomButton('telegram');
        }
    }

    function createCustomButton(type) {
        const id = type === 'download' ? 'custom-download-btn' : 'custom-telegram-btn';
        if (document.getElementById(id)) return;

        const menuRenderer = document.querySelector('ytd-menu-renderer');
        if (!menuRenderer) return;
        
        const baseButton = menuRenderer.querySelector('ytd-button-renderer button') || 
                           menuRenderer.querySelector('yt-button-view-model button');
        if (!baseButton) return;

        const buttonRenderer = baseButton.closest('ytd-button-renderer') || baseButton.closest('yt-button-view-model');
        const newRenderer = buttonRenderer.cloneNode(true);
        newRenderer.id = id;
        const innerBtn = newRenderer.querySelector('button');
        if(innerBtn) modifyButton(innerBtn, type);

        const buttonsContainer = menuRenderer.querySelector('#top-level-buttons-computed');
        if (buttonsContainer) {
            buttonsContainer.appendChild(newRenderer);
        }
    }

    function initButtons() {
        const observer = new MutationObserver(() => {
            if (window.location.pathname.includes('/watch')) {
                processButtons();
            }
        });
        observer.observe(document.body, { childList: true, subtree: true });
        if (window.location.pathname.includes('/watch')) {
            setTimeout(processButtons, 1000); setTimeout(processButtons, 3000);
        }
    }

    // --- ЗАПУСК ---
    initHDLogic();
    initButtons();
    injectSettingsMenu();

})();