muah.ai - Mod Panel

Replaces VIP-locked images with the actual image and provides a mod panel to open them in a new tab or download them.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         muah.ai - Mod Panel
// @license      MIT
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  Replaces VIP-locked images with the actual image and provides a mod panel to open them in a new tab or download them.
// @match        https://muah.ai/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    const found = new Set();

    function unlock() {
        const locked = document.querySelectorAll('.media.is-locked');
        if (!locked.length) return;

        locked.forEach(el => {
            const img = el.querySelector('img');
            if (!img || !img.src) return;
            if (!found.has(img.src)) found.add(img.src);
            const newImg = document.createElement('img');
            newImg.src = img.src;
            newImg.alt = 'Chat media';
            el.replaceWith(newImg);
        });
    }

    const btn = document.createElement('button');
    btn.textContent = 'Mod Panel';
    Object.assign(btn.style, {
        position: 'fixed',
        top: '20px',
        right: '20px',
        zIndex: 99999,
        padding: '10px 18px',
        fontSize: '14px',
        fontWeight: 'bold',
        color: '#fff',
        backgroundColor: '#7c3aed',
        border: 'none',
        borderRadius: '8px',
        cursor: 'pointer'
    });

    let panel = null;

    function openPanel() {
        if (panel) { panel.remove(); panel = null; return; }

        panel = document.createElement('div');
        Object.assign(panel.style, {
            position: 'fixed',
            top: '70px',
            right: '20px',
            zIndex: 99999,
            width: '340px',
            maxHeight: '70vh',
            overflowY: 'auto',
            backgroundColor: '#fff',
            borderRadius: '10px',
            boxShadow: '0 4px 20px rgba(0,0,0,0.2)',
            padding: '16px'
        });

        let html = '<div style="font-size:14px;margin-bottom:12px;">Use <a href="https://temp-mail.org/" target="_blank" rel="noopener" style="color:#2563eb;font-weight:bold;text-decoration:none;">this</a> to have infinite accounts.</div>';

        if (!found.size) {
            html += '<div style="padding:8px;font-size:14px;">No images found.</div>';
        } else {
            let imgHtml = '<div style="font-weight:bold;margin-bottom:10px;">Images</div>';
            const srcs = Array.from(found);
            srcs.forEach((src, i) => {
                imgHtml += `<a href="${src}" target="_blank" rel="noopener" style="display:block;padding:8px;margin-bottom:6px;font-size:13px;color:#7c3aed;text-decoration:none;border:1px solid #e5e7eb;border-radius:6px;">Image ${i + 1} — Open in new tab</a>`;
                imgHtml += `<button data-src="${src}" style="display:block;width:100%;padding:8px;margin-bottom:6px;font-size:13px;color:#fff;background-color:#dc2626;border:none;border-radius:6px;cursor:pointer;">Download Image ${i + 1}</button>`;
            });
            html += imgHtml;
        }

        html += '<button id="refreshBtn" style="display:block;width:100%;padding:10px;margin-top:10px;font-size:14px;color:#fff;background-color:#2563eb;border:none;border-radius:6px;cursor:pointer;">Refresh Page</button>';

        panel.innerHTML = html;
        document.body.appendChild(panel);

        panel.querySelector('#refreshBtn').addEventListener('click', () => {
            location.reload();
        });
    }

    btn.addEventListener('click', openPanel);
    document.body.appendChild(btn);

    unlock();

    const observer = new MutationObserver(unlock);
    observer.observe(document.body, { childList: true, subtree: true });
})();