XButtonx

calc umur, auto reload, hapus Ads, darkmode

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         XButtonx
// @namespace    http://tampermonkey.net/
// @version      1.6
// @description  calc umur, auto reload, hapus Ads, darkmode
// @author       xkhd
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // --- Floating main button ---
    const floatingBtn = document.createElement('div');
    floatingBtn.style.cssText = `
        position: fixed; bottom: 60px; right: 60px;
        width: 60px; height: 60px; border-radius: 50%;
        overflow: hidden; z-index: 9999; cursor: pointer;
        border: 3px solid #007bff; background: #fff;
        display: flex; align-items: center; justify-content: center;
        transition: transform 0.3s ease; box-shadow: 0 4px 8px rgba(0,0,0,0.3);
    `;
    const iconImg = document.createElement('img');
    iconImg.src = 'https://lh3.googleusercontent.com/a/AGNmyxaEnKjzfKogUt2-V-11G5OAQMl0OZKBz7562IzJ=s96-c';
    iconImg.style.cssText = 'width: 100%; height: 100%; object-fit: cover; border-radius: 50%;';
    floatingBtn.appendChild(iconImg);
    document.body.appendChild(floatingBtn);

    // --- Button container (positioned relative to floating button center) ---
    const btnContainer = document.createElement('div');
    // offset to align with floatingBtn center (floatingBtn bottom/right are 60px)
    btnContainer.style.cssText = `
        position: fixed; bottom: 90px; right: 90px;
        width: 0; height: 0; z-index: 9998; pointer-events: none;
    `;
    document.body.appendChild(btnContainer);

    const menuButtons = [];

    // --- Helper: create tooltip element for a button ---
    function makeTooltip(text) {
        const tip = document.createElement('div');
        tip.textContent = text;
        tip.style.cssText = `
            position: absolute;
            bottom: 130%;
            left: 50%;
            transform: translateX(-50%);
            white-space: nowrap;
            padding: 6px 8px;
            background: rgba(0,0,0,0.85);
            color: #fff;
            font-size: 12px;
            border-radius: 6px;
            box-shadow: 0 4px 10px rgba(0,0,0,0.25);
            pointer-events: none;
            opacity: 0;
            transition: opacity 0.18s ease, transform 0.18s ease;
            transform-origin: bottom center;
            z-index: 10001;
        `;
        return tip;
    }

    // --- SVG icons (inline) ---
    const SVG = {
        calc: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                <rect x="3" y="3" width="18" height="18" rx="2" stroke="lime" stroke-width="1.6" fill="#ffffff"/>
                <path d="M7 7h10M7 11h10M7 15h10" stroke="lime" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
               </svg>`,
        reload: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                    <path d="M21 12a9 9 0 10-2.6 6.1L21 21v-4.1" stroke="blue" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                 </svg>`,
        removeAds: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                      <circle cx="12" cy="12" r="8" stroke="red" stroke-width="1.6" fill="#ffffff"/>
                      <path d="M8 8l8 8M16 8l-8 8" stroke="red" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
                   </svg>`,
        dark: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
                 <path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z" stroke="orange" stroke-width="1.4" fill="#ffffff"/>
               </svg>`
    };

    // --- Create a menu button with SVG and tooltip text ---
    function createIconButton(svgHTML, tooltipText, callback) {
        const btn = document.createElement('button');
        btn.innerHTML = svgHTML;
        btn.setAttribute('aria-label', tooltipText);
        btn.style.cssText = `
            position: absolute;
            width: 36px; height: 36px; /* rectangle-ish for nicer alignment */
            display:flex; align-items:center; justify-content:center;
            transform: translate(0px, 0px);
            opacity: 0;
            transition: transform 0.38s cubic-bezier(.2,.9,.2,1), opacity 0.28s ease;
            pointer-events: auto;
            background: transparent;
            border: 2px solid #007bff;
            border-radius: 8px;
            padding: 6px;
            font-size: 13px;
            cursor: pointer;
            box-shadow: 0 2px 6px rgba(0,0,0,0.18);
        `;

        // tooltip
        const tip = makeTooltip(tooltipText);
        btn.appendChild(tip);

        // mouse handlers (use dataset tx,ty that will be set later)
        btn.addEventListener('mouseenter', () => {
            const tx = parseFloat(btn.dataset.tx || 0);
            const ty = parseFloat(btn.dataset.ty || 0);
            btn.style.transform = `translate(${tx}px, ${ty}px) scale(1.08)`;
            btn.style.boxShadow = '0 6px 18px rgba(0,0,0,0.28)';
            tip.style.opacity = '1';
            tip.style.transform = 'translateX(-50%) translateY(-6px)';
        });
        btn.addEventListener('mouseleave', () => {
            const tx = parseFloat(btn.dataset.tx || 0);
            const ty = parseFloat(btn.dataset.ty || 0);
            btn.style.transform = `translate(${tx}px, ${ty}px) scale(1)`;
            btn.style.boxShadow = '0 2px 6px rgba(0,0,0,0.18)';
            tip.style.opacity = '0';
            tip.style.transform = 'translateX(-50%) translateY(0)';
        });

        btn.addEventListener('click', (e) => {
            e.stopPropagation(); // avoid closing menu if needed
            callback && callback(e);
        });

        btnContainer.appendChild(btn);
        menuButtons.push(btn);
        return btn;
    }

    // --- Kalkulator Umur (statis) ---
    function showAgeCalculator() {
        const container = document.createElement('div');
        container.style.cssText = `
            all: initial;
            font-family: Arial, sans-serif;
            font-size: 14px;
            position: fixed; top: 50%; left: 50%;
            transform: translate(-50%, -50%);
            background: #ffffff;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 8px 30px rgba(0,0,0,0.25);
            z-index: 10000; min-width: 300px;
            color: #000000;
        `;
        container.innerHTML = `
            <h3 style="margin:0 0 10px 0; font-size:16px; font-weight:700; color:#222;">Kalkulator Umur</h3>
            <label style="display:block; margin-bottom:6px; color:#333;">Tanggal Lahir:</label>
            <input type="date" id="birthDate" style="padding:8px; width:100%; margin-bottom:12px; border:1px solid #ddd; border-radius:6px;">
            <label style="display:block; margin-bottom:6px; color:#333;">Tanggal Acuan:</label>
            <input type="date" id="refDate" value="${new Date().toISOString().split('T')[0]}" style="padding:8px; width:100%; margin-bottom:12px; border:1px solid #ddd; border-radius:6px;">
            <div style="display:flex; gap:10px; justify-content:space-between; margin-top:8px;">
                <button id="calcBtn" style="flex:1; background:#007bff; color:#fff; padding:8px; border:none; border-radius:6px; cursor:pointer;">Hitung</button>
                <button id="closeBtn" style="flex:1; background:#6c757d; color:#fff; padding:8px; border:none; border-radius:6px; cursor:pointer;">Tutup</button>
            </div>
            <div id="result" style="margin-top:14px; font-weight:700; color:#222;"></div>
        `;

        document.body.appendChild(container);

        container.querySelector('#closeBtn').onclick = () => container.remove();
        container.querySelector('#calcBtn').onclick = () => {
            const birthVal = container.querySelector('#birthDate').value;
            const refVal = container.querySelector('#refDate').value;
            const birth = birthVal ? new Date(birthVal) : NaN;
            const ref = refVal ? new Date(refVal) : NaN;
            if (isNaN(birth) || isNaN(ref)) {
                alert("Mohon masukkan kedua tanggal.");
                return;
            }
            if (ref < birth) {
                alert("Tanggal acuan tidak boleh sebelum tanggal lahir.");
                return;
            }
            const age = calcAge(birth, ref);
            container.querySelector('#result').textContent =
                `${age.years} tahun, ${age.months} bulan, ${age.days} hari`;
        };
    }

    function calcAge(birth, ref) {
        let years = ref.getFullYear() - birth.getFullYear();
        let months = ref.getMonth() - birth.getMonth();
        let days = ref.getDate() - birth.getDate();

        if (days < 0) {
            months--;
            const prevMonth = new Date(ref.getFullYear(), ref.getMonth(), 0);
            days += prevMonth.getDate();
        }
        if (months < 0) {
            years--;
            months += 12;
        }
        return { years, months, days };
    }

    // --- Placeholder Auto Reload ---
    function showAutoReloadPopup() {
        // Example implementation: simple popup with interval in minutes (you can extend)
        const container = document.createElement('div');
        container.style.cssText = `
            all: initial;
            font-family: Arial, sans-serif;
            font-size: 14px;
            position: fixed; top: 50%; left: 50%;
            transform: translate(-50%, -50%);
            background: #fff;
            padding: 16px;
            border-radius: 10px;
            box-shadow: 0 8px 30px rgba(0,0,0,0.25);
            z-index: 10000; min-width: 280px;
            color: #000;
        `;
        container.innerHTML = `
            <h3 style="margin:0 0 10px 0; font-size:16px; color:#222;">Auto Reload</h3>
            <label style="display:block; margin-bottom:6px;">Interval (menit)</label>
            <input id="reloadMin" type="number" min="1" placeholder="Menit" style="width:100%; padding:8px; border:1px solid #ddd; border-radius:6px;">
            <div style="display:flex; gap:8px; margin-top:10px;">
                <button id="startReload" style="flex:1; background:#007bff; color:#fff; padding:8px; border:none; border-radius:6px; cursor:pointer;">Mulai</button>
                <button id="stopReload" style="flex:1; background:#6c757d; color:#fff; padding:8px; border:none; border-radius:6px; cursor:pointer;">Berhenti</button>
            </div>
            <div style="display:flex; justify-content:flex-end; margin-top:10px;">
                <button id="closeReload" style="background:transparent; border:none; color:#007bff; cursor:pointer;">Tutup</button>
            </div>
        `;
        document.body.appendChild(container);

        let intervalRef = null;
        container.querySelector('#startReload').onclick = () => {
            const m = parseInt(container.querySelector('#reloadMin').value, 10);
            if (isNaN(m) || m <= 0) {
                alert('Masukkan interval (menit) yang valid.');
                return;
            }
            if (intervalRef) clearInterval(intervalRef);
            intervalRef = setInterval(() => location.reload(), m * 60 * 1000);
            alert(`Auto reload setiap ${m} menit diaktifkan.`);
        };
        container.querySelector('#stopReload').onclick = () => {
            if (intervalRef) {
                clearInterval(intervalRef);
                intervalRef = null;
                alert('Auto reload dihentikan.');
            } else alert('Auto reload belum aktif.');
        };
        container.querySelector('#closeReload').onclick = () => container.remove();
    }

    // --- Remove Ads ---
    function removeAds() {
        const selectors = [
            '[id^="ad"]','[class*="ad"]','[id*="banner"]','[class*="banner"]',
            '[class*="promo"]','[class*="sponsored"]','[class*="ads"]',
            '[id*="popup"]','[class*="popup"]','[class*="overlay"]'
        ];
        selectors.forEach(sel => document.querySelectorAll(sel).forEach(el => el.style.display = 'none'));
        alert('Berhasil menyembunyikan elemen yang berlabel iklan (metode heuristik).');
    }

    // --- Dark Mode toggle (kept global) ---
    const darkStyle = document.createElement('style');
    darkStyle.textContent = `
        body.dark-mode, body.dark-mode * {
            background-color: #111 !important;
            color: #ddd !important;
            border-color: #333 !important;
        }
    `;
    document.head.appendChild(darkStyle);

    if (localStorage.getItem('darkModeEnabled') === 'true') {
        document.body.classList.add('dark-mode');
    }
    function toggleDarkMode() {
        document.body.classList.toggle('dark-mode');
        localStorage.setItem('darkModeEnabled', document.body.classList.contains('dark-mode'));
    }

    // --- Add icon buttons (SVG icons + tooltip text + callbacks) ---
    createIconButton(SVG.calc, 'Kalkulator Umur', showAgeCalculator);
    createIconButton(SVG.reload, 'Auto Reload', showAutoReloadPopup);
    createIconButton(SVG.removeAds, 'Hapus Iklan', removeAds);
    createIconButton(SVG.dark, 'Dark Mode', toggleDarkMode);

    // --- Quarter-circle animation logic ---
    let menuOpen = false;
    floatingBtn.addEventListener('click', () => {
        menuOpen = !menuOpen;
        const total = menuButtons.length;
        const radius = 120; // jarak tombol dari pusat
        const startAngle = -90; // degrees (top)
        const endAngle = -180; // degrees (left)
        const step = (endAngle - startAngle) / Math.max(1, (total - 1));

        menuButtons.forEach((btn, i) => {
            if (menuOpen) {
                const angleDeg = startAngle + step * i;
                const angle = angleDeg * (Math.PI / 180);
                const x = Math.cos(angle) * radius;
                const y = Math.sin(angle) * radius;
                // store translation so hover can reapply scale without losing coords
                btn.dataset.tx = x.toFixed(2);
                btn.dataset.ty = y.toFixed(2);
                // small staggered delay for nicer effect
                btn.style.transitionDelay = `${i * 0.03}s`;
                // move and show
                btn.style.transform = `translate(${x}px, ${y}px) scale(1)`;
                btn.style.opacity = '1';
            } else {
                btn.style.transitionDelay = `${(menuButtons.length - 1 - i) * 0.02}s`;
                btn.dataset.tx = 0;
                btn.dataset.ty = 0;
                btn.style.transform = `translate(0px, 0px) scale(1)`;
                btn.style.opacity = '0';
            }
        });

        floatingBtn.style.transform = menuOpen ? 'rotate(45deg)' : 'rotate(0deg)';
    });

    // --- Close menu when clicking outside ---
    document.addEventListener('click', (e) => {
        if (!menuOpen) return;
        if (floatingBtn.contains(e.target)) return;
        // if clicked a menu button, keep menu open (optional). We'll close for simplicity.
        menuOpen = false;
        menuButtons.forEach((btn, i) => {
            btn.style.transitionDelay = `${(menuButtons.length - 1 - i) * 0.02}s`;
            btn.dataset.tx = 0;
            btn.dataset.ty = 0;
            btn.style.transform = `translate(0px, 0px) scale(1)`;
            btn.style.opacity = '0';
        });
        floatingBtn.style.transform = 'rotate(0deg)';
    });

    // --- Prevent accidental selection when double-clicking ---
    floatingBtn.addEventListener('mousedown', (e) => e.preventDefault());

})();