// ELF Arsenal native Chimera client. The upstream WebUI remains available in a
// separate browser tab, but is no longer embedded: its opaque iframe errors
// cannot be diagnosed and its storage assumptions conflict with sandboxing.
let _eaPath = '/';
let _eaConnected = false;
function eaFriendlyError(value) {
const message = String(value || '').trim();
if (/Configureer eerst een geldig PS5-adres/i.test(message)) return 'Configure a PS5 host in Settings first.';
if (/ELF Arsenal-payload.*gestart/i.test(message)) return 'Start the ELF Arsenal payload explicitly, then retry.';
return message || 'ELF Arsenal is unavailable on port 6969.';
}
function eaBytes(value) {
const bytes = Number(value || 0);
if (bytes < 1024) return `${bytes} B`;
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
if (bytes < 1024 * 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
return `${(bytes / 1024 / 1024 / 1024).toFixed(1)} GB`;
}
function eaJoin(base, name) {
const cleanName = String(name || '').replace(/^\/+|\/+$/g, '');
return base === '/' ? `/${cleanName}` : `${String(base).replace(/\/+$/, '')}/${cleanName}`;
}
function eaParent(value) {
const parts = String(value || '/').split('/').filter(Boolean);
parts.pop();
return parts.length ? `/${parts.join('/')}` : '/';
}
function eaSetStatus(message, type = '') {
const status = document.getElementById('ea-embed-status');
if (!status) return;
status.textContent = message;
status.className = `ea-native-status ${type}`;
}
function eaRenderList(packet) {
const target = document.getElementById('ea-native-list');
const pathLabel = document.getElementById('ea-native-path');
if (!target || !pathLabel) return;
pathLabel.innerHTML = `${escHtml(_eaPath)}`;
const entries = (packet.entries || []).slice().sort((left, right) =>
Number(Boolean(right.is_dir)) - Number(Boolean(left.is_dir)) || String(left.name).localeCompare(String(right.name)));
target.innerHTML = entries.length ? entries.map(entry => {
const remotePath = eaJoin(_eaPath, entry.name);
const isElf = !entry.is_dir && /\.elf$/i.test(entry.name);
return `
Loading directory…
'; try { const [packet, job] = await Promise.all([ window.pork.eaList(_eaPath), window.pork.eaJobStatus().catch(() => ({ busy: false })), ]); eaRenderList(packet); const jobTarget = document.getElementById('ea-native-job'); if (jobTarget) jobTarget.textContent = job.busy ? `File operation active${job.progress != null ? ` · ${job.progress}%` : ''}` : 'No active file operation'; } catch (error) { if (target) target.innerHTML = `Native Chimera file browser and launcher for the ELF Arsenal service on your PS5.
Browse with Chimera's authenticated API. The original upstream WebUI opens separately and can no longer crash this page.
Waiting for ELF Arsenal…
FTP alone is not enough: ELF Arsenal must be running on port 6969. Launch and upload actions always require an explicit confirmation.
`; document.getElementById('ea-embed-open').addEventListener('click', () => { const url = document.getElementById('ea-embed-open')?.dataset.url; if (url) window.pork.openShell(url); }); document.getElementById('ea-embed-start').addEventListener('click', async (event) => { const button = event.currentTarget; button.disabled = true; eaSetStatus('Starting ELF Arsenal explicitly through Payload Manager…', 'warning'); try { await window.pork.eaStart(); showToast('ELF Arsenal started. Rechecking the service.', 'ok'); await eaReload(); } catch (error) { eaSetStatus(`Start failed: ${error.message}`, 'error'); showToast(`ELF Arsenal start failed: ${error.message}`, 'error'); } finally { button.disabled = false; } }); document.getElementById('ea-embed-reload').addEventListener('click', eaReload); document.getElementById('ea-native-path').addEventListener('click', event => { const button = event.target.closest('.ea-native-parent'); if (button) eaLoadDirectory(button.dataset.path); }); root.querySelectorAll('.ea-native-root').forEach(button => button.addEventListener('click', () => eaLoadDirectory(button.dataset.path))); document.getElementById('ea-native-list').addEventListener('click', async event => { const row = event.target.closest('.ea-native-row'); if (!row) return; const button = event.target.closest('button'); try { if (button?.classList.contains('ea-native-open')) await eaLoadDirectory(row.dataset.path); if (button?.classList.contains('ea-native-download')) await window.pork.eaDownload(row.dataset.path, row.dataset.name); if (button?.classList.contains('ea-native-launch')) { const confirmation = await showExactConfirmation(`Launch ${row.dataset.path} through ELF Arsenal?`, 'LAUNCH ELF'); if (!confirmation) return; await window.pork.eaLaunch(row.dataset.path, [], false); showToast(`${row.dataset.name} launch request sent.`, 'ok'); } } catch (error) { showToast(error.message, 'error', 10000); } }); document.getElementById('ea-native-upload').addEventListener('click', async () => { if (!_eaConnected) return showToast('Start ELF Arsenal first.', 'error'); const confirmation = await showExactConfirmation(`Upload one selected file to ${_eaPath}?`, 'UPLOAD FILE'); if (!confirmation) return; try { const uploadRoot = _eaPath === '/' ? '/' : `${_eaPath.replace(/\/+$/, '')}/`; const result = await window.pork.eaUpload(null, uploadRoot); if (result) { showToast(`Uploaded ${eaBytes(result.bytes)} to ${result.remotePath}.`, 'ok'); await eaLoadDirectory(_eaPath); } } catch (error) { showToast(error.message, 'error', 10000); } }); eaReload(); } async function loadElfArsenal() { if (!document.getElementById('ea-native-list')) buildElfArsenalEmbed(); else await eaReload(); }