(function () { function apiOrigin() { var m = document.querySelector('meta[name="auth-api-origin"]'); return m && m.content ? m.content.trim() : ""; } function apiUrl(path) { var o = apiOrigin(); if (path.charAt(0) !== "/") path = "/" + path; return o + path; } function readJsonBody(r) { return r.text().then(function (text) { if (!text || !text.trim()) return {}; try { return JSON.parse(text); } catch (e) { return { error: "INVALID_RESPONSE" }; } }); } function appendTurnstileLoadError(el, message) { if (!el || el.querySelector("[data-ts-load-error]")) return; var p = document.createElement("p"); p.className = "auth-hint"; p.setAttribute("data-ts-load-error", "1"); p.textContent = message; el.appendChild(p); } window.AITOKENS_AUTH = { apiUrl: apiUrl, fetchConfig: function () { return fetch(apiUrl("/api/auth/config"), { credentials: "omit" }) .then(readJsonBody) .catch(function () { return { turnstileSiteKey: "" }; }); }, get: function (path) { return fetch(apiUrl(path), { credentials: "include" }).then(function (r) { return readJsonBody(r).then(function (data) { return { ok: r.ok, status: r.status, data: data }; }); }); }, post: function (path, body) { return fetch(apiUrl(path), { method: "POST", credentials: "include", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }).then(function (r) { return readJsonBody(r).then(function (data) { return { ok: r.ok, status: r.status, data: data }; }); }); }, mountTurnstile: function (el, sitekey, cb) { if (!sitekey) { el.innerHTML = '
Configure TURNSTILE_SITE_KEY on the API, or set DEV_SKIP_TURNSTILE=1 in development.
Could not load Turnstile from Cloudflare. Check network, DNS, and ad blockers.
'; if (cb) cb(null); } }, 50); } }, getTurnstileToken: function (widgetId) { if (widgetId == null) return ""; return window.turnstile.getResponse(widgetId) || ""; }, resetTurnstile: function (widgetId) { if (widgetId != null && window.turnstile) window.turnstile.reset(widgetId); }, }; })();