initial commit

This commit is contained in:
syntaxbullet
2026-05-13 17:26:13 +02:00
commit 99569d2cf3
43 changed files with 8725 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Extractor — Test Upload</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #0d0d0d; --surface: #161616; --border: #2a2a2a;
--text: #e0e0e0; --muted: #666; --accent: #2563eb; --green: #16a34a; --red: #dc2626;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 14px;
}
body { background: var(--bg); color: var(--text); min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 28px; width: 100%; max-width: 520px; display: flex; flex-direction: column; gap: 18px; }
h1 { font-size: 15px; font-weight: 600; }
.drop-zone {
border: 2px dashed var(--border); border-radius: 7px; padding: 36px 20px;
text-align: center; cursor: pointer; transition: border-color 0.15s, background 0.15s;
color: var(--muted); font-size: 13px;
}
.drop-zone:hover, .drop-zone.over { border-color: var(--accent); background: rgba(37,99,235,0.05); color: var(--text); }
.drop-zone.has-file { border-color: var(--green); color: var(--green); }
input[type=file] { display: none; }
button {
padding: 8px 16px; border-radius: 6px; border: none; background: var(--accent);
color: #fff; font-size: 13px; cursor: pointer; transition: background 0.12s;
}
button:hover:not(:disabled) { background: #1d4ed8; }
button:disabled { opacity: 0.4; cursor: not-allowed; }
.result {
background: var(--bg); border: 1px solid var(--border); border-radius: 6px;
padding: 14px; font-family: "SF Mono", "Fira Mono", monospace; font-size: 11px;
white-space: pre-wrap; word-break: break-all; max-height: 320px; overflow-y: auto;
color: var(--text); display: none;
}
.result.error { border-color: var(--red); color: #f87171; }
.result.success { border-color: var(--green); }
.status { font-size: 12px; color: var(--muted); min-height: 16px; }
</style>
</head>
<body>
<div class="card">
<h1>Extractor — Test Upload</h1>
<div class="drop-zone" id="drop-zone">
<input type="file" id="file-input" accept=".pdf">
<span id="drop-label">Drop a PDF here, or click to select</span>
</div>
<button id="submit-btn" disabled>Extract</button>
<p class="status" id="status"></p>
<pre class="result" id="result"></pre>
</div>
<script>
const dropZone = document.getElementById("drop-zone");
const fileInput = document.getElementById("file-input");
const dropLabel = document.getElementById("drop-label");
const submitBtn = document.getElementById("submit-btn");
const statusEl = document.getElementById("status");
const resultEl = document.getElementById("result");
let selectedFile = null;
function csrfHeaders(extra = {}) {
const csrf = document.cookie
.split("; ")
.find((part) => part.startsWith("bmp_demo_csrf="))
?.slice("bmp_demo_csrf=".length);
return csrf ? { ...extra, "X-BMP-CSRF": decodeURIComponent(csrf) } : extra;
}
dropZone.addEventListener("click", () => fileInput.click());
fileInput.addEventListener("change", () => setFile(fileInput.files[0]));
dropZone.addEventListener("dragover", e => { e.preventDefault(); dropZone.classList.add("over"); });
dropZone.addEventListener("dragleave", () => dropZone.classList.remove("over"));
dropZone.addEventListener("drop", e => {
e.preventDefault();
dropZone.classList.remove("over");
setFile(e.dataTransfer.files[0]);
});
function setFile(file) {
if (!file || file.type !== "application/pdf") {
statusEl.textContent = "Please select a PDF file.";
return;
}
selectedFile = file;
dropLabel.textContent = file.name;
dropZone.classList.add("has-file");
submitBtn.disabled = false;
statusEl.textContent = "";
resultEl.style.display = "none";
}
submitBtn.addEventListener("click", async () => {
if (!selectedFile) return;
submitBtn.disabled = true;
statusEl.textContent = "Extracting…";
resultEl.style.display = "none";
const form = new FormData();
form.append("pdf", selectedFile);
try {
const res = await fetch("/extract", { method: "POST", headers: csrfHeaders(), body: form });
const json = await res.json();
resultEl.textContent = JSON.stringify(json, null, 2);
resultEl.className = "result " + (res.ok ? "success" : "error");
resultEl.style.display = "block";
statusEl.textContent = res.ok
? `Written → ${json.files?.json || json.stem}`
: `Error ${res.status}`;
} catch (err) {
resultEl.textContent = String(err);
resultEl.className = "result error";
resultEl.style.display = "block";
statusEl.textContent = "Request failed.";
} finally {
submitBtn.disabled = false;
}
});
</script>
</body>
</html>