YouTube tema, ozellik ve oynatici yoneticisi (reklam engelleme icermez)
// ==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 });
})();