feat: 更新管理员登录为简易版jwt

This commit is contained in:
Lan
2025-02-09 22:57:21 +08:00
parent f2f301f515
commit ede0e62f32
20 changed files with 113 additions and 29 deletions
+76 -10
View File
@@ -2,22 +2,88 @@
# @Author : Lan # @Author : Lan
# @File : depends.py # @File : depends.py
# @Software: PyCharm # @Software: PyCharm
from fastapi import Header, HTTPException from fastapi import Header, HTTPException, Depends
from fastapi.requests import Request from fastapi.requests import Request
import base64
import hmac
import json
import time
from core.settings import settings from core.settings import settings
from apps.admin.services import FileService, ConfigService, LocalFileService from apps.admin.services import FileService, ConfigService, LocalFileService
def create_token(data: dict, expires_in: int = 3600 * 24) -> str:
"""
创建JWT token
:param data: 数据负载
:param expires_in: 过期时间(秒)
"""
header = base64.b64encode(json.dumps({"alg": "HS256", "typ": "JWT"}).encode()).decode()
payload = base64.b64encode(json.dumps({
**data,
"exp": int(time.time()) + expires_in
}).encode()).decode()
signature = hmac.new(
settings.jwt_secret_key.encode(),
f"{header}.{payload}".encode(),
'sha256'
).digest()
signature = base64.b64encode(signature).decode()
return f"{header}.{payload}.{signature}"
def verify_token(token: str) -> dict:
"""
验证JWT token
:param token: JWT token
:return: 解码后的数据
"""
try:
header_b64, payload_b64, signature_b64 = token.split('.')
# 验证签名
expected_signature = hmac.new(
settings.jwt_secret_key.encode(),
f"{header_b64}.{payload_b64}".encode(),
'sha256'
).digest()
expected_signature_b64 = base64.b64encode(expected_signature).decode()
if signature_b64 != expected_signature_b64:
raise ValueError("无效的签名")
# 解码payload
payload = json.loads(base64.b64decode(payload_b64))
# 检查是否过期
if payload.get("exp", 0) < time.time():
raise ValueError("token已过期")
return payload
except Exception as e:
raise ValueError(f"token验证失败: {str(e)}")
async def admin_required(authorization: str = Header(default=None), request: Request = None): async def admin_required(authorization: str = Header(default=None), request: Request = None):
is_admin = (authorization.split(' ')[-1] if authorization else '') == settings.admin_token """
if request.url.path.startswith('/share/'): 验证管理员权限
if not settings.openUpload and not is_admin: """
raise HTTPException(status_code=403, detail='本站未开启游客上传,如需上传请先登录后台') try:
else: if not authorization or not authorization.startswith('Bearer '):
if not is_admin: raise ValueError("缺少Bearer token")
raise HTTPException(status_code=401, detail='未授权或授权校验失败')
return is_admin token = authorization.split(' ')[1]
payload = verify_token(token)
is_admin = payload.get("is_admin", False)
if request.url.path.startswith('/share/'):
if not settings.openUpload and not is_admin:
raise HTTPException(status_code=403, detail='本站未开启游客上传,如需上传请先登录后台')
else:
if not is_admin:
raise HTTPException(status_code=401, detail='未授权或授权校验失败')
return is_admin
except ValueError as e:
raise HTTPException(status_code=401, detail=str(e))
async def get_file_service(): async def get_file_service():
return FileService() return FileService()
+4
View File
@@ -13,3 +13,7 @@ class ShareItem(BaseModel):
class DeleteItem(BaseModel): class DeleteItem(BaseModel):
filename: str filename: str
class LoginData(BaseModel):
password: str
+15 -4
View File
@@ -4,19 +4,30 @@
# @Software: PyCharm # @Software: PyCharm
import datetime import datetime
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends, HTTPException
from apps.admin.services import FileService, ConfigService, LocalFileService from apps.admin.services import FileService, ConfigService, LocalFileService
from apps.admin.dependencies import admin_required, get_file_service, get_config_service, get_local_file_service from apps.admin.dependencies import admin_required, get_file_service, get_config_service, get_local_file_service
from apps.admin.schemas import IDData, ShareItem, DeleteItem from apps.admin.schemas import IDData, ShareItem, DeleteItem, LoginData
from core.response import APIResponse from core.response import APIResponse
from apps.base.models import FileCodes, KeyValue from apps.base.models import FileCodes, KeyValue
from apps.admin.dependencies import create_token
from core.settings import settings
admin_api = APIRouter(prefix='/admin', tags=['管理']) admin_api = APIRouter(prefix='/admin', tags=['管理'])
@admin_api.post('/login') @admin_api.post('/login')
async def login(admin: bool = Depends(admin_required)): async def login(data: LoginData):
return APIResponse() # 验证管理员密码
if data.password != settings.admin_password:
raise HTTPException(status_code=401, detail="密码错误")
# 生成包含管理员身份的token
token = create_token({"is_admin": True})
return APIResponse(detail={
"token": token,
"token_type": "Bearer"
})
@admin_api.get('/dashboard') @admin_api.get('/dashboard')
+3
View File
@@ -66,6 +66,9 @@ DEFAULT_CONFIG = {
'port': 12345, 'port': 12345,
'showAdminAddr': 0, 'showAdminAddr': 0,
'robotsText': 'User-agent: *\nDisallow: /', 'robotsText': 'User-agent: *\nDisallow: /',
'jwt_secret_key': "your-secret-key", # 建议使用环境变量
'jwt_algorithm': "HS256",
'admin_password': 'FileCodeBox2023', # 建议使用环境变量存储
} }
@@ -1,4 +1,4 @@
import{c as i,B as k,r as h,o as u,I as v,d as x,e as t,n as o,g as e,i as w,f as n,X as _,F as M,q as C,p as z,y as B,J as L,m as D,K as F,t as I,z as d}from"./index-CiI2cp0V.js";import{B as j}from"./box-BA8SMkDM.js";/** import{c as i,B as k,r as h,o as u,I as v,d as x,e as t,n as o,g as e,i as w,f as n,X as _,F as M,q as C,p as z,y as B,J as L,m as D,K as F,t as I,z as d}from"./index-BXFy05WO.js";import{B as j}from"./box-Cg0hrykV.js";/**
* @license lucide-vue-next v0.445.0 - ISC * @license lucide-vue-next v0.445.0 - ISC
* *
* This source code is licensed under the ISC license. * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as g,B as v,H as w,o as _,d as u,e as t,n as a,g as e,i as k,t as i,f as y,F as U,q as F,A as M,z as p,J as z,K as C}from"./index-CiI2cp0V.js";import{F as m}from"./file-CWusGEpI.js";import{H as D,T as S}from"./trash-dDHutUhM.js";/** import{c as g,B as v,H as w,o as _,d as u,e as t,n as a,g as e,i as k,t as i,f as y,F as U,q as F,A as M,z as p,J as z,K as C}from"./index-BXFy05WO.js";import{F as m}from"./file-DYxS796P.js";import{H as D,T as S}from"./trash-CUA4S_ac.js";/**
* @license lucide-vue-next v0.445.0 - ISC * @license lucide-vue-next v0.445.0 - ISC
* *
* This source code is licensed under the ISC license. * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as V,B as T,u as q,r as _,b as k,d as c,e as t,n as o,g as a,i as A,j as P,f as m,v as H,m as I,F as v,q as w,t as d,A as S,z as g}from"./index-CiI2cp0V.js";import{F as L}from"./file-CWusGEpI.js";/** import{c as V,B as T,u as q,r as _,b as k,d as c,e as t,n as o,g as a,i as A,j as P,f as m,v as H,m as I,F as v,q as w,t as d,A as S,z as g}from"./index-BXFy05WO.js";import{F as L}from"./file-DYxS796P.js";/**
* @license lucide-vue-next v0.445.0 - ISC * @license lucide-vue-next v0.445.0 - ISC
* *
* This source code is licensed under the ISC license. * This source code is licensed under the ISC license.
+1
View File
@@ -0,0 +1 @@
import{G as y,r as u,B as b,u as v,d as w,e,n as l,g as o,i as x,f as h,h as k,j as S,v as A,m as V,t as B,y as D,z as j,A as P,_}from"./index-BXFy05WO.js";import{B as z}from"./box-Cg0hrykV.js";const M=y("adminData",()=>{const d=u(localStorage.getItem("adminPassword")||"");function n(a){d.value=a,localStorage.setItem("token",a)}return{adminPassword:d,updateAdminPwd:n}}),I={class:"mx-auto h-16 w-16 relative"},L={class:"rounded-md shadow-sm -space-y-px"},N=["disabled"],T=b({__name:"LoginView",setup(d){const n=v(),a=u(""),i=u(!1),s=x("isDarkMode"),c=M(),p=()=>{let r=!0;return a.value?a.value.length<6&&(n.showAlert("密码长度至少为6位","error"),r=!1):(n.showAlert("无效的密码","error"),r=!1),r},m=D(),f=async()=>{if(p()){P.post("/admin/login",{password:a.value}).then(r=>{c.updateAdminPwd(r.detail.token),m.push("/admin")}).catch(r=>{n.showAlert(r.response.data.detail,"error")}),i.value=!0;try{await new Promise(r=>setTimeout(r,2e3))}catch{}finally{i.value=!1}}};return(r,t)=>(j(),w("div",{class:l(["min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 transition-colors duration-200 relative overflow-hidden",o(s)?"bg-gray-900":"bg-gray-50"])},[t[6]||(t[6]=e("div",{class:"absolute inset-0 z-0"},[e("div",{class:"cyber-grid"}),e("div",{class:"floating-particles"})],-1)),e("div",{class:l(["max-w-md w-full space-y-8 backdrop-blur-lg bg-opacity-20 p-8 rounded-xl border border-opacity-20",[o(s)?"bg-gray-800 border-gray-600":"bg-white/70 border-gray-200"]])},[e("div",null,[e("div",I,[t[1]||(t[1]=e("div",{class:"absolute inset-0 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full animate-spin-slow"},null,-1)),t[2]||(t[2]=e("div",{class:"absolute -inset-2 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full opacity-50 blur-md animate-pulse"},null,-1)),e("div",{class:l(["absolute inset-1 rounded-full flex items-center justify-center",o(s)?"bg-gray-800":"bg-white"])},[h(o(z),{class:l(["h-8 w-8",o(s)?"text-cyan-400":"text-cyan-600"])},null,8,["class"])],2)]),e("h2",{class:l(["mt-6 text-center text-3xl font-extrabold",o(s)?"text-white":"text-gray-900"])}," 登录 ",2)]),e("form",{class:"mt-8 space-y-6",onSubmit:k(f,["prevent"])},[t[5]||(t[5]=e("input",{type:"hidden",name:"remember",value:"true"},null,-1)),e("div",L,[e("div",null,[t[3]||(t[3]=e("label",{for:"password",class:"sr-only"},"密码",-1)),S(e("input",{id:"password",name:"password",type:"password",autocomplete:"current-password",required:"","onUpdate:modelValue":t[0]||(t[0]=g=>a.value=g),class:l(["appearance-none rounded-t-md relative block w-full px-4 py-3 border transition-all duration-200 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-cyan-500 focus:z-10 sm:text-sm backdrop-blur-sm",o(s)?"bg-gray-800/50 border-gray-600 text-white placeholder-gray-400 hover:border-gray-500":"bg-white/50 border-gray-300 text-gray-900 hover:border-gray-400"]),placeholder:"密码"},null,2),[[A,a.value]])])]),e("div",null,[e("button",{type:"submit",class:l(["group relative w-full flex justify-center py-3 px-4 border border-transparent text-sm font-medium rounded-md text-white transition-all duration-300 transform hover:scale-[1.02] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-500 shadow-lg hover:shadow-cyan-500/50",o(s)?"bg-gradient-to-r from-cyan-500 to-purple-500 hover:from-cyan-600 hover:to-purple-600":"bg-gradient-to-r from-cyan-600 to-purple-600 hover:from-cyan-700 hover:to-purple-700",i.value?"opacity-75 cursor-not-allowed":""]),disabled:i.value},[t[4]||(t[4]=e("span",{class:"absolute left-0 inset-y-0 flex items-center pl-3"},null,-1)),V(" "+B(i.value?"登录中...":"登录"),1)],10,N)])],32)],2)],2))}}),E=_(T,[["__scopeId","data-v-3d6e2ab2"]]);export{E as default};
@@ -1 +0,0 @@
@keyframes spin-2e50c3fa{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin-slow[data-v-2e50c3fa]{animation:spin-2e50c3fa 8s linear infinite}.fade-enter-active[data-v-2e50c3fa],.fade-leave-active[data-v-2e50c3fa]{transition:opacity .3s ease}.fade-enter-from[data-v-2e50c3fa],.fade-leave-to[data-v-2e50c3fa]{opacity:0}input[data-v-2e50c3fa]:focus{box-shadow:0 0 15px #6366f14d}button[data-v-2e50c3fa]:active:not(:disabled){transform:scale(.98)}.cyber-grid[data-v-2e50c3fa]{background-image:linear-gradient(transparent 95%,#6366f11a 50%),linear-gradient(90deg,transparent 95%,rgba(99,102,241,.1) 50%);background-size:30px 30px;width:100%;height:100%;position:absolute;opacity:.5}.floating-particles[data-v-2e50c3fa]{position:absolute;width:100%;height:100%;background:radial-gradient(circle at center,transparent 0%,transparent 100%);filter:url(#gooey)}.floating-particles[data-v-2e50c3fa]:before,.floating-particles[data-v-2e50c3fa]:after{content:"";position:absolute;width:100%;height:100%;background-image:radial-gradient(circle at center,rgba(99,102,241,.1) 0%,transparent 50%);animation:float-2e50c3fa 20s infinite linear}.floating-particles[data-v-2e50c3fa]:after{animation-delay:-10s;opacity:.5}@keyframes float-2e50c3fa{0%{transform:translate(0) scale(1)}50%{transform:translate(50px,50px) scale(1.5)}to{transform:translate(0) scale(1)}}button[data-v-2e50c3fa]:hover:not(:disabled){box-shadow:0 0 25px #6366f180}.fade-enter-active[data-v-2e50c3fa],.fade-leave-active[data-v-2e50c3fa]{transition:all .5s cubic-bezier(.4,0,.2,1)}
-1
View File
@@ -1 +0,0 @@
import{G as y,r as u,B as v,u as b,d as w,e,n as l,g as o,i as x,f as h,h as k,j as S,v as A,m as V,t as B,y as D,z as j,A as P,_}from"./index-CiI2cp0V.js";import{B as z}from"./box-BA8SMkDM.js";const M=y("adminData",()=>{const d=u(localStorage.getItem("adminPassword")||"");function n(t){d.value=t,localStorage.setItem("token",t)}return{adminPassword:d,updateAdminPwd:n}}),I={class:"mx-auto h-16 w-16 relative"},L={class:"rounded-md shadow-sm -space-y-px"},N=["disabled"],T=v({__name:"LoginView",setup(d){const n=b(),t=u(""),i=u(!1),s=x("isDarkMode"),c=M(),p=()=>{let a=!0;return t.value?t.value.length<6&&(n.showAlert("密码长度至少为6位","error"),a=!1):(n.showAlert("无效的密码","error"),a=!1),a},m=D(),f=async()=>{if(p()){c.updateAdminPwd(t.value),P.post("/admin/login",{password:t.value}).then(()=>{m.push("/admin")}).catch(a=>{n.showAlert(a.response.data.detail,"error")}),i.value=!0;try{await new Promise(a=>setTimeout(a,2e3))}catch{}finally{i.value=!1}}};return(a,r)=>(j(),w("div",{class:l(["min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 transition-colors duration-200 relative overflow-hidden",o(s)?"bg-gray-900":"bg-gray-50"])},[r[6]||(r[6]=e("div",{class:"absolute inset-0 z-0"},[e("div",{class:"cyber-grid"}),e("div",{class:"floating-particles"})],-1)),e("div",{class:l(["max-w-md w-full space-y-8 backdrop-blur-lg bg-opacity-20 p-8 rounded-xl border border-opacity-20",[o(s)?"bg-gray-800 border-gray-600":"bg-white/70 border-gray-200"]])},[e("div",null,[e("div",I,[r[1]||(r[1]=e("div",{class:"absolute inset-0 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full animate-spin-slow"},null,-1)),r[2]||(r[2]=e("div",{class:"absolute -inset-2 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full opacity-50 blur-md animate-pulse"},null,-1)),e("div",{class:l(["absolute inset-1 rounded-full flex items-center justify-center",o(s)?"bg-gray-800":"bg-white"])},[h(o(z),{class:l(["h-8 w-8",o(s)?"text-cyan-400":"text-cyan-600"])},null,8,["class"])],2)]),e("h2",{class:l(["mt-6 text-center text-3xl font-extrabold",o(s)?"text-white":"text-gray-900"])}," 登录 ",2)]),e("form",{class:"mt-8 space-y-6",onSubmit:k(f,["prevent"])},[r[5]||(r[5]=e("input",{type:"hidden",name:"remember",value:"true"},null,-1)),e("div",L,[e("div",null,[r[3]||(r[3]=e("label",{for:"password",class:"sr-only"},"密码",-1)),S(e("input",{id:"password",name:"password",type:"password",autocomplete:"current-password",required:"","onUpdate:modelValue":r[0]||(r[0]=g=>t.value=g),class:l(["appearance-none rounded-t-md relative block w-full px-4 py-3 border transition-all duration-200 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-cyan-500 focus:z-10 sm:text-sm backdrop-blur-sm",o(s)?"bg-gray-800/50 border-gray-600 text-white placeholder-gray-400 hover:border-gray-500":"bg-white/50 border-gray-300 text-gray-900 hover:border-gray-400"]),placeholder:"密码"},null,2),[[A,t.value]])])]),e("div",null,[e("button",{type:"submit",class:l(["group relative w-full flex justify-center py-3 px-4 border border-transparent text-sm font-medium rounded-md text-white transition-all duration-300 transform hover:scale-[1.02] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-500 shadow-lg hover:shadow-cyan-500/50",o(s)?"bg-gradient-to-r from-cyan-500 to-purple-500 hover:from-cyan-600 hover:to-purple-600":"bg-gradient-to-r from-cyan-600 to-purple-600 hover:from-cyan-700 hover:to-purple-700",i.value?"opacity-75 cursor-not-allowed":""]),disabled:i.value},[r[4]||(r[4]=e("span",{class:"absolute left-0 inset-y-0 flex items-center pl-3"},null,-1)),V(" "+B(i.value?"登录中...":"登录"),1)],10,N)])],32)],2)],2))}}),E=_(T,[["__scopeId","data-v-2e50c3fa"]]);export{E as default};
@@ -0,0 +1 @@
@keyframes spin-3d6e2ab2{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin-slow[data-v-3d6e2ab2]{animation:spin-3d6e2ab2 8s linear infinite}.fade-enter-active[data-v-3d6e2ab2],.fade-leave-active[data-v-3d6e2ab2]{transition:opacity .3s ease}.fade-enter-from[data-v-3d6e2ab2],.fade-leave-to[data-v-3d6e2ab2]{opacity:0}input[data-v-3d6e2ab2]:focus{box-shadow:0 0 15px #6366f14d}button[data-v-3d6e2ab2]:active:not(:disabled){transform:scale(.98)}.cyber-grid[data-v-3d6e2ab2]{background-image:linear-gradient(transparent 95%,#6366f11a 50%),linear-gradient(90deg,transparent 95%,rgba(99,102,241,.1) 50%);background-size:30px 30px;width:100%;height:100%;position:absolute;opacity:.5}.floating-particles[data-v-3d6e2ab2]{position:absolute;width:100%;height:100%;background:radial-gradient(circle at center,transparent 0%,transparent 100%);filter:url(#gooey)}.floating-particles[data-v-3d6e2ab2]:before,.floating-particles[data-v-3d6e2ab2]:after{content:"";position:absolute;width:100%;height:100%;background-image:radial-gradient(circle at center,rgba(99,102,241,.1) 0%,transparent 50%);animation:float-3d6e2ab2 20s infinite linear}.floating-particles[data-v-3d6e2ab2]:after{animation-delay:-10s;opacity:.5}@keyframes float-3d6e2ab2{0%{transform:translate(0) scale(1)}50%{transform:translate(50px,50px) scale(1.5)}to{transform:translate(0) scale(1)}}button[data-v-3d6e2ab2]:hover:not(:disabled){box-shadow:0 0 25px #6366f180}.fade-enter-active[data-v-3d6e2ab2],.fade-leave-active[data-v-3d6e2ab2]{transition:all .5s cubic-bezier(.4,0,.2,1)}
@@ -1,4 +1,4 @@
var De=Object.defineProperty;var Pe=(d,e,t)=>e in d?De(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var v=(d,e,t)=>Pe(d,typeof e!="symbol"?e+"":e,t);import{c as _e,_ as Fe,u as Ze,s as Oe,r as D,o as Ue,a as Qe,w as He,b as Ne,d as I,e as p,f as $,n as w,g as f,i as Ve,t as j,h as Ge,j as We,k as Y,v as Xe,l as Q,m as Z,p as Ke,X as xe,T as Je,F as Ye,q as et,x as le,y as tt,z as L,A as nt}from"./index-CiI2cp0V.js";import{c as H,u as st,S as it,C as rt,a as ot,Q as lt,E as at}from"./_commonjsHelpers-GlvjlJV-.js";import{B as ct}from"./box-BA8SMkDM.js";import{F as ke}from"./file-CWusGEpI.js";import{H as ut,T as pt}from"./trash-dDHutUhM.js";/** var De=Object.defineProperty;var Pe=(d,e,t)=>e in d?De(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var v=(d,e,t)=>Pe(d,typeof e!="symbol"?e+"":e,t);import{c as _e,_ as Fe,u as Ze,s as Oe,r as D,o as Ue,a as Qe,w as He,b as Ne,d as I,e as p,f as $,n as w,g as f,i as Ve,t as j,h as Ge,j as We,k as Y,v as Xe,l as Q,m as Z,p as Ke,X as xe,T as Je,F as Ye,q as et,x as le,y as tt,z as L,A as nt}from"./index-BXFy05WO.js";import{c as H,u as st,S as it,C as rt,a as ot,Q as lt,E as at}from"./_commonjsHelpers-CoPwux66.js";import{B as ct}from"./box-Cg0hrykV.js";import{F as ke}from"./file-DYxS796P.js";import{H as ut,T as pt}from"./trash-CUA4S_ac.js";/**
* @license lucide-vue-next v0.445.0 - ISC * @license lucide-vue-next v0.445.0 - ISC
* *
* This source code is licensed under the ISC license. * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as W,B as oe,r as z,o as ne,w as he,d as F,z as D,e as a,_ as se,u as ae,y as ge,i as pe,b as ye,p as ve,f as M,n as f,g as i,t as U,h as Q,l as E,k as N,j as J,v as X,x as K,C as be,F as Y,q as Z,m as V,X as xe,T as me,A as ee}from"./index-CiI2cp0V.js";import{g as we,u as _e,S as Ce,C as Ae,E as Me,a as Se,Q as Be}from"./_commonjsHelpers-GlvjlJV-.js";import{F as te}from"./file-CWusGEpI.js";import{T as Ie,H as Te}from"./trash-dDHutUhM.js";/** import{c as W,B as oe,r as z,o as ne,w as he,d as F,z as D,e as a,_ as se,u as ae,y as ge,i as pe,b as ye,p as ve,f as M,n as f,g as i,t as U,h as Q,l as E,k as N,j as J,v as X,x as K,C as be,F as Y,q as Z,m as V,X as xe,T as me,A as ee}from"./index-BXFy05WO.js";import{g as we,u as _e,S as Ce,C as Ae,E as Me,a as Se,Q as Be}from"./_commonjsHelpers-CoPwux66.js";import{F as te}from"./file-DYxS796P.js";import{T as Ie,H as Te}from"./trash-CUA4S_ac.js";/**
* @license lucide-vue-next v0.445.0 - ISC * @license lucide-vue-next v0.445.0 - ISC
* *
* This source code is licensed under the ISC license. * This source code is licensed under the ISC license.
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
import{c as k,B as F,D as R,r as _,E as K,o as V,F as X,G as x,H as Y}from"./index-CiI2cp0V.js";/** import{c as k,B as F,D as R,r as _,E as K,o as V,F as X,G as x,H as Y}from"./index-BXFy05WO.js";/**
* @license lucide-vue-next v0.445.0 - ISC * @license lucide-vue-next v0.445.0 - ISC
* *
* This source code is licensed under the ISC license. * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as a}from"./index-CiI2cp0V.js";/** import{c as a}from"./index-BXFy05WO.js";/**
* @license lucide-vue-next v0.445.0 - ISC * @license lucide-vue-next v0.445.0 - ISC
* *
* This source code is licensed under the ISC license. * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{c as a}from"./index-CiI2cp0V.js";/** import{c as a}from"./index-BXFy05WO.js";/**
* @license lucide-vue-next v0.445.0 - ISC * @license lucide-vue-next v0.445.0 - ISC
* *
* This source code is licensed under the ISC license. * This source code is licensed under the ISC license.
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
import{c as a}from"./index-CiI2cp0V.js";/** import{c as a}from"./index-BXFy05WO.js";/**
* @license lucide-vue-next v0.445.0 - ISC * @license lucide-vue-next v0.445.0 - ISC
* *
* This source code is licensed under the ISC license. * This source code is licensed under the ISC license.
+1 -1
View File
@@ -11,7 +11,7 @@
<meta name="keywords" content="{{keywords}}" /> <meta name="keywords" content="{{keywords}}" />
<meta name="generator" content="FileCodeBox2.2" /> <meta name="generator" content="FileCodeBox2.2" />
<title>{{title}}</title> <title>{{title}}</title>
<script type="module" crossorigin src="/assets/index-CiI2cp0V.js"></script> <script type="module" crossorigin src="/assets/index-BXFy05WO.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Bx419AMb.css"> <link rel="stylesheet" crossorigin href="/assets/index-Bx419AMb.css">
</head> </head>
<body> <body>