const API_BASE="/api",SITE_AUTHOR="moomomiimi001@gmail.com",Auth={getCurrentUser(){const e=localStorage.getItem("miltest_current_user");return e?JSON.parse(e):null},setCurrentUser(e){e?localStorage.setItem("miltest_current_user",JSON.stringify(e)):localStorage.removeItem("miltest_current_user")},getToken(){return localStorage.getItem("miltest_token")},setToken(e){e?localStorage.setItem("miltest_token",e):localStorage.removeItem("miltest_token")},isLoggedIn(){return!!this.getToken()},async register(e){localStorage.removeItem("miltest_kicked");try{const t={username:e.username,password:e.password,regCode:e.regCode};e.email&&(t.email=e.email),e.refCode&&(t.refCode=e.refCode),e.smsCode&&(t.smsCode=e.smsCode),e.phone&&(t.phone=e.phone),e.education&&(t.education=e.education),e.region&&(t.region=e.region),e.fingerprint&&(t.fingerprint=e.fingerprint);const r=await(await fetch(API_BASE+"/auth/register",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).json();return r.success&&r.token&&(this.setToken(r.token),this.setCurrentUser(r.user)),r}catch{return{success:!1,msg:"\u7F51\u7EDC\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u5668\u72B6\u6001"}}},async upgradeAccount(e){try{const t=this.getToken(),r=await(await fetch(API_BASE+"/auth/upgrade",{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer "+t},body:JSON.stringify({regCode:e})})).json();return r.success&&await this.getProfile(),r}catch{return{success:!1,msg:"\u7F51\u7EDC\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u5668\u72B6\u6001"}}},async updateProfile(e){try{const t=this.getToken();return await(await fetch(API_BASE+"/auth/profile",{method:"PATCH",headers:{"Content-Type":"application/json",Authorization:"Bearer "+t},body:JSON.stringify(e)})).json()}catch{return{success:!1,msg:"\u7F51\u7EDC\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u5668\u72B6\u6001"}}},async login(e,t,s){localStorage.removeItem("miltest_kicked");try{const n=await(await fetch(API_BASE+"/auth/login",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e,password:t,fingerprint:s})})).json();return n.success&&(this.setToken(n.token),this.setCurrentUser(n.user)),n}catch{return{success:!1,msg:"\u7F51\u7EDC\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u5668\u72B6\u6001"}}},async logout(){const e=this.getToken();if(e)try{await fetch(API_BASE+"/auth/logout",{method:"POST",headers:{Authorization:"Bearer "+e}})}catch{}this.setToken(null),this.setCurrentUser(null),localStorage.removeItem("miltest_kicked")},async getProfile(){const e=this.getToken();if(!e)return null;try{const t=await fetch(API_BASE+"/auth/me",{headers:{Authorization:"Bearer "+e}});if(t.status===401){try{const r=await t.json();if(r&&r.code==="KICKED")return this.logout(),showKickedModal(),null}catch{}return this.logout(),localStorage.setItem("miltest_kicked","1"),null}const s=await t.json();return s.success?(this.setCurrentUser(s.user),s.user):null}catch{return null}},async getTestResult(e){const t=this.getToken();if(!t)return null;try{const s=await fetch(API_BASE+"/results/"+e,{headers:{Authorization:"Bearer "+t}});if(!s.ok)return null;const r=await s.json();return r.success?r.result:null}catch{return null}},async getInviteCode(){const e=this.getToken();if(!e)return null;try{const s=await(await fetch(API_BASE+"/invite/code",{headers:{Authorization:"Bearer "+e}})).json();return s.success?s.code:null}catch{return null}},async getInviteRecords(){const e=this.getToken();if(!e)return[];try{const s=await(await fetch(API_BASE+"/invite/records",{headers:{Authorization:"Bearer "+e}})).json();return s.success?s.records:[]}catch{return[]}},async getInviteStats(){const e=this.getToken();if(!e)return{count:0};try{const s=await(await fetch(API_BASE+"/invite/stats",{headers:{Authorization:"Bearer "+e}})).json();return s.success?s:{count:0}}catch{return{count:0}}},async getPoints(){const e=this.getToken();if(!e)return{points:0,lifetime:0};try{const s=await(await fetch(API_BASE+"/points",{headers:{Authorization:"Bearer "+e}})).json();return s.success?s:{points:0,lifetime:0}}catch{return{points:0,lifetime:0}}},async getDashboardRecords(){const e=this.getToken();if(!e)return[];try{const s=await(await fetch(API_BASE+"/dashboard/records",{headers:{Authorization:"Bearer "+e}})).json();return s.success?s.records:[]}catch{return[]}},async getAllUsers(){const e=this.getToken();if(!e)return{};try{const s=await(await fetch(API_BASE+"/admin/users",{headers:{Authorization:"Bearer "+e}})).json();if(s.success){const r={};return s.users.forEach(n=>{r[n.email]=n}),r}return{}}catch{return{}}},async deleteUser(e){const t=this.getToken();if(t)try{await fetch(API_BASE+"/admin/users/"+encodeURIComponent(e),{method:"DELETE",headers:{Authorization:"Bearer "+t}})}catch{}},async getNotices(){try{const t=await(await fetch(API_BASE+"/notices")).json();return t.success?t.notices:[]}catch{return[]}},async saveTestResult(e,t){try{return localStorage.setItem("miltest_last_result_"+e,JSON.stringify(t)),!0}catch{return!1}},getUsers(){return JSON.parse(localStorage.getItem("miltest_users")||"{}")}};window.addEventListener("DOMContentLoaded",async()=>{Auth.getToken()&&!Auth.getCurrentUser()&&await Auth.getProfile()}),typeof SITE_AUTHOR<"u"&&console.debug("\u8054\u7CFB\u4F5C\u8005:",SITE_AUTHOR),(function(){const e="moomomiimi001",t="gmail.com",s=e+"@"+t;document.querySelectorAll("[data-email]").forEach(r=>{r.dataset.email==="author"&&(r.textContent=s,r.href="mailto:"+s)})})();function showKickedModal(){if(document.getElementById("miltest-kicked-modal"))return;const e=document.createElement("div");e.id="miltest-kicked-modal",e.style.cssText="position:fixed;top:0;left:0;width:100vw;height:100vh;background:rgba(0,0,0,0.55);display:flex;align-items:center;justify-content:center;z-index:99999;",e.innerHTML=`

\u8D26\u53F7\u5DF2\u5728\u5176\u4ED6\u8BBE\u5907\u767B\u5F55

\u60A8\u7684\u8D26\u53F7\u5DF2\u5728\u5176\u4ED6\u8BBE\u5907\u767B\u5F55\uFF0C\u5F53\u524D\u4F1A\u8BDD\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\u3002

`,document.body.appendChild(e)}(function(){const e=window.fetch;window.fetch=async function(){const t=await e.apply(this,arguments);if(t.status===401&&!t.url.includes("/auth/me"))try{if((t.headers.get("content-type")||"").includes("json")){const n=await t.clone().json();n&&n.code==="KICKED"&&(Auth.logout(),showKickedModal())}}catch{}return t}})();