HEX
Server: LiteSpeed
System: Linux s383.bitcommand.com 5.14.0-687.24.1.el9_8.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jul 9 18:14:06 EDT 2026 x86_64
User: pclast (1605)
PHP: 8.1.34
Disabled: exec,system,passthru,shell_exec,escapeshellarg,escapeshellcmd,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Upload Files
File: /home/pclast/public_html/wp-content/plugins/zhaket-updater/includes/Booster/booster-js.php
<script id="zhaket-booster" data-no-minify="1" data-no-optimize="1" data-noptimize="1" data-rocket-status="opt-out">
    (function(){
        // --- Configuration ---
        const debug = <?php echo !empty($settings['debug_mode']) ? 'true' : 'false'; ?>;
        const blocked = <?php echo $json_blocked; ?>;
        const cdnMap = <?php echo $json_cdn_map; ?>;
        const whitelist = <?php echo $whitelisted_domains; ?>;
        const maxTime = <?php echo $timeout; ?>;
        const reportUrl = '<?php echo $ajax_url; ?>';
        const currentHost = window.location.hostname;

        // تشخیص اینکه آیا سرویس ورکر در حال حاضر فعال است یا خیر
        const isSwActive = <?php echo $is_sw_active ? 'true' : 'false'; ?>;

        if (debug) {
            console.log('%c[Zhaket Booster Start] Debug Mode Active', "color: #27ae60; font-weight: bold;");
            if (isSwActive) {
                console.log('%c⚡ Running in SW Mode: DOM Interception Disabled, Performance Monitoring Active.', "color: #2980b9;");
            } else {
                console.log('%c⚠️ Running in Fallback Mode: DOM Interception & Monitoring both Active.', "color: #f39c12;");
            }
        }

        /**
         * Logic:
         * 1. Own Domain -> Allow + isLocal: true (Bypass tracking)
         * 2. Blocked -> Block
         * 3. CDN -> Replace
         * 4. Whitelist/Default -> Allow + isLocal: false
         */
        function getProcessedUrl(src) {
            if (!src || typeof src !== 'string' || src.startsWith('data:')) return { action: 'allow', url: src, isLocal: true };

            try {
                const urlObj = new URL(src, window.location.origin);
                const fullUrl = urlObj.href;
                const host = urlObj.hostname;

                const isDomainMatch = (pattern) => host === pattern || host.endsWith('.' + pattern);
                const isFullUrlMatch = (pattern) => fullUrl.includes(pattern);

                if (isDomainMatch(currentHost)) return { action: 'allow', url: src, isLocal: true };

                if (blocked.some(p => isDomainMatch(p) || isFullUrlMatch(p))) {
                    if (debug && !isSwActive) console.log(`%c[Blocked By Zhaket Booster]%c ${src}`, "color: red; font-weight: bold;", "color: inherit;");
                    return { action: 'block', url: src, isLocal: false };
                }

                const cdnMatch = cdnMap[src] || cdnMap[fullUrl] || cdnMap[src.replace(window.location.origin, '')];
                if (cdnMatch) {
                    if (debug && !isSwActive) console.log(`%c[CDN Replace By Zhaket Booster]%c ${src} -> ${cdnMatch}`, "color: blue; font-weight: bold;", "color: inherit;");
                    return { action: 'replace', url: cdnMatch, isLocal: false };
                }

                if (whitelist.some(p => isDomainMatch(p) || isFullUrlMatch(p))) return { action: 'allow', url: src, isLocal: false };

                return { action: 'allow', url: src, isLocal: false };
            } catch (e) {
                return { action: 'allow', url: src, isLocal: false };
            }
        }

        // =========================================================
        // 🔴 بخش Fallback: فقط در صورت خاموش بودن SW اجرا می‌شود
        // =========================================================
        if (!isSwActive) {

            // --- 1. Intercept Element Creation ---
            const _createElement = document.createElement.bind(document);
            document.createElement = function(tag) {
                const el = _createElement(tag);
                const tagName = tag.toLowerCase();

                if (tagName === 'script' || tagName === 'link' || tagName === 'img' || tagName === 'iframe') {
                    const targetAttr = tagName === 'link' ? 'href' : 'src';

                    Object.defineProperty(el, targetAttr, {
                        get: function() { return this.getAttribute(targetAttr); },
                        set: function(val) {
                            const result = getProcessedUrl(val);
                            if (result.action === 'block') {
                                if (tagName === 'script') el.setAttribute('type', 'javascript/blocked');
                                return;
                            }
                            if (result.action === 'replace') {
                                val = result.url;
                                el.removeAttribute('integrity');
                            }
                            this.setAttribute(targetAttr, val);
                        }
                    });

                    const _setAttribute = el.setAttribute.bind(el);
                    el.setAttribute = function(name, value) {
                        if (name.toLowerCase() === targetAttr) {
                            const result = getProcessedUrl(value);
                            if (result.action === 'block') {
                                if (tagName === 'script') _setAttribute.call(this, 'type', 'javascript/blocked');
                                return;
                            }
                            if (result.action === 'replace') {
                                value = result.url;
                                this.removeAttribute('integrity');
                            }
                        }
                        return _setAttribute.call(this, name, value);
                    };
                }
                return el;
            };

            // --- 2. Network Interception (Fetch & XHR) ---
            const _fetch = window.fetch;
            window.fetch = function(input, init) {
                let url = (typeof input === 'string') ? input : (input?.url || '');
                const result = getProcessedUrl(url);
                if (result.action === 'block') return Promise.reject(new Error('Blocked by Zhaket Booster'));

                if (result.action === 'replace') {
                    if (typeof input === 'string') input = result.url;
                    else if (input && input.url) input = new Request(result.url, input);
                }
                return _fetch.apply(this, arguments);
            };

            const _open = XMLHttpRequest.prototype.open;
            XMLHttpRequest.prototype.open = function(method, url) {
                const result = getProcessedUrl(url);
                this._isBlocked = (result.action === 'block');
                const finalUrl = result.action === 'replace' ? result.url : url;
                return _open.call(this, method, finalUrl, arguments[2], arguments[3], arguments[4]);
            };

            const _send = XMLHttpRequest.prototype.send;
            XMLHttpRequest.prototype.send = function() {
                if (this._isBlocked) {
                    setTimeout(() => this.dispatchEvent(new Event('error')), 0);
                    return;
                }
                return _send.apply(this, arguments);
            };

            // --- 3. Mutation Observer ---
            const processNode = (node) => {
                if (node.nodeType !== 1 || node.hasAttribute('data-booster-processed')) return;

                const isScript = node.tagName === 'SCRIPT';
                const isLink = node.tagName === 'LINK';
                const attr = isScript ? 'src' : (isLink ? 'href' : (node.tagName === 'IFRAME' || node.tagName === 'IMG' ? 'src' : null));

                if (!attr || !node.hasAttribute(attr)) return;
                const url = node.getAttribute(attr);
                if (!url) return;

                const result = getProcessedUrl(url);

                node.setAttribute('data-booster-processed', 'true');

                if (result.action === 'block') {
                    if (isScript) node.setAttribute('type', 'javascript/blocked');
                    node.remove();
                } else if (result.action === 'replace') {
                    if (isScript) {
                        const newScript = document.createElement('script');
                        newScript.src = result.url;
                        newScript.setAttribute('data-booster-processed', 'true');
                        Array.from(node.attributes).forEach(a => {
                            if (a.name !== 'src' && a.name !== 'data-booster-processed' && a.name !== 'integrity') {
                                newScript.setAttribute(a.name, a.value);
                            }
                        });
                        if (node.parentNode) node.parentNode.insertBefore(newScript, node);
                        node.remove();
                    } else {
                        node.setAttribute(attr, result.url);
                        node.removeAttribute('integrity');
                    }
                }
            };

            const observer = new MutationObserver(muts => {
                muts.forEach(m => m.addedNodes.forEach(node => {
                    processNode(node);
                    if (node.querySelectorAll) node.querySelectorAll('script, link, iframe, img').forEach(processNode);
                }));
            });
            observer.observe(document.documentElement, { childList: true, subtree: true });
            document.querySelectorAll('script, link, iframe, img').forEach(processNode);

        } // پایان بخش Fallback

        // =========================================================
        // 🟢 بخش مانیتورینگ: همیشه اجرا می‌شود (مستقل از وضعیت SW)
        // =========================================================
        let reportBuffer = [];
        let reportTimer = null;
        const DEBOUNCE_DELAY = 5000; // ارسال یکپارچه بعد از 5 ثانیه

        function sendBatchedReports() {
            if (reportBuffer.length === 0) return;
            if (reportTimer) { clearTimeout(reportTimer); reportTimer = null; }

            try {
                const isAuthorizedUser = document.body && (
                    document.body.classList.contains('logged-in') ||
                    document.body.classList.contains('wp-admin')
                );

                if (isAuthorizedUser) {
                    const data = new FormData();
                    data.append('reports', JSON.stringify(reportBuffer));

                    if (navigator.sendBeacon) navigator.sendBeacon(reportUrl, data);
                    else fetch(reportUrl, { method: 'POST', body: data, keepalive: true }).catch(()=>{});

                    if (debug) console.log(`%c📊 [Zhaket Booster] Batch Report Sent: %c${reportBuffer.length} slow/failed items`, "color: green; font-weight: bold;", "color: inherit;");
                }
            } catch (e) {}

            reportBuffer = [];
        }

        function queueReportItem(itemData) {
            reportBuffer.push(itemData);
            if (reportTimer) clearTimeout(reportTimer);
            reportTimer = setTimeout(sendBatchedReports, DEBOUNCE_DELAY);
        }

        document.addEventListener('visibilitychange', () => {
            if (document.visibilityState === 'hidden') sendBatchedReports();
        });

        if (window.PerformanceObserver) {
            const perfObserver = new PerformanceObserver(list => {
                list.getEntries().forEach(entry => {
                    const result = getProcessedUrl(entry.name);

                    // منابعی که بلاک شده‌اند یا متعلق به دامنه خودت هستند بررسی نمی‌شوند
                    if (result.action === 'block' || result.isLocal) return;

                    const isCached = entry.transferSize === 0 && entry.decodedBodySize > 0;
                    const isSlow = !isCached && entry.duration > maxTime;
                    const isFailed = 'responseStatus' in entry ? entry.responseStatus >= 400 : false;

                    if (isSlow || isFailed) {
                        if (debug) {
                            const status = isFailed ? `FAILED (HTTP ${entry.responseStatus || 'Error'})` : `${Math.round(entry.duration)}ms`;
                            console.log(`%c🐢 [Queued External Resource]%c ${entry.name} (${status})`, "color: orange; font-weight: bold;", "color: inherit;");
                        }

                        queueReportItem({
                            url: entry.name,
                            duration: isFailed ? (entry.responseStatus || 0) : entry.duration,
                            issue_type: isFailed ? 'failed' : 'slow'
                        });
                    }
                });
            });
            perfObserver.observe({ type: 'resource', buffered: true });
        }
    })();
</script>