From 1880a6ce0f2b8ad43ee5264a04a2c78770f4afa4 Mon Sep 17 00:00:00 2001 From: veypi Date: Sun, 1 Feb 2026 23:24:26 +0800 Subject: [PATCH] update router params --- api/app/access/create.go | 24 +++++-------- api/app/access/del.go | 12 ++----- api/app/access/get.go | 14 ++++---- api/app/access/list.go | 10 ++---- api/app/access/patch.go | 18 ++++------ api/app/app.go | 71 ++++++++++++++++---------------------- api/app/app_user/create.go | 15 +++----- api/app/app_user/del.go | 13 +++---- api/app/app_user/get.go | 16 ++++----- api/app/app_user/list.go | 11 ++---- api/app/app_user/patch.go | 15 +++----- api/app/init.go | 17 ++++----- api/app/resource/create.go | 12 ++----- api/app/resource/del.go | 12 ++----- api/app/resource/get.go | 14 ++++---- api/app/resource/list.go | 10 ++---- api/app/resource/patch.go | 13 ++----- api/app/role/create.go | 16 +++------ api/app/role/del.go | 12 ++----- api/app/role/get.go | 14 ++++---- api/app/role/list.go | 13 +++---- api/app/role/patch.go | 16 +++------ api/init.go | 32 +++++++++++------ api/sms/send.go | 22 +++++------- api/sms/validate.go | 5 +-- api/token/base.go | 23 ++++++------ api/token/create.go | 13 +++---- api/token/get.go | 34 ++++++++---------- api/user/create.go | 18 +++++----- api/user/init.go | 7 ++-- api/user/login.go | 33 +++++++++--------- api/user/role/create.go | 11 ++---- api/user/role/del.go | 14 ++++---- api/user/role/get.go | 29 +++++++--------- api/user/role/patch.go | 15 +++----- api/user/user.go | 31 +++++++++-------- cli/main.go | 2 -- init.go | 15 ++++---- libs/auth/jwt.go | 5 ++- models/app.go | 21 +++++------ models/init.go | 43 ++++++++++++----------- models/sms.go | 49 ++++++++++++-------------- models/token.go | 11 +++--- models/user.go | 5 +-- oauth/authorize.go | 64 +++++++++++++++------------------- oauth/init.go | 6 ++-- oauth/revoke.go | 21 +++++------ oauth/token.go | 29 +++++++--------- oauth/user.go | 33 ++++++++---------- ui/assets/vyes.min.js | 2 +- 50 files changed, 404 insertions(+), 557 deletions(-) diff --git a/api/app/access/create.go b/api/app/access/create.go index 9e31164..8eacd72 100644 --- a/api/app/access/create.go +++ b/api/app/access/create.go @@ -13,24 +13,18 @@ import ( ) type createOpts struct { - AppID string `json:"app_id"` - UserID *string `json:"user_id"` - RoleID *string `json:"role_id"` - ResourceID *string `json:"resource_id"` - Name string `json:"name"` - TID string `json:"tid"` - Level uint `json:"level"` + AppID string `json:"app_id" parse:"json"` + UserID *string `json:"user_id" parse:"json"` + RoleID *string `json:"role_id" parse:"json"` + ResourceID *string `json:"resource_id" parse:"json"` + Name string `json:"name" parse:"json"` + TID string `json:"tid" parse:"json"` + Level uint `json:"level" parse:"json"` } -var _ = Router.Post("/", createAccess) - -func createAccess(x *vigo.X) (any, error) { - // 解析请求参数 - opts := &createOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Post("/", "创建访问权限", createAccess) +func createAccess(x *vigo.X, opts *createOpts) (any, error) { // 创建新记录 access := models.Access{ AppID: opts.AppID, diff --git a/api/app/access/del.go b/api/app/access/del.go index 2de72b4..68b7968 100644 --- a/api/app/access/del.go +++ b/api/app/access/del.go @@ -13,18 +13,12 @@ import ( ) type deleteOpts struct { - ID string `parse:"path"` + ID string `parse:"path@id"` } -var _ = Router.Delete("/:id", deleteAccess) - -func deleteAccess(x *vigo.X) (any, error) { - // 解析路径参数 - opts := &deleteOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Delete("/{id}", "删除访问权限", deleteAccess) +func deleteAccess(x *vigo.X, opts *deleteOpts) (any, error) { // 查找记录 var access models.Access if err := cfg.DB().Where("id = ?", opts.ID).First(&access).Error; err != nil { diff --git a/api/app/access/get.go b/api/app/access/get.go index fdabff9..f3e88d7 100644 --- a/api/app/access/get.go +++ b/api/app/access/get.go @@ -12,18 +12,16 @@ import ( "github.com/vyes-ai/vigo" ) -var _ = Router.Get("/:id", getAccess) +type getIDReq struct { + ID string `parse:"path@id"` +} -func getAccess(x *vigo.X) (any, error) { - // 获取路径参数 - id := x.Params.Get("id") - if id == "" { - return nil, vigo.NewError("ID不能为空").WithCode(400) - } +var _ = Router.Get("/{id}", "获取访问权限详情", getAccess) +func getAccess(x *vigo.X, req *getIDReq) (any, error) { // 查询数据库 var access models.Access - err := cfg.DB().Where("id = ?", id).First(&access).Error + err := cfg.DB().Where("id = ?", req.ID).First(&access).Error if err != nil { return nil, vigo.NewError("未找到资源").WithCode(404) } diff --git a/api/app/access/list.go b/api/app/access/list.go index b02e7f9..30401e5 100644 --- a/api/app/access/list.go +++ b/api/app/access/list.go @@ -26,15 +26,9 @@ type listResponse struct { Items []models.Access `json:"items"` } -var _ = Router.Get("/", listAccess) - -func listAccess(x *vigo.X) (any, error) { - // 解析查询参数 - opts := &listOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Get("/", "获取访问权限列表", listAccess) +func listAccess(x *vigo.X, opts *listOpts) (any, error) { // 构建查询 db := cfg.DB().Model(&models.Access{}) if opts.AppID != "" { diff --git a/api/app/access/patch.go b/api/app/access/patch.go index a2c9b50..0744f86 100644 --- a/api/app/access/patch.go +++ b/api/app/access/patch.go @@ -13,21 +13,15 @@ import ( ) type updateOpts struct { - ID string `parse:"path"` - Name *string `json:"name"` - TID *string `json:"tid"` - Level *uint `json:"level"` + ID string `parse:"path@id"` + Name *string `json:"name" parse:"json"` + TID *string `json:"tid" parse:"json"` + Level *uint `json:"level" parse:"json"` } -var _ = Router.Patch("/:id", updateAccess) - -func updateAccess(x *vigo.X) (any, error) { - // 解析请求参数 - opts := &updateOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Patch("/{id}", "更新访问权限", updateAccess) +func updateAccess(x *vigo.X, opts *updateOpts) (any, error) { // 查找记录 var access models.Access if err := cfg.DB().Where("id = ?", opts.ID).First(&access).Error; err != nil { diff --git a/api/app/app.go b/api/app/app.go index 5286150..c2c648e 100644 --- a/api/app/app.go +++ b/api/app/app.go @@ -13,37 +13,36 @@ import ( "gorm.io/gorm" ) -var _ = Router.Get("/:app_id/key", auth.Check("app", "app_id", auth.DoDelete), appKey) +type appIDReq struct { + AppID string `parse:"path@app_id"` +} -func appKey(x *vigo.X) (any, error) { - id := x.Params.Get("app_id") - if id == "" { - return nil, vigo.ErrArgMissing.WithArgs("app_id") - } +var _ = Router.Get("/{app_id}/key", "重置应用密钥", auth.Check("app", "app_id", auth.DoDelete), appKey) + +func appKey(x *vigo.X, req *appIDReq) (any, error) { data := &models.App{} - data.ID = id + data.ID = req.AppID key := utils.RandSeq(32) - // err := cfg.DB().Where("id = ?", x.Params.GetStr("app_id")).First(data).Error err := cfg.DB().Model(data).Update("key", key).Error return key, err } -var _ = Router.Delete("/:app_id", auth.Check("app", "app_id", auth.DoDelete), appDelete) +var _ = Router.Delete("/{app_id}", "删除应用", auth.Check("app", "app_id", auth.DoDelete), appDelete) -func appDelete(x *vigo.X) (any, error) { +func appDelete(x *vigo.X, req *appIDReq) (any, error) { data := &models.App{} - err := cfg.DB().Where("id = ?", x.Params.Get("app_id")).Delete(data).Error + err := cfg.DB().Where("id = ?", req.AppID).Delete(data).Error return data, err } -var _ = Router.Get("/:app_id", auth.Check("app", "app_id", auth.DoRead), appGet) +var _ = Router.Get("/{app_id}", "获取应用详情", auth.Check("app", "app_id", auth.DoRead), appGet) -func appGet(x *vigo.X) (any, error) { +func appGet(x *vigo.X, req *appIDReq) (any, error) { data := &models.App{} - err := cfg.DB().Where("id = ?", x.Params.Get("app_id")).First(data).Error + err := cfg.DB().Where("id = ?", req.AppID).First(data).Error return data, err } @@ -52,14 +51,9 @@ type listOpts struct { Name *string `json:"name" parse:"query"` } -var _ = Router.Get("/", appList) +var _ = Router.Get("/", "获取应用列表", appList) -func appList(x *vigo.X) (any, error) { - opts := &listOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } +func appList(x *vigo.X, opts *listOpts) (any, error) { data := make([]*struct { models.App UserStatus string `json:"user_status"` @@ -90,34 +84,32 @@ type postOpts struct { InitUrl string `json:"init_url" parse:"json"` } -var _ = Router.Post("/", auth.Check("app", "", auth.DoCreate), appPost) +var _ = Router.Post("/", "创建应用", auth.Check("app", "", auth.DoCreate), appPost) -func appPost(x *vigo.X) (any, error) { - opts := &postOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } +func appPost(x *vigo.X, opts *postOpts) (any, error) { data := &models.App{} - data.Name = opts.Name data.Icon = opts.Icon if data.Icon == "" { data.Icon = fmt.Sprintf("https://public.veypi.com/img/avatar/%04d.jpg", rand.New(rand.NewSource(time.Now().UnixNano())).Intn(220)) } - data.Typ = opts.Typ + data.Des = "" if opts.Des != nil { data.Des = *opts.Des } - err = cfg.DB().Transaction(func(tx *gorm.DB) error { + data.Typ = opts.Typ + data.Status = opts.Status + data.InitUrl = opts.InitUrl + err := cfg.DB().Transaction(func(tx *gorm.DB) error { data.Key = utils.RandSeq(32) err := tx.Create(data).Error if err != nil { return err } + uid, _ := x.Get("uid").(string) au := &models.AppUser{ AppID: data.ID, - UserID: x.Request.Context().Value("uid").(string), + UserID: uid, Status: models.AUSTATUS_OK, } return tx.Create(au).Error @@ -127,27 +119,22 @@ func appPost(x *vigo.X) (any, error) { } type patchOpts struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@app_id"` + ID string `json:"id" gorm:"primaryKey;type:varchar(36)" parse:"path@app_id"` Name *string `json:"name" parse:"json"` Icon *string `json:"icon" parse:"json"` Des *string `json:"des" parse:"json"` Typ *string `json:"typ" gorm:"default:auto" parse:"json"` - InitRoleID *string `json:"init_role_id" gorm:"index;type:varchar(32)" parse:"json"` + InitRoleID *string `json:"init_role_id" gorm:"index;type:varchar(36)" parse:"json"` Status *string `json:"status" gorm:"default:ok" parse:"json"` InitUrl *string `json:"init_url" parse:"json"` } -var _ = Router.Patch("/:app_id", auth.Check("app", "app_id", auth.DoUpdate), appPatch) +var _ = Router.Patch("/{app_id}", "更新应用", auth.Check("app", "app_id", auth.DoUpdate), appPatch) -func appPatch(x *vigo.X) (any, error) { - opts := &patchOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } +func appPatch(x *vigo.X, opts *patchOpts) (any, error) { data := &models.App{} - err = cfg.DB().Where("id = ?", opts.ID).First(data).Error + err := cfg.DB().Where("id = ?", opts.ID).First(data).Error if err != nil { return nil, err } diff --git a/api/app/app_user/create.go b/api/app/app_user/create.go index a54f335..7eddd20 100644 --- a/api/app/app_user/create.go +++ b/api/app/app_user/create.go @@ -7,19 +7,14 @@ import ( ) type createOpts struct { - AppID string `parse:"path"` - UserID string `json:"user_id"` - Status string `json:"status" default:"ok"` + AppID string `parse:"path@app_id"` + UserID string `json:"user_id" parse:"json"` + Status string `json:"status" parse:"json" default:"ok"` } -var _ = Router.Post("/", createAppUser) - -func createAppUser(x *vigo.X) (any, error) { - opts := &createOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Post("/", "创建应用用户", createAppUser) +func createAppUser(x *vigo.X, opts *createOpts) (any, error) { appUser := &models.AppUser{ AppID: opts.AppID, UserID: opts.UserID, diff --git a/api/app/app_user/del.go b/api/app/app_user/del.go index 585a2d1..eaeab3f 100644 --- a/api/app/app_user/del.go +++ b/api/app/app_user/del.go @@ -7,18 +7,13 @@ import ( ) type deleteOpts struct { - AppID string `parse:"path"` - UserID string `parse:"path"` + AppID string `parse:"path@app_id"` + UserID string `parse:"path@user_id"` } -var _ = Router.Delete("/:user_id", deleteAppUser) - -func deleteAppUser(x *vigo.X) (any, error) { - opts := &deleteOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Delete("/{user_id}", "删除应用用户", deleteAppUser) +func deleteAppUser(x *vigo.X, opts *deleteOpts) (any, error) { appUser := &models.AppUser{} if err := cfg.DB().Where("app_id = ? AND user_id = ?", opts.AppID, opts.UserID).First(appUser).Error; err != nil { return nil, vigo.NewError("app_user not found").WithCode(404) diff --git a/api/app/app_user/get.go b/api/app/app_user/get.go index 91c46b9..8a2c019 100644 --- a/api/app/app_user/get.go +++ b/api/app/app_user/get.go @@ -6,18 +6,16 @@ import ( "github.com/vyes-ai/vigo" ) -var _ = Router.Get("/:user_id", getAppUser) - -func getAppUser(x *vigo.X) (any, error) { - appID := x.Params.Get("app_id") - userID := x.Params.Get("user_id") +type appUserIDReq struct { + AppID string `parse:"path@app_id"` + UserID string `parse:"path@user_id"` +} - if appID == "" || userID == "" { - return nil, vigo.NewError("app_id or user_id is empty").WithCode(400) - } +var _ = Router.Get("/{user_id}", "获取应用用户详情", getAppUser) +func getAppUser(x *vigo.X, req *appUserIDReq) (any, error) { appUser := &models.AppUser{} - err := cfg.DB().Where("app_id = ? AND user_id = ?", appID, userID).First(appUser).Error + err := cfg.DB().Where("app_id = ? AND user_id = ?", req.AppID, req.UserID).First(appUser).Error if err != nil { return nil, vigo.NewError("app_user not found").WithCode(404) } diff --git a/api/app/app_user/list.go b/api/app/app_user/list.go index 08099b1..a08c00d 100644 --- a/api/app/app_user/list.go +++ b/api/app/app_user/list.go @@ -7,7 +7,7 @@ import ( ) type listOpts struct { - AppID string `parse:"path"` + AppID string `parse:"path@app_id"` Page int `parse:"query" default:"1"` PageSize int `parse:"query" default:"20"` Status string `parse:"query" default:""` @@ -18,14 +18,9 @@ type listResponse struct { Items []*models.AppUser `json:"items"` } -var _ = Router.Get("/", listAppUsers) - -func listAppUsers(x *vigo.X) (any, error) { - opts := &listOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Get("/", "获取应用用户列表", listAppUsers) +func listAppUsers(x *vigo.X, opts *listOpts) (any, error) { query := cfg.DB().Model(&models.AppUser{}).Where("app_id = ?", opts.AppID) if opts.Status != "" { diff --git a/api/app/app_user/patch.go b/api/app/app_user/patch.go index e98801e..a10b221 100644 --- a/api/app/app_user/patch.go +++ b/api/app/app_user/patch.go @@ -7,19 +7,14 @@ import ( ) type updateOpts struct { - AppID string `parse:"path"` - UserID string `parse:"path"` - Status *string `json:"status"` + AppID string `parse:"path@app_id"` + UserID string `parse:"path@user_id"` + Status *string `json:"status" parse:"json"` } -var _ = Router.Patch("/:user_id", updateAppUser) - -func updateAppUser(x *vigo.X) (any, error) { - opts := &updateOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Patch("/{user_id}", "更新应用用户", updateAppUser) +func updateAppUser(x *vigo.X, opts *updateOpts) (any, error) { appUser := &models.AppUser{} if err := cfg.DB().Where("app_id = ? AND user_id = ?", opts.AppID, opts.UserID).First(appUser).Error; err != nil { return nil, vigo.NewError("app_user not found").WithCode(404) diff --git a/api/app/init.go b/api/app/init.go index dd57ad9..754878c 100644 --- a/api/app/init.go +++ b/api/app/init.go @@ -8,19 +8,20 @@ package app import ( - "github.com/veypi/OneAuth/cfg" + "github.com/veypi/OneAuth/api/app/access" + "github.com/veypi/OneAuth/api/app/app_user" + "github.com/veypi/OneAuth/api/app/resource" + "github.com/veypi/OneAuth/api/app/role" "github.com/veypi/OneAuth/libs/auth" - "github.com/veypi/OneAuth/models" "github.com/vyes-ai/vigo" - "github.com/vyes-ai/vigo/contrib/crud" ) var Router = vigo.NewRouter() -var appRouter = Router.SubRouter(":app_id").UseBefore(auth.Check("app", ":app_id", 2)) +var appRouter = Router.SubRouter("/{app_id}").Use(auth.Check("app", "{app_id}", 2)) func init() { - crud.All(appRouter.SubRouter("resource"), cfg.DB, models.Resource{}) - crud.All(appRouter.SubRouter("user"), cfg.DB, models.AppUser{}) - crud.All(appRouter.SubRouter("role"), cfg.DB, models.Role{}) - crud.All(appRouter.SubRouter("access"), cfg.DB, models.Access{}) + appRouter.Extend("/resource", resource.Router) + appRouter.Extend("/user", app_user.Router) + appRouter.Extend("/role", role.Router) + appRouter.Extend("/access", access.Router) } diff --git a/api/app/resource/create.go b/api/app/resource/create.go index 519508f..ea1572d 100644 --- a/api/app/resource/create.go +++ b/api/app/resource/create.go @@ -6,21 +6,15 @@ import ( "github.com/veypi/OneAuth/models" ) -var _ = Router.Post("/", createResource) - type createOpts struct { - AppID string `json:"app_id" parse:"path"` + AppID string `json:"app_id" parse:"path@app_id"` Name string `json:"name" parse:"json"` Des string `json:"des" parse:"json"` } -func createResource(x *vigo.X) (any, error) { - // 解析参数 - opts := &createOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Post("/", "创建资源", createResource) +func createResource(x *vigo.X, opts *createOpts) (any, error) { // 创建资源对象 resource := &models.Resource{ AppID: opts.AppID, diff --git a/api/app/resource/del.go b/api/app/resource/del.go index efd43ce..ef595f4 100644 --- a/api/app/resource/del.go +++ b/api/app/resource/del.go @@ -6,19 +6,13 @@ import ( "github.com/veypi/OneAuth/models" ) -var _ = Router.Delete("/:resource_id", deleteResource) - type deleteOpts struct { - ResourceID string `parse:"path"` + ResourceID string `parse:"path@resource_id"` } -func deleteResource(x *vigo.X) (any, error) { - // 解析参数 - opts := &deleteOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Delete("/{resource_id}", "删除资源", deleteResource) +func deleteResource(x *vigo.X, opts *deleteOpts) (any, error) { // 查找资源 resource := &models.Resource{} if err := cfg.DB().Where("id = ?", opts.ResourceID).First(resource).Error; err != nil { diff --git a/api/app/resource/get.go b/api/app/resource/get.go index 378efa9..6bcdcdb 100644 --- a/api/app/resource/get.go +++ b/api/app/resource/get.go @@ -6,18 +6,16 @@ import ( "github.com/veypi/OneAuth/models" ) -var _ = Router.Get("/:resource_id", getResource) +type getIDReq struct { + ID string `parse:"path@resource_id"` +} -func getResource(x *vigo.X) (any, error) { - // 获取路径参数 - resourceID := x.Params.Get("resource_id") - if resourceID == "" { - return nil, vigo.NewError("resource_id is required").WithCode(400) - } +var _ = Router.Get("/{resource_id}", "获取资源详情", getResource) +func getResource(x *vigo.X, req *getIDReq) (any, error) { // 查询数据库 resource := &models.Resource{} - err := cfg.DB().Where("id = ?", resourceID).First(resource).Error + err := cfg.DB().Where("id = ?", req.ID).First(resource).Error if err != nil { return nil, vigo.NewError("resource not found").WithCode(404) } diff --git a/api/app/resource/list.go b/api/app/resource/list.go index b951954..3237b6c 100644 --- a/api/app/resource/list.go +++ b/api/app/resource/list.go @@ -18,15 +18,9 @@ type listResponse struct { Items []*models.Resource `json:"items"` } -var _ = Router.Get("/", listResources) - -func listResources(x *vigo.X) (any, error) { - // 解析参数 - opts := &listOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Get("/", "获取资源列表", listResources) +func listResources(x *vigo.X, opts *listOpts) (any, error) { // 构建查询 db := cfg.DB().Model(&models.Resource{}) if opts.AppID != "" { diff --git a/api/app/resource/patch.go b/api/app/resource/patch.go index 10bbfc7..891fd77 100644 --- a/api/app/resource/patch.go +++ b/api/app/resource/patch.go @@ -6,21 +6,15 @@ import ( "github.com/veypi/OneAuth/models" ) -var _ = Router.Patch("/:resource_id", updateResource) - type updateOpts struct { - ResourceID string `parse:"path"` + ResourceID string `parse:"path@resource_id"` Name *string `json:"name" parse:"json"` Des *string `json:"des" parse:"json"` } -func updateResource(x *vigo.X) (any, error) { - // 解析参数 - opts := &updateOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Patch("/{resource_id}", "更新资源", updateResource) +func updateResource(x *vigo.X, opts *updateOpts) (any, error) { // 查找资源 resource := &models.Resource{} if err := cfg.DB().Where("id = ?", opts.ResourceID).First(resource).Error; err != nil { @@ -43,5 +37,4 @@ func updateResource(x *vigo.X) (any, error) { } } return resource, nil - } diff --git a/api/app/role/create.go b/api/app/role/create.go index 5802151..1ba37fa 100644 --- a/api/app/role/create.go +++ b/api/app/role/create.go @@ -6,21 +6,15 @@ import ( "github.com/vyes-ai/vigo" ) -var _ = Router.Post("/", createRole) - type createOpts struct { - AppID string `parse:"path"` // 应用 ID - Name string `json:"name"` // 角色名称 - Des string `json:"des"` // 角色描述 + AppID string `parse:"path@app_id"` // 应用 ID + Name string `json:"name" parse:"json"` // 角色名称 + Des string `json:"des" parse:"json"` // 角色描述 } -func createRole(x *vigo.X) (any, error) { - // 解析参数 - opts := &createOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Post("/", "创建角色", createRole) +func createRole(x *vigo.X, opts *createOpts) (any, error) { // 创建角色 role := &models.Role{ AppID: opts.AppID, diff --git a/api/app/role/del.go b/api/app/role/del.go index ba819fd..7a67a45 100644 --- a/api/app/role/del.go +++ b/api/app/role/del.go @@ -6,19 +6,13 @@ import ( "github.com/veypi/OneAuth/models" ) -var _ = Router.Delete("/:role_id", deleteRole) - type deleteOpts struct { - RoleID string `parse:"path"` // 角色 ID + RoleID string `parse:"path@role_id"` // 角色 ID } -func deleteRole(x *vigo.X) (any, error) { - // 解析参数 - opts := &deleteOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Delete("/{role_id}", "删除角色", deleteRole) +func deleteRole(x *vigo.X, opts *deleteOpts) (any, error) { // 查找角色 role := &models.Role{} if err := cfg.DB().Where("id = ?", opts.RoleID).First(role).Error; err != nil { diff --git a/api/app/role/get.go b/api/app/role/get.go index 57ae972..6325d1c 100644 --- a/api/app/role/get.go +++ b/api/app/role/get.go @@ -6,18 +6,16 @@ import ( "github.com/veypi/OneAuth/models" ) -var _ = Router.Get("/:role_id", getRole) +type getIDReq struct { + ID string `parse:"path@role_id"` +} -func getRole(x *vigo.X) (any, error) { - // 获取角色 ID - roleID := x.Params.Get("role_id") - if roleID == "" { - return nil, vigo.NewError("role_id is required").WithCode(400) - } +var _ = Router.Get("/{role_id}", "获取角色详情", getRole) +func getRole(x *vigo.X, req *getIDReq) (any, error) { // 查询数据库 role := &models.Role{} - err := cfg.DB().Where("id = ?", roleID).First(role).Error + err := cfg.DB().Where("id = ?", req.ID).First(role).Error if err != nil { return nil, vigo.NewError("role not found").WithCode(404) } diff --git a/api/app/role/list.go b/api/app/role/list.go index 6cc4e27..fb36f13 100644 --- a/api/app/role/list.go +++ b/api/app/role/list.go @@ -6,9 +6,10 @@ import ( "github.com/vyes-ai/vigo" ) -var _ = Router.Get("/", listRoles) +var _ = Router.Get("/", "获取角色列表", listRoles) type listOpts struct { + AppID string `parse:"path@app_id"` Page int `parse:"query" default:"1"` PageSize int `parse:"query" default:"20"` Keyword string `parse:"query" default:""` @@ -21,15 +22,9 @@ type listResponse struct { Items []*models.Role `json:"items"` } -func listRoles(x *vigo.X) (any, error) { - // 解析参数 - opts := &listOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } - +func listRoles(x *vigo.X, opts *listOpts) (any, error) { // 构建查询 - db := cfg.DB().Model(&models.Role{}) + db := cfg.DB().Model(&models.Role{}).Where("app_id = ?", opts.AppID) query := db // 应用关键词搜索 diff --git a/api/app/role/patch.go b/api/app/role/patch.go index a6ac807..6b10282 100644 --- a/api/app/role/patch.go +++ b/api/app/role/patch.go @@ -6,21 +6,15 @@ import ( "github.com/vyes-ai/vigo" ) -var _ = Router.Patch("/:role_id", updateRole) - type updateOpts struct { - RoleID string `parse:"path"` // 角色 ID - Name *string `json:"name"` // 可选,角色名称 - Des *string `json:"des"` // 可选,角色描述 + RoleID string `parse:"path@role_id"` // 角色 ID + Name *string `json:"name" parse:"json"` // 可选,角色名称 + Des *string `json:"des" parse:"json"` // 可选,角色描述 } -func updateRole(x *vigo.X) (any, error) { - // 解析参数 - opts := &updateOpts{} - if err := x.Parse(opts); err != nil { - return nil, err - } +var _ = Router.Patch("/{role_id}", "更新角色", updateRole) +func updateRole(x *vigo.X, opts *updateOpts) (any, error) { // 查找角色 role := &models.Role{} if err := cfg.DB().Where("id = ?", opts.RoleID).First(role).Error; err != nil { diff --git a/api/init.go b/api/init.go index b87e6e4..465fa98 100644 --- a/api/init.go +++ b/api/init.go @@ -14,23 +14,33 @@ import ( "github.com/veypi/OneAuth/api/user" "github.com/veypi/OneAuth/cfg" "github.com/veypi/OneAuth/libs/auth" + "github.com/veypi/OneAuth/oauth" "github.com/vyes-ai/vigo" "github.com/vyes-ai/vigo/contrib/common" ) -var Router = vigo.NewRouter().UseBefore(auth.CheckJWT).UseAfter(common.JsonResponse, common.JsonErrorResponse) +var Router = vigo.NewRouter() -var ( - _ = Router.Extend("user", user.Router) - _ = Router.Extend("token", token.Router) - _ = Router.Extend("app", app.Router) - _ = Router.Extend("sms", sms.Router) - _ = Router.Get("cfg", vigo.SkipBefore, getCfg) -) +func init() { + // 注册全局中间件 + Router.Use(auth.CheckJWT) + Router.After(common.JsonResponse, common.JsonErrorResponse) + + // 注册子资源路由 + Router.Extend("user", user.Router) + Router.Extend("token", token.Router) + Router.Extend("app", app.Router) + Router.Extend("sms", sms.Router) + Router.Extend("oauth", oauth.Router) -var _ = Router.Any("*", vigo.SkipBefore, func(x *vigo.X) error { - return vigo.ErrNotFound -}) + // 注册基础接口 + Router.Get("/cfg", "获取配置信息", vigo.SkipBefore, getCfg) + + // 404 处理 + Router.Any("/**", vigo.SkipBefore, func(x *vigo.X) error { + return vigo.ErrNotFound + }) +} func getCfg(x *vigo.X) any { return map[string]any{ diff --git a/api/sms/send.go b/api/sms/send.go index 9df3303..0315b46 100644 --- a/api/sms/send.go +++ b/api/sms/send.go @@ -15,29 +15,24 @@ import ( // SendCodeRequest 发送验证码请求 type SendCodeRequest struct { - Phone string `json:"phone"` - Region string `json:"region"` - Purpose string `json:"purpose"` - TemplateID string `json:"template_id"` + Phone string `json:"phone" parse:"json"` + Region string `json:"region" parse:"json"` + Purpose string `json:"purpose" parse:"json"` + TemplateID string `json:"template_id" parse:"json"` } // SendCodeResponse 发送验证码响应 type SendCodeResponse struct { - ID uint `json:"id"` + ID string `json:"id"` Phone string `json:"phone"` ExpiresAt time.Time `json:"expires_at"` Interval int `json:"interval"` // 下次可发送间隔(秒) } -var _ = Router.Post("/", vigo.SkipBefore, limiter.NewAdvancedRequestLimiter(time.Minute*3, 5, time.Second*30), sendCode) +var _ = Router.Post("/", "发送验证码", vigo.SkipBefore, limiter.NewAdvancedRequestLimiter(time.Minute*3, 5, time.Second*30), sendCode) // SendCode 发送验证码 -func sendCode(x *vigo.X) (any, error) { - req := &SendCodeRequest{} - err := x.Parse(req) - if err != nil { - return nil, err - } +func sendCode(x *vigo.X, req *SendCodeRequest) (any, error) { // 1. 验证手机号 normalizedPhone := utils.NormalizePhoneNumber(req.Phone) if !utils.ValidatePhoneNumber(normalizedPhone) { @@ -101,10 +96,9 @@ func sendCode(x *vigo.X) (any, error) { if err != nil { return nil, err } - return &SendCodeResponse{ ID: smsCode.ID, - Phone: normalizedPhone, + Phone: smsCode.Phone, ExpiresAt: smsCode.ExpiresAt, Interval: int(cfg.Config.SMS.Global.SendInterval.Seconds()), }, nil diff --git a/api/sms/validate.go b/api/sms/validate.go index 0912043..8c95394 100644 --- a/api/sms/validate.go +++ b/api/sms/validate.go @@ -14,6 +14,7 @@ import ( "github.com/veypi/OneAuth/cfg" "github.com/veypi/OneAuth/libs/utils" "github.com/veypi/OneAuth/models" + "github.com/vyes-ai/vigo" "gorm.io/gorm" ) @@ -30,9 +31,9 @@ func VerifyCode(Phone, Code, Region, Purpose string) error { if err != nil { if err == gorm.ErrRecordNotFound { - return fmt.Errorf("verification code not found or already used") + return vigo.NewError("verification code not found or already used").WithCode(404) } - return fmt.Errorf("failed to query sms code: %w", err) + return vigo.NewError("failed to query sms code").WithError(err) } // 2. 检查验证码是否过期 diff --git a/api/token/base.go b/api/token/base.go index 4a0051b..b184812 100644 --- a/api/token/base.go +++ b/api/token/base.go @@ -8,23 +8,18 @@ import ( "github.com/vyes-ai/vigo" ) -// var _ = Router.Patch("/:token_id", tokenPatch) - type patchOpts struct { ID string `json:"id" parse:"path@token_id"` ExpiredAt *time.Time `json:"expired_at" parse:"json"` OverPerm *string `json:"over_perm" parse:"json"` } -func tokenPatch(x *vigo.X) (any, error) { - opts := &patchOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } +var _ = Router.Patch("/{token_id}", "更新 Token", tokenPatch) + +func tokenPatch(x *vigo.X, opts *patchOpts) (any, error) { data := &models.Token{} - err = cfg.DB().Where("id = ?", opts.ID).First(data).Error + err := cfg.DB().Where("id = ?", opts.ID).First(data).Error if err != nil { return nil, err } @@ -40,10 +35,14 @@ func tokenPatch(x *vigo.X) (any, error) { return data, err } -var _ = Router.Delete("/:token_id", tokenDelete) +type deleteOpts struct { + ID string `parse:"path@token_id"` +} + +var _ = Router.Delete("/{token_id}", "删除 Token", tokenDelete) -func tokenDelete(x *vigo.X) (any, error) { +func tokenDelete(x *vigo.X, opts *deleteOpts) (any, error) { data := &models.Token{} - err := cfg.DB().Where("id = ?", x.Params.Get("token_id")).Delete(data).Error + err := cfg.DB().Where("id = ?", opts.ID).Delete(data).Error return data, err } diff --git a/api/token/create.go b/api/token/create.go index 2e8e97c..7ed1148 100644 --- a/api/token/create.go +++ b/api/token/create.go @@ -24,21 +24,16 @@ type postOpts struct { Refresh *string `json:"refresh" parse:"json"` Typ *string `json:"typ" parse:"json"` - AppID *string `json:"app_id" gorm:"index;type:varchar(32)" parse:"json"` + AppID *string `json:"app_id" gorm:"index;type:varchar(36)" parse:"json"` ExpiredAt *time.Time `json:"expired_at" parse:"json"` OverPerm *string `json:"over_perm" parse:"json"` Device *string `json:"device" parse:"json"` } -var _ = Router.Post("/", vigo.SkipBefore, tokenPost) +var _ = Router.Post("/", "创建 Token", vigo.SkipBefore, tokenPost) // for user login app -func tokenPost(x *vigo.X) (any, error) { - opts := &postOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } +func tokenPost(x *vigo.X, opts *postOpts) (any, error) { aid := cfg.Config.ID if opts.AppID != nil && *opts.AppID != "" { aid = *opts.AppID @@ -127,7 +122,7 @@ func tokenPost(x *vigo.X) (any, error) { HttpOnly: true, // 是否仅限 HTTP(S) 访问 Secure: false, // 是否通过安全连接传输 Cookie } - http.SetCookie(x, cookie) + http.SetCookie(x.ResponseWriter(), cookie) return token, nil } else { return nil, vigo.ErrArgInvalid diff --git a/api/token/get.go b/api/token/get.go index 966ee18..be4c8de 100644 --- a/api/token/get.go +++ b/api/token/get.go @@ -17,38 +17,32 @@ type getOpts struct { ID string `json:"id" parse:"path@token_id"` } -// var _ = Router.Get("/:token_id", tokenGet) +var _ = Router.Get("/{token_id}", "获取 Token 详情", tokenGet) -func tokenGet(x *vigo.X) (any, error) { - opts := &getOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } +func tokenGet(x *vigo.X, opts *getOpts) (any, error) { data := &models.Token{} - err = cfg.DB().Where("id = ?", opts.ID).First(data).Error + err := cfg.DB().Where("id = ?", opts.ID).First(data).Error return data, err } type listOpts struct { Limit int `json:"limit"` - UserID string `json:"user_id" gorm:"index;type:varchar(32)" parse:"query"` - AppID string `json:"app_id" gorm:"index;type:varchar(32)" parse:"query"` + UserID string `json:"user_id" gorm:"index;type:varchar(36)" parse:"query"` + AppID string `json:"app_id" gorm:"index;type:varchar(36)" parse:"query"` } -// var _ = Router.Get("/", tokenList) +var _ = Router.Get("/", "获取 Token 列表", tokenList) -func tokenList(x *vigo.X) (any, error) { - opts := &listOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } +func tokenList(x *vigo.X, opts *listOpts) (any, error) { data := make([]*models.Token, 0, 10) query := cfg.DB() - query = query.Where("user_id = ?", opts.UserID) - query = query.Where("app_id = ?", opts.AppID) - err = query.Limit(opts.Limit).Find(&data).Error + if opts.UserID != "" { + query = query.Where("user_id = ?", opts.UserID) + } + if opts.AppID != "" { + query = query.Where("app_id = ?", opts.AppID) + } + err := query.Limit(opts.Limit).Find(&data).Error return data, err } diff --git a/api/user/create.go b/api/user/create.go index c91f132..1a4d21c 100644 --- a/api/user/create.go +++ b/api/user/create.go @@ -23,7 +23,7 @@ import ( "gorm.io/gorm" ) -var _ = Router.Post("/", vigo.SkipBefore, publicLimits, userPost) +var _ = Router.Post("/", "用户注册", vigo.SkipBefore, publicLimits, userPost) type postOpts struct { Username string `json:"username" gorm:"varchar(100);unique;default:not null" parse:"json"` @@ -37,19 +37,13 @@ type postOpts struct { Email *string `json:"email" gorm:"varchar(20);unique;default:null" parse:"json"` } -func userPost(x *vigo.X) (any, error) { - opts := &postOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } +func userPost(x *vigo.X, opts *postOpts) (any, error) { data := &models.User{} - data.ID = strings.ReplaceAll(uuid.New().String(), "-", "") if cfg.Config.SMS.Enable { data.Phone = opts.Region + opts.Phone data.Region = opts.Region - err = sms.VerifyCode(opts.Phone, opts.VerifyCode, opts.Region, "signup") + err := sms.VerifyCode(opts.Phone, opts.VerifyCode, opts.Region, "signup") if err != nil { return nil, vigo.ErrArgInvalid.WithArgs("verify code").WithString(err.Error()) } @@ -65,12 +59,16 @@ func userPost(x *vigo.X) (any, error) { return nil, vigo.ErrArgInvalid.WithArgs("code") } code = utils.PKCS7Padding(code, 32) + // We need ID for encryption, but it's not generated yet. + // We can generate it manually here since vigo.Model doesn't auto-generate it before Create + data.ID = strings.ReplaceAll(uuid.New().String(), "-", "") + data.Code, err = utils.AesEncrypt([]byte(data.ID), code, []byte(data.Salt)) if err != nil { return nil, vigo.ErrArgInvalid.WithArgs("code") } ncode, err := utils.AesDecrypt([]byte(data.Code), code, []byte(data.Salt)) - if err != nil || ncode != data.ID { + if err != nil || string(ncode) != data.ID { return nil, vigo.ErrInternalServer.WithString("code decrypt failed") } if opts.Nickname != nil { diff --git a/api/user/init.go b/api/user/init.go index c598570..e35ecd1 100644 --- a/api/user/init.go +++ b/api/user/init.go @@ -8,16 +8,13 @@ package user import ( - "github.com/veypi/OneAuth/cfg" + "github.com/veypi/OneAuth/api/user/role" "github.com/veypi/OneAuth/libs/auth" - "github.com/veypi/OneAuth/models" "github.com/vyes-ai/vigo" - "github.com/vyes-ai/vigo/contrib/crud" ) var Router = vigo.NewRouter() -var userRouter = Router.SubRouter("/:user_id").UseBefore(userGet) func init() { - crud.All(Router.SubRouter("/:user_id/user_role"), cfg.DB, models.UserRole{}).UseBefore(auth.Check("user", "", 4)) + Router.Extend("/{user_id}/user_role", role.Router).Use(auth.Check("user", "", 4)) } diff --git a/api/user/login.go b/api/user/login.go index bb104ee..6b7b729 100644 --- a/api/user/login.go +++ b/api/user/login.go @@ -24,7 +24,7 @@ import ( var publicLimits = limiter.NewAdvancedRequestLimiter(time.Minute*5, 20, time.Second*3, nil).Limit -var _ = Router.Post("/login", +var _ = Router.Post("/login", "用户登录", vigo.SkipBefore, publicLimits, userLogin) @@ -42,14 +42,9 @@ type loginOpts struct { Device *string `json:"device" parse:"json"` } -func userLogin(x *vigo.X) (any, error) { +func userLogin(x *vigo.X, opts *loginOpts) (any, error) { // Implement login logic here // For example, validate user credentials and return a token - opts := &loginOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } user := &models.User{} query := cfg.DB() typ := "" @@ -64,7 +59,7 @@ func userLogin(x *vigo.X) (any, error) { default: query = query.Where("username = ?", opts.UserName) } - err = query.First(user).Error + err := query.First(user).Error if err != nil { return nil, vigo.ErrNotFound } @@ -99,19 +94,25 @@ func userLogin(x *vigo.X) (any, error) { if opts.Device != nil { data.Device = *opts.Device } - data.Ip = x.GetRemoteIP() - logv.AssertError(cfg.DB().Create(data).Error) + + err = cfg.DB().Create(data).Error + if err != nil { + return nil, err + } claim := &auth.Claims{} - claim.IssuedAt = jwt.NewNumericDate(time.Now()) - claim.Issuer = cfg.Config.ID - claim.ID = data.ID claim.AID = aid claim.UID = user.ID - claim.Name = user.Username - claim.Icon = user.Icon + claim.ID = data.ID claim.ExpiresAt = jwt.NewNumericDate(data.ExpiredAt) + claim.Name = user.Username if user.Nickname != "" { claim.Name = user.Nickname } - return auth.GenJwt(claim) + claim.Icon = user.Icon + + token, err := auth.GenJwt(claim) + return map[string]any{ + "token": token, + "expired_at": data.ExpiredAt, + }, err } diff --git a/api/user/role/create.go b/api/user/role/create.go index 8b8d9da..4e760cc 100644 --- a/api/user/role/create.go +++ b/api/user/role/create.go @@ -13,7 +13,7 @@ import ( "github.com/vyes-ai/vigo" ) -var _ = Router.Post("/", userRolePost) +var _ = Router.Post("/", "创建用户角色", userRolePost) type postOpts struct { UserID string `json:"user_id" parse:"path"` @@ -22,19 +22,14 @@ type postOpts struct { Status string `json:"status" parse:"json"` } -func userRolePost(x *vigo.X) (any, error) { - opts := &postOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } +func userRolePost(x *vigo.X, opts *postOpts) (any, error) { data := &models.UserRole{} data.UserID = opts.UserID data.RoleID = opts.RoleID data.AppID = opts.AppID data.Status = opts.Status - err = cfg.DB().Create(data).Error + err := cfg.DB().Create(data).Error return data, err } diff --git a/api/user/role/del.go b/api/user/role/del.go index fa2cfb8..f918223 100644 --- a/api/user/role/del.go +++ b/api/user/role/del.go @@ -13,14 +13,14 @@ import ( "github.com/vyes-ai/vigo" ) -var _ = Router.Delete("/:id", userRoleDelete) +type deleteIDReq struct { + ID string `parse:"path@id"` +} + +var _ = Router.Delete("/{id}", "删除用户角色", userRoleDelete) -func userRoleDelete(x *vigo.X) (any, error) { - id := x.Params.Get("id") - if id == "" { - return nil, vigo.ErrArgInvalid.WithArgs("id") - } +func userRoleDelete(x *vigo.X, req *deleteIDReq) (any, error) { data := &models.UserRole{} - err := cfg.DB().Where("id = ?", id).Delete(data).Error + err := cfg.DB().Where("id = ?", req.ID).Delete(data).Error return data, err } diff --git a/api/user/role/get.go b/api/user/role/get.go index 570edc7..75131f5 100644 --- a/api/user/role/get.go +++ b/api/user/role/get.go @@ -14,33 +14,28 @@ import ( "github.com/vyes-ai/vigo" ) -var _ = Router.Get("/:id", ` - get user role -`, userRoleGet) +type getIDReq struct { + ID string `parse:"path@id"` +} + +var _ = Router.Get("/{id}", "获取用户角色详情", userRoleGet) -func userRoleGet(x *vigo.X) (any, error) { +func userRoleGet(x *vigo.X, req *getIDReq) (any, error) { data := &models.UserRole{} - err := cfg.DB().Where("id = ?", x.Params.Get("id")).First(data).Error + err := cfg.DB().Where("id = ?", req.ID).First(data).Error return data, err } -var _ = Router.Get("/", ` - list user roles -`, userRoleList) - type listOpts struct { - UserID *string `json:"user_id" parse:"path"` + UserID *string `json:"user_id" parse:"path@user_id"` RoleID *string `json:"role_id" parse:"query"` AppID *string `json:"app_id" parse:"query"` Status *string `json:"status" parse:"query"` } -func userRoleList(x *vigo.X) (any, error) { - opts := &listOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } +var _ = Router.Get("/", "获取用户角色列表", userRoleList) + +func userRoleList(x *vigo.X, opts *listOpts) (any, error) { data := make([]*struct { models.UserRole Username string `json:"username"` @@ -65,7 +60,7 @@ func userRoleList(x *vigo.X) (any, error) { if opts.Status != nil { query = query.Where("status LIKE ?", opts.Status) } - err = query.Scan(&data).Error + err := query.Scan(&data).Error return data, err } diff --git a/api/user/role/patch.go b/api/user/role/patch.go index 320c9df..3b81713 100644 --- a/api/user/role/patch.go +++ b/api/user/role/patch.go @@ -14,24 +14,19 @@ import ( ) type patchOpts struct { - ID string `json:"id" parse:"path"` + ID string `json:"id" parse:"path@id"` Status *string `json:"status" parse:"json"` } -var _ = Router.Patch("/:id", userRolePatch) +var _ = Router.Patch("/{id}", "更新用户角色", userRolePatch) -func userRolePatch(x *vigo.X) (any, error) { - opts := &patchOpts{} - err := x.Parse(opts) - if err != nil { - return nil, err - } +func userRolePatch(x *vigo.X, opts *patchOpts) (any, error) { data := &models.UserRole{} - err = cfg.DB().Where("id = ?", opts.ID).First(data).Error + err := cfg.DB().Where("id = ?", opts.ID).First(data).Error if err != nil { return nil, err } - optsMap := make(map[string]interface{}) + optsMap := make(map[string]any) if opts.Status != nil { optsMap["status"] = opts.Status } diff --git a/api/user/user.go b/api/user/user.go index 528ee7d..f593105 100644 --- a/api/user/user.go +++ b/api/user/user.go @@ -8,30 +8,34 @@ import ( "github.com/vyes-ai/vigo/contrib/crud" ) -var _ = Router.Delete("/:user_id", auth.Check("user", "user_id", auth.DoDelete, checkOwner), userDelete) +type userIDReq struct { + UserID string `parse:"path@user_id"` +} + +var _ = Router.Delete("/{user_id}", "删除用户", auth.Check("user", "user_id", auth.DoDelete, checkOwner), userDelete) -func userDelete(x *vigo.X) (any, error) { +func userDelete(x *vigo.X, req *userIDReq) (any, error) { data := &models.User{} - err := cfg.DB().Where("id = ?", x.Params.Get("user_id")).Delete(data).Error + err := cfg.DB().Where("id = ?", req.UserID).Delete(data).Error return data, err } -var _ = Router.Get("/:user_id", auth.Check("user", "user_id", auth.DoRead, checkOwner), vigo.DiliverData) +var _ = Router.Get("/{user_id}", "获取用户详情", auth.Check("user", "user_id", auth.DoRead, checkOwner), userGet) func checkOwner(x *vigo.X, data any) bool { u, ok1 := data.(*models.User) - return ok1 && u.ID == x.Params.Get("user_id") + return ok1 && u.ID == x.PathParams.Get("user_id") } -func userGet(x *vigo.X) (any, error) { +func userGet(x *vigo.X, req *userIDReq) (any, error) { data := &models.User{} - err := cfg.DB().Where("id = ?", x.Params.Get("user_id")).First(data).Error + err := cfg.DB().Where("id = ?", req.UserID).First(data).Error return data, err } -var _ = Router.Get("/", "list user", auth.Check("user", "", auth.DoUpdate), crud.List(cfg.DB, &models.User{})) +var _ = Router.Get("/", "用户列表", auth.Check("user", "", auth.DoUpdate), crud.List(cfg.DB, &models.User{})) -var _ = Router.Patch("/:user_id", auth.Check("user", "user_id", auth.DoUpdate, checkOwner), userPatch) +var _ = Router.Patch("/{user_id}", "更新用户", auth.Check("user", "user_id", auth.DoUpdate, checkOwner), userPatch) type patchOpts struct { ID string `json:"id" parse:"path@user_id"` @@ -44,13 +48,12 @@ type patchOpts struct { Status *uint `json:"status" parse:"json"` } -func userPatch(x *vigo.X, args any) (any, error) { - opts := &patchOpts{} - err := x.Parse(opts) +func userPatch(x *vigo.X, opts *patchOpts) (any, error) { + data := &models.User{} + err := cfg.DB().Where("id = ?", opts.ID).First(data).Error if err != nil { - return nil, err + return nil, vigo.ErrNotFound } - data := args.(*models.User) optsMap := make(map[string]any) if opts.Username != nil { diff --git a/cli/main.go b/cli/main.go index d376b27..9968991 100644 --- a/cli/main.go +++ b/cli/main.go @@ -69,7 +69,5 @@ func runWeb() error { return err } server.SetRouter(OneAuth.Router) - server.EnableAI() - server.Router().Print() return server.Run() } diff --git a/init.go b/init.go index f6fbe1f..fcdb1ef 100644 --- a/init.go +++ b/init.go @@ -8,8 +8,9 @@ package OneAuth import ( "embed" + "github.com/veypi/OneAuth/api" - "github.com/veypi/vyes-ui" + vyesui "github.com/veypi/vyes-ui" "github.com/vyes-ai/vigo" "github.com/vyes-ai/vigo/contrib/cors" "github.com/vyes-ai/vigo/contrib/vyes" @@ -20,9 +21,9 @@ var Router = vigo.NewRouter() //go:embed ui/* var uifs embed.FS -var ( - _ = Router.Extend("v", vyesui.Router) - _ = Router.Extend("api", api.Router) - _ = Router.SubRouter("/*path").UseBefore(cors.AllowAny) - _ = vyes.WrapUI(Router, uifs) -) +func init() { + Router.Extend("v", vyesui.Router) + Router.Extend("api", api.Router) + Router.SubRouter("/*path").Use(cors.AllowAny) + vyes.WrapUI(Router, uifs) +} diff --git a/libs/auth/jwt.go b/libs/auth/jwt.go index 24cfe56..ecdc6f7 100644 --- a/libs/auth/jwt.go +++ b/libs/auth/jwt.go @@ -102,8 +102,11 @@ func Check(target string, pid string, l AuthLevel, funcs ...CustomCheckFunc) fun if strings.HasPrefix(pid, "@") { tid, _ = x.Get(pid[1:]).(string) } + if strings.HasPrefix(pid, "{") && strings.HasSuffix(pid, "}") { + tid = x.PathParams.Get(pid[1 : len(pid)-1]) + } if strings.HasPrefix(pid, ":") { - tid = x.Params.Get(pid[1:]) + tid = x.PathParams.Get(pid[1:]) } if !claims.Access.Check(target, tid, l) { err = AuthNoPerm diff --git a/models/app.go b/models/app.go index f7a63c3..19999fa 100644 --- a/models/app.go +++ b/models/app.go @@ -1,6 +1,7 @@ package models import ( + "github.com/vyes-ai/vigo" "github.com/vyes-ai/vigo/logv" "gorm.io/gorm" ) @@ -11,13 +12,13 @@ const AUSTATUS_APPLYING = "applying" const AUSTATUS_REJECT = "reject" type App struct { - BaseModel + vigo.Model Name string `json:"name" parse:"json"` Icon string `json:"icon" parse:"json"` Des string `json:"des" parse:"json"` Typ string `json:"typ" gorm:"default:public" parse:"json"` Status string `json:"status" gorm:"default:ok" parse:"json"` - InitRoleID *string `json:"init_role_id" gorm:"index;type:varchar(32);default: null" parse:"json"` + InitRoleID *string `json:"init_role_id" gorm:"index;type:varchar(36);default: null" parse:"json"` InitRole *Role `json:"init_role" gorm:"foreignKey:InitRoleID;references:ID"` InitUrl string `json:"init_url" parse:"json"` UserCount uint `json:"user_count" default:"0"` @@ -25,7 +26,7 @@ type App struct { } type AppUser struct { - BaseModel + vigo.Model AppID string `json:"app_id" parse:"path"` App *App `json:"app" gorm:"foreignKey:AppID;references:ID"` @@ -68,7 +69,7 @@ func (m *AppUser) AfterUpdate(tx *gorm.DB) error { } type Resource struct { - BaseModel + vigo.Model AppID string `json:"app_id" parse:"path@app_id"` App *App `json:"-" gorm:"foreignKey:AppID;references:ID"` Name string `json:"name" parse:"json"` @@ -76,7 +77,7 @@ type Resource struct { } type Role struct { - BaseModel + vigo.Model AppID string `json:"app_id" parse:"path@app_id"` App *App `json:"-" gorm:"foreignKey:AppID;references:ID"` Name string `json:"name" parse:"json"` @@ -86,17 +87,17 @@ type Role struct { } type Access struct { - BaseModel - AppID string `json:"app_id" gorm:"index;type:varchar(32)" parse:"path@app_id"` + vigo.Model + AppID string `json:"app_id" gorm:"index;type:varchar(36)" parse:"path@app_id"` App *App `json:"-" gorm:"foreignKey:AppID;references:ID"` - UserID *string `json:"user_id" gorm:"index;type:varchar(32);default: null" parse:"json"` + UserID *string `json:"user_id" gorm:"index;type:varchar(36);default: null" parse:"json"` User *User `json:"-" gorm:"foreignKey:UserID;references:ID"` - RoleID *string `json:"role_id" gorm:"index;type:varchar(32);default: null" parse:"json"` + RoleID *string `json:"role_id" gorm:"index;type:varchar(36);default: null" parse:"json"` Role *Role `json:"-" gorm:"foreignKey:RoleID;references:ID"` - ResourceID *string `json:"resource_id" gorm:"index;type:varchar(32);default: null" parse:"json"` + ResourceID *string `json:"resource_id" gorm:"index;type:varchar(36);default: null" parse:"json"` Resource *Resource `json:"-" gorm:"foreignKey:ResourceID;references:ID"` Name string `json:"name" parse:"json"` diff --git a/models/init.go b/models/init.go index f26c606..74d3613 100644 --- a/models/init.go +++ b/models/init.go @@ -7,34 +7,35 @@ package models import ( - "github.com/veypi/OneAuth/cfg" "strings" - "time" + + "github.com/veypi/OneAuth/cfg" + "github.com/veypi/OneAuth/oauth" "github.com/google/uuid" - "github.com/vyes-ai/vigo/contrib/dbmodels" + "github.com/vyes-ai/vigo" "github.com/vyes-ai/vigo/logv" - "gorm.io/gorm" ) -type BaseModel struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" methods:"get,patch,delete" parse:"path"` - CreatedAt time.Time `json:"created_at" methods:"*list" parse:"query"` - UpdatedAt time.Time `json:"updated_at" methods:"*list" parse:"query"` - DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` -} - -func (m *BaseModel) BeforeCreate(tx *gorm.DB) error { - if m.ID == "" { - m.ID = strings.ReplaceAll(uuid.New().String(), "-", "") - } - return nil -} - -var AllModels = &dbmodels.ModelList{} +var AllModels = &vigo.ModelList{} func init() { AllModels.Append(User{}, AppUser{}, Resource{}, Access{}, Role{}, UserRole{}, Token{}, App{}, SMSCode{}, SMSLog{}) + AllModels.Append( + oauth.User{}, + oauth.UserLoginLog{}, + oauth.OAuthClient{}, + oauth.OAuthAuthorizationCode{}, + oauth.OAuthAccessToken{}, + oauth.OAuthRefreshToken{}, + oauth.OAuthScope{}, + oauth.OAuthClientScope{}, + oauth.OAuthProvider{}, + oauth.OAuthAccount{}, + oauth.UserToken{}, + oauth.UserSession{}, + oauth.OAuthUserConsent{}, + ) } func Migrate() error { @@ -66,7 +67,7 @@ func InitDB() error { for rName, l := range roles { role := &Role{} logv.AssertError(cfg.DB().Where("app_id = ? AND name = ?", app.ID, rName).Attrs(&Role{ - BaseModel: BaseModel{ + Model: vigo.Model{ ID: strings.ReplaceAll(uuid.New().String(), "-", ""), }, AppID: app.ID, @@ -87,5 +88,5 @@ func InitDB() error { if app.InitRoleID == nil { logv.AssertError(cfg.DB().Model(app).Update("init_role_id", adminID).Error) } - return nil + return oauth.InitializeOAuthData(cfg.DB()) } diff --git a/models/sms.go b/models/sms.go index c08a12d..055ff0a 100644 --- a/models/sms.go +++ b/models/sms.go @@ -1,26 +1,24 @@ package models import ( - "gorm.io/gorm" "time" + + "github.com/vyes-ai/vigo" ) // SMSCode 短信验证码记录 type SMSCode struct { - ID uint `gorm:"primarykey" json:"id"` - Phone string `gorm:"index;not null" json:"phone"` // 手机号 - Code string `gorm:"not null" json:"code"` // 验证码 - Region string `gorm:"index;not null" json:"region"` // 区域 - Purpose string `gorm:"index;not null" json:"purpose"` // 用途(注册、登录、重置密码等) - Status CodeStatus `gorm:"default:0" json:"status"` // 状态 - ExpiresAt time.Time `gorm:"index;not null" json:"expires_at"` // 过期时间 - UsedAt *time.Time `gorm:"index" json:"used_at"` // 使用时间 - Attempts int `gorm:"default:0" json:"attempts"` // 验证尝试次数 - SendCount int `gorm:"default:1" json:"send_count"` // 发送次数 - RemoteIP string `gorm:"index" json:"remote_ip"` // 远程IP地址 - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at"` + vigo.Model + Phone string `gorm:"index;type:varchar(20);not null" json:"phone"` // 手机号 + Code string `gorm:"type:varchar(10);not null" json:"code"` // 验证码 + Region string `gorm:"index;type:varchar(10);not null" json:"region"` // 区域 + Purpose string `gorm:"index;type:varchar(20);not null" json:"purpose"` // 用途(注册、登录、重置密码等) + Status CodeStatus `gorm:"default:0" json:"status"` // 状态 + ExpiresAt time.Time `gorm:"index;not null" json:"expires_at"` // 过期时间 + UsedAt *time.Time `gorm:"index" json:"used_at"` // 使用时间 + Attempts int `gorm:"default:0" json:"attempts"` // 验证尝试次数 + SendCount int `gorm:"default:1" json:"send_count"` // 发送次数 + RemoteIP string `gorm:"index;type:varchar(50)" json:"remote_ip"` // 远程IP地址 } // CodeStatus 验证码状态 @@ -35,18 +33,15 @@ const ( // SMSLog 短信发送日志 type SMSLog struct { - ID uint `gorm:"primarykey" json:"id"` - Phone string `gorm:"index;not null" json:"phone"` - Region string `gorm:"index;not null" json:"region"` - Provider string `gorm:"not null" json:"provider"` - MessageID string `gorm:"index" json:"message_id"` // 服务商返回的消息ID - Content string `json:"content"` // 短信内容 - Status string `gorm:"not null" json:"status"` // 发送状态 - Error string `json:"error"` // 错误信息 - Cost float64 `json:"cost"` // 费用 - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at"` + vigo.Model + Phone string `gorm:"index;type:varchar(20);not null" json:"phone"` + Region string `gorm:"index;type:varchar(10);not null" json:"region"` + Provider string `gorm:"type:varchar(20);not null" json:"provider"` + MessageID string `gorm:"index;type:varchar(100)" json:"message_id"` // 服务商返回的消息ID + Content string `gorm:"type:text" json:"content"` // 短信内容 + Status string `gorm:"type:varchar(20);not null" json:"status"` // 发送状态 + Error string `gorm:"type:text" json:"error"` // 错误信息 + Cost float64 `json:"cost"` // 费用 } // IsExpired 检查验证码是否过期 diff --git a/models/token.go b/models/token.go index 65f54f8..7f98eaa 100644 --- a/models/token.go +++ b/models/token.go @@ -1,15 +1,18 @@ package models -import "time" +import ( + "github.com/vyes-ai/vigo" + "time" +) // refresh token,由oa 秘钥签发,有效期长, 存储在token表 // app token, 由app 秘钥签发,有效期短, 不存储 // OverPerm 非oa应用获取oa数据的权限,由用户设定 type Token struct { - BaseModel - UserID string `json:"user_id" gorm:"index;type:varchar(32)" parse:"json"` + vigo.Model + UserID string `json:"user_id" gorm:"index;type:varchar(36)" parse:"json"` User *User `json:"-"` - AppID string `json:"app_id" gorm:"index;type:varchar(32)" parse:"json"` + AppID string `json:"app_id" gorm:"index;type:varchar(36)" parse:"json"` App *App `json:"-"` ExpiredAt time.Time `json:"expired_at" parse:"json"` OverPerm string `json:"over_perm" parse:"json"` diff --git a/models/user.go b/models/user.go index 9c60473..11a2084 100644 --- a/models/user.go +++ b/models/user.go @@ -1,6 +1,7 @@ package models import ( + "github.com/vyes-ai/vigo" "gorm.io/gorm" ) @@ -8,7 +9,7 @@ import ( // salt 32 hex / 16 byte / 128 bit // code 64 hex / 32 byte / 256 bit type User struct { - BaseModel + vigo.Model Username string `json:"username" gorm:"type:varchar(100);unique;default:not null" parse:"json"` Nickname string `json:"nickname" gorm:"type:varchar(100)" parse:"json"` Icon string `json:"icon" parse:"json"` @@ -24,7 +25,7 @@ type User struct { } type UserRole struct { - BaseModel + vigo.Model UserID string `json:"user_id" parse:"path@user_id"` User *User `json:"-" gorm:"foreignKey:UserID;references:ID"` diff --git a/oauth/authorize.go b/oauth/authorize.go index 2b31b82..4042051 100644 --- a/oauth/authorize.go +++ b/oauth/authorize.go @@ -15,13 +15,13 @@ import ( // AuthorizeRequest 授权请求参数 type AuthorizeRequest struct { - ResponseType string `form:"response_type" binding:"required"` - ClientID string `form:"client_id" binding:"required"` - RedirectURI string `form:"redirect_uri" binding:"required"` - Scope string `form:"scope"` - State string `form:"state"` - CodeChallenge string `form:"code_challenge"` - CodeChallengeMethod string `form:"code_challenge_method"` + ResponseType string `json:"response_type" parse:"query"` + ClientID string `json:"client_id" parse:"query"` + RedirectURI string `json:"redirect_uri" parse:"query"` + Scope string `json:"scope" parse:"query"` + State string `json:"state" parse:"query"` + CodeChallenge string `json:"code_challenge" parse:"query"` + CodeChallengeMethod string `json:"code_challenge_method" parse:"query"` } // AuthorizeResponse 授权响应 @@ -34,22 +34,17 @@ type AuthorizeResponse struct { } // handleAuthorize 处理OAuth授权请求 -func handleAuthorize(x *vigo.X) error { - args := &AuthorizeRequest{} - if err := x.Parse(args); err != nil { - return vigo.NewError("参数解析失败").WithError(err).WithCode(400) - } - +func handleAuthorize(x *vigo.X, args *AuthorizeRequest) (any, error) { db := cfg.DB() // 1. 验证响应类型 if args.ResponseType != ResponseTypeCode { errorURI := BuildErrorRedirectURI(args.RedirectURI, ErrorUnsupportedResponseType, "不支持的响应类型", args.State) - return x.JSON(&AuthorizeResponse{ + return &AuthorizeResponse{ Error: "unsupported_response_type", ErrorDesc: "不支持的响应类型", RedirectURI: errorURI, - }) + }, nil } // 2. 验证客户端 @@ -57,28 +52,28 @@ func handleAuthorize(x *vigo.X) error { if err := db.Where("client_id = ? AND is_active = ?", args.ClientID, true).First(&client).Error; err != nil { if err == gorm.ErrRecordNotFound { errorURI := BuildErrorRedirectURI(args.RedirectURI, ErrorInvalidClient, "无效的客户端", args.State) - return x.JSON(&AuthorizeResponse{ + return &AuthorizeResponse{ Error: "invalid_client", ErrorDesc: "无效的客户端", RedirectURI: errorURI, - }) + }, nil } - return vigo.NewError("数据库查询失败").WithError(err).WithCode(500) + return nil, vigo.NewError("数据库查询失败").WithError(err).WithCode(500) } // 3. 验证重定向URI if !client.IsRedirectURIValid(args.RedirectURI) { - return vigo.NewError("无效的重定向URI").WithCode(400) + return nil, vigo.NewError("无效的重定向URI").WithCode(400) } // 4. 验证作用域 if args.Scope != "" && !client.HasScope(args.Scope) { errorURI := BuildErrorRedirectURI(args.RedirectURI, ErrorInvalidScope, "无效的授权范围", args.State) - return x.JSON(&AuthorizeResponse{ + return &AuthorizeResponse{ Error: "invalid_scope", ErrorDesc: "无效的授权范围", RedirectURI: errorURI, - }) + }, nil } // TODO: 在实际应用中,这里应该: @@ -87,48 +82,45 @@ func handleAuthorize(x *vigo.X) error { // 3. 用户同意后生成授权码 // 为了演示,这里假设用户已登录且同意授权 - // 假设当前用户ID (实际应从session或JWT token中获取) + // 假设当前用户ID (实际应从session or JWT token中获取) userID := "demo-user-id" // 5. 生成授权码 code, err := generateRandomString(32) if err != nil { errorURI := BuildErrorRedirectURI(args.RedirectURI, ErrorServerError, "授权码生成失败", args.State) - return x.JSON(&AuthorizeResponse{ + return &AuthorizeResponse{ Error: "server_error", ErrorDesc: "授权码生成失败", RedirectURI: errorURI, - }) + }, nil } - // 6. 创建授权码记录 + // 6. 保存授权码 authCode := &OAuthAuthorizationCode{ Code: code, ClientID: client.ID, UserID: userID, RedirectURI: args.RedirectURI, Scope: args.Scope, + ExpiresAt: time.Now().Add(10 * time.Minute), // 授权码10分钟有效 CodeChallenge: args.CodeChallenge, CodeChallengeMethod: args.CodeChallengeMethod, - ExpiresAt: time.Now().Add(DefaultAuthorizationCodeExpiry), - Used: false, } if err := db.Create(authCode).Error; err != nil { errorURI := BuildErrorRedirectURI(args.RedirectURI, ErrorServerError, "授权码保存失败", args.State) - return x.JSON(&AuthorizeResponse{ + return &AuthorizeResponse{ Error: "server_error", ErrorDesc: "授权码保存失败", RedirectURI: errorURI, - }) + }, nil } - // 7. 构建成功重定向URI - redirectURI := BuildRedirectURI(args.RedirectURI, authCode.Code, args.State) - - return x.JSON(&AuthorizeResponse{ - Code: authCode.Code, + // 7. 返回授权码重定向 + return &AuthorizeResponse{ + Code: code, State: args.State, - RedirectURI: redirectURI, - }) + RedirectURI: BuildRedirectURI(args.RedirectURI, code, args.State), + }, nil } diff --git a/oauth/init.go b/oauth/init.go index e380a37..9e2791a 100644 --- a/oauth/init.go +++ b/oauth/init.go @@ -15,13 +15,13 @@ var Router = vigo.NewRouter() func init() { // OAuth 授权端点 - var _ = Router.Get("/authorize", `OAuth授权端点 - 获取授权码`, AuthorizeRequest{}, handleAuthorize) + var _ = Router.Get("/authorize", "OAuth授权端点 - 获取授权码", vigo.SkipBefore, handleAuthorize) // OAuth 令牌端点 - var _ = Router.Post("/token", `OAuth令牌端点 - 用授权码换取令牌或刷新令牌`, TokenRequest{}, handleToken) + var _ = Router.Post("/token", "OAuth令牌端点 - 用授权码换取令牌或刷新令牌", vigo.SkipBefore, handleToken) // OAuth 撤销端点 - var _ = Router.Post("/revoke", `OAuth撤销端点 - 撤销访问令牌或刷新令牌`, RevokeRequest{}, handleRevoke) + var _ = Router.Post("/revoke", "OAuth撤销端点 - 撤销访问令牌或刷新令牌", vigo.SkipBefore, handleRevoke) } // InitializeOAuthData 初始化OAuth相关的基础数据 diff --git a/oauth/revoke.go b/oauth/revoke.go index 470e608..4b48b31 100644 --- a/oauth/revoke.go +++ b/oauth/revoke.go @@ -13,10 +13,10 @@ import ( // RevokeRequest 撤销令牌请求参数 type RevokeRequest struct { - Token string `form:"token" binding:"required"` - TokenTypeHint string `form:"token_type_hint"` // access_token 或 refresh_token - ClientID string `form:"client_id"` - ClientSecret string `form:"client_secret"` + Token string `parse:"form" binding:"required"` + TokenTypeHint string `parse:"form"` // access_token 或 refresh_token + ClientID string `parse:"form"` + ClientSecret string `parse:"form"` } // RevokeResponse 撤销令牌响应 @@ -26,14 +26,9 @@ type RevokeResponse struct { } // handleRevoke 处理OAuth撤销请求 -func handleRevoke(x *vigo.X) error { - args := &RevokeRequest{} - if err := x.Parse(args); err != nil { - return vigo.NewError("参数解析失败").WithError(err).WithCode(400) - } - +func handleRevoke(x *vigo.X, args *RevokeRequest) (any, error) { if args.Token == "" { - return vigo.NewError("令牌不能为空").WithCode(400) + return nil, vigo.NewError("令牌不能为空").WithCode(400) } db := cfg.DB() @@ -58,8 +53,8 @@ func handleRevoke(x *vigo.X) error { // 根据OAuth 2.0规范,即使令牌不存在也返回成功 // 这样可以防止攻击者通过响应差异推断令牌是否存在 - return x.JSON(&RevokeResponse{ + return &RevokeResponse{ Message: "令牌撤销成功", Success: true, - }) + }, nil } diff --git a/oauth/token.go b/oauth/token.go index d80c6f9..fa3f1fb 100644 --- a/oauth/token.go +++ b/oauth/token.go @@ -19,16 +19,16 @@ import ( // TokenRequest 令牌请求参数 type TokenRequest struct { - GrantType string `form:"grant_type" binding:"required"` - Code string `form:"code"` - RedirectURI string `form:"redirect_uri"` - ClientID string `form:"client_id"` - ClientSecret string `form:"client_secret"` - RefreshToken string `form:"refresh_token"` - CodeVerifier string `form:"code_verifier"` - Username string `form:"username"` // for password grant - Password string `form:"password"` // for password grant - Scope string `form:"scope"` // for password grant + GrantType string `json:"grant_type" parse:"form"` + Code string `json:"code" parse:"form"` + RedirectURI string `json:"redirect_uri" parse:"form"` + ClientID string `json:"client_id" parse:"form"` + ClientSecret string `json:"client_secret" parse:"form"` + RefreshToken string `json:"refresh_token" parse:"form"` + CodeVerifier string `json:"code_verifier" parse:"form"` + Username string `json:"username" parse:"form"` // for password grant + Password string `json:"password" parse:"form"` // for password grant + Scope string `json:"scope" parse:"form"` // for password grant } // TokenResponse 令牌响应 @@ -41,12 +41,7 @@ type TokenResponse struct { } // handleToken 处理OAuth令牌请求 -func handleToken(x *vigo.X) error { - args := &TokenRequest{} - if err := x.Parse(args); err != nil { - return vigo.NewError("参数解析失败").WithError(err).WithCode(400) - } - +func handleToken(x *vigo.X, args *TokenRequest) (any, error) { db := cfg.DB() switch args.GrantType { @@ -57,7 +52,7 @@ func handleToken(x *vigo.X) error { case GrantTypePassword: return handlePasswordGrant(db, x, args) default: - return vigo.NewError("不支持的授权类型").WithCode(400) + return nil, vigo.NewError("不支持的授权类型").WithCode(400) } } diff --git a/oauth/user.go b/oauth/user.go index 1bcc91a..38bbc28 100644 --- a/oauth/user.go +++ b/oauth/user.go @@ -9,13 +9,13 @@ package oauth import ( "time" - "github.com/veypi/OneAuth/models" + "github.com/vyes-ai/vigo" "gorm.io/gorm" ) // User 用户表 type User struct { - models.BaseModel + vigo.Model Username string `json:"username" gorm:"uniqueIndex;not null;size:50;comment:用户名""` Email string `json:"email" gorm:"uniqueIndex;size:100;comment:邮箱地址"` Phone string `json:"phone" gorm:"uniqueIndex;size:20;comment:手机号码"` @@ -42,7 +42,7 @@ type User struct { // Role 角色表 type Role struct { - models.BaseModel + vigo.Model Name string `json:"name" gorm:"uniqueIndex;not null;size:50;comment:角色名称" validate:"required"` DisplayName string `json:"display_name" gorm:"size:100;comment:显示名称"` Description string `json:"description" gorm:"type:text;comment:角色描述"` @@ -57,7 +57,7 @@ type Role struct { // Permission 权限表 type Permission struct { - models.BaseModel + vigo.Model Name string `json:"name" gorm:"uniqueIndex;not null;size:100;comment:权限名称" validate:"required"` DisplayName string `json:"display_name" gorm:"size:100;comment:显示名称"` Description string `json:"description" gorm:"type:text;comment:权限描述"` @@ -98,7 +98,7 @@ type RolePermission struct { // UserLoginLog 用户登录日志表 type UserLoginLog struct { - models.BaseModel + vigo.Model UserID string `json:"user_id" gorm:"not null;type:varchar(32);index;comment:用户ID"` IPAddress string `json:"ip_address" gorm:"size:45;comment:IP地址"` UserAgent string `json:"user_agent" gorm:"type:text;comment:用户代理"` @@ -113,9 +113,6 @@ type UserLoginLog struct { // GORM Hooks func (u *User) BeforeCreate(tx *gorm.DB) error { - if err := u.BaseModel.BeforeCreate(tx); err != nil { - return err - } if u.Locale == "" { u.Locale = "zh-CN" } @@ -175,7 +172,7 @@ func (r *Role) HasPermission(resource, action string) bool { // OAuthClient OAuth客户端表 type OAuthClient struct { - models.BaseModel + vigo.Model ClientID string `json:"client_id" gorm:"uniqueIndex;not null;size:255;comment:客户端ID"` ClientSecret string `json:"-" gorm:"not null;size:255;comment:客户端密钥"` ClientName string `json:"client_name" gorm:"not null;size:255;comment:客户端名称"` @@ -201,7 +198,7 @@ type OAuthClient struct { // OAuthAuthorizationCode 授权码表 type OAuthAuthorizationCode struct { - models.BaseModel + vigo.Model Code string `json:"code" gorm:"uniqueIndex;not null;size:255;comment:授权码"` ClientID string `json:"client_id" gorm:"not null;type:varchar(32);index;comment:客户端ID"` UserID string `json:"user_id" gorm:"not null;type:varchar(32);index;comment:用户ID"` @@ -219,7 +216,7 @@ type OAuthAuthorizationCode struct { // OAuthAccessToken 访问令牌表 type OAuthAccessToken struct { - models.BaseModel + vigo.Model Token string `json:"token" gorm:"uniqueIndex;not null;size:500;comment:访问令牌"` ClientID string `json:"client_id" gorm:"not null;type:varchar(32);index;comment:客户端ID"` UserID string `json:"user_id" gorm:"not null;type:varchar(32);index;comment:用户ID"` @@ -235,7 +232,7 @@ type OAuthAccessToken struct { // OAuthRefreshToken 刷新令牌表 type OAuthRefreshToken struct { - models.BaseModel + vigo.Model Token string `json:"token" gorm:"uniqueIndex;not null;size:500;comment:刷新令牌"` AccessTokenID string `json:"access_token_id" gorm:"type:varchar(32);uniqueIndex;comment:访问令牌ID"` ClientID string `json:"client_id" gorm:"not null;type:varchar(32);index;comment:客户端ID"` @@ -252,7 +249,7 @@ type OAuthRefreshToken struct { // OAuthScope OAuth授权范围表 type OAuthScope struct { - models.BaseModel + vigo.Model Name string `json:"name" gorm:"uniqueIndex;not null;size:100;comment:范围名称"` DisplayName string `json:"display_name" gorm:"size:100;comment:显示名称"` Description string `json:"description" gorm:"type:text;comment:范围描述"` @@ -272,7 +269,7 @@ type OAuthClientScope struct { // OAuthProvider 第三方OAuth提供商表(用于OAuth客户端模式) type OAuthProvider struct { - models.BaseModel + vigo.Model Name string `json:"name" gorm:"uniqueIndex;not null;size:100;comment:提供商名称"` DisplayName string `json:"display_name" gorm:"size:100;comment:显示名称"` ClientID string `json:"client_id" gorm:"not null;size:255;comment:客户端ID"` @@ -289,7 +286,7 @@ type OAuthProvider struct { // OAuthAccount 用户OAuth账户表(第三方登录) type OAuthAccount struct { - models.BaseModel + vigo.Model UserID string `json:"user_id" gorm:"not null;type:varchar(32);index;comment:用户ID"` ProviderID string `json:"provider_id" gorm:"not null;type:varchar(32);index;comment:提供商ID"` ProviderUserID string `json:"provider_user_id" gorm:"not null;size:255;comment:提供商用户ID"` @@ -308,7 +305,7 @@ type OAuthAccount struct { // UserToken 用户令牌表(API令牌等) type UserToken struct { - models.BaseModel + vigo.Model UserID string `json:"user_id" gorm:"not null;type:varchar(32);index;comment:用户ID"` TokenType string `json:"token_type" gorm:"not null;size:50;comment:令牌类型"` // api, session, etc. Token string `json:"token" gorm:"uniqueIndex;not null;size:500;comment:令牌值"` @@ -325,7 +322,7 @@ type UserToken struct { // UserSession 用户会话表 type UserSession struct { - models.BaseModel + vigo.Model UserID string `json:"user_id" gorm:"not null;type:varchar(32);index;comment:用户ID"` SessionID string `json:"session_id" gorm:"uniqueIndex;not null;size:255;comment:会话ID"` IPAddress string `json:"ip_address" gorm:"size:45;comment:IP地址"` @@ -340,7 +337,7 @@ type UserSession struct { // OAuthUserConsent 用户授权同意表 type OAuthUserConsent struct { - models.BaseModel + vigo.Model UserID string `json:"user_id" gorm:"not null;type:varchar(32);index;comment:用户ID"` ClientID string `json:"client_id" gorm:"not null;type:varchar(32);index;comment:客户端ID"` Scope string `json:"scope" gorm:"type:text;comment:授权范围"` diff --git a/ui/assets/vyes.min.js b/ui/assets/vyes.min.js index 6447a51..e037a3b 100644 --- a/ui/assets/vyes.min.js +++ b/ui/assets/vyes.min.js @@ -1 +1 @@ -var t;t=function(){const t=[],e=[];function n(){return`${performance.now().toString(36)}-${Math.random().toString(36).substring(2,5)}`}setInterval((()=>{let n=new Set(e.splice(0)),o=0;for(let e of n)t[e]&&(window.vdev||t[e](),o++);return o}),25),window.$vupdate=e=>{t[e]()};var o=[];const r=Symbol("isProxy"),i=Symbol("DataID"),s=Symbol("bind"),a=Symbol("root"),c=Symbol("root arg");function l(t,e){t[a]=e,Object.keys(e).forEach((e=>{e in t||(t[e]=c)}))}function u(t){return!(!t||"object"!=typeof t||t instanceof Node||t instanceof Date||t instanceof RegExp||t instanceof Event||t.t||t.constructor!==Object&&t.constructor!==Array)}function f(t,e){if(!t||!t[r]||!u(e))return e;let n=t[s];if(!e[r])return Object.keys(t).forEach((n=>{void 0===e[n]&&delete t[n]})),Object.keys(e).forEach((n=>{t[n]?.[r]?t[n]=f(t[n],e[n]):t[n]=e[n]})),t;if(e[i]===t[i])return e;for(let o in n)if(e[s][o]?.indexOf)for(let t of n[o])-1===e[s][o].indexOf(t)&&e[s][o].push(t);else e[s][o]=n[o];for(let o in e)o in t&&t[o]?.[r]&&(e[o]=f(t[o],e[o]));return e}const h={console,window,prompt:prompt.bind(window),alert:alert.bind(window),confirm:confirm.bind(window),RegExp,document,Array,Object,Math,Date,JSON,Symbol,Number,eval,isNaN,parseInt,parseFloat,setTimeout:setTimeout.bind(window),setInterval:setInterval.bind(window),clearTimeout:clearTimeout.bind(window),clearInterval:clearInterval.bind(window),encodeURIComponent,btoa:btoa.bind(window),fetch:fetch.bind(window),TextDecoder,history,requestAnimationFrame:requestAnimationFrame.bind(window)};function d(t,e,n){const o=new Proxy(t,{has:(t,e)=>!0,get(o,r,i){let s;return"$data"===r?s=t:"$env"===r?s=e:r in o?s=Reflect.get(o,r,i):r in e?s=e[r]:n&&r in n?s=n[r]:r in h?s=h[r]:r in window&&(s=window[r]),s},set:(t,e,n,o)=>Reflect.set(t,e,n,o)});return o}const p=Object.getPrototypeOf((async function(){})).constructor;function m(t,e){if(t.startsWith("/"))return t;const n=e.substring(0,e.lastIndexOf("/")).split("/").filter((t=>""!==t)),o=t.split("/").filter((t=>""!==t));for(const r of o)if(".."===r)n.length>0&&n.pop();else{if("."===r)continue;n.push(r)}return"/"+n.join("/")}const w={Wrap:function h(d,p=void 0){const m=n();let w=!1;"[object Array]"==={}.toString.call(d)&&(w=!0),p&&l(d,p),d[i]=m;const y={},b={get(t,e,n){if(e===i)return m;if(e===r)return!0;if(e===s)return y;const l=Reflect.get(t,e,n);if(l===c)return t[a][e];if("symbol"==typeof e)return l;let f=-1;if(o.length>0){let t=e;f=o[o.length-1],w&&(t=""),y.hasOwnProperty(t)?-1==y[t].indexOf(f)&&y[t].push(f):y[t]=[f]}if(window.vdev,u(l)&&!l[r]){let o=h(l,void 0);return Reflect.set(t,e,o,n),o}return l},set(n,i,s,l){const h=Reflect.get(n,i,l);if(h===c)return n[a][i]=s,!0;if(h===s)return!0;let d=!0;if(Array.isArray(s)&&Array.isArray(h)?(h.length=0,h.push(...s)):h&&h[r]&&u(s)?(s=f(h,s),d=Reflect.set(n,i,s,l)):d=Reflect.set(n,i,s,l),d&&0===o.length){let n=i;if(w&&(n=""),y[n]){let o=0;for(;o{n(e())})):t.push(e);try{r=e()}catch(b){}finally{o.pop()}return"function"==typeof n&&n(r),i},Cancel:function(e){e>=0&&et.trim()))}const i=await import(t);"string"==typeof o?i.default?e[o]=i.default:e[o]=i:o.forEach((t=>{t in i?e[t]=i[t]:t in i.default&&(e[t]=i.default[t])}))}catch(l){}}return s.trim()}};class y{constructor(){this.events={}}on(t,e,n=null){if("function"!=typeof e)throw Error("\u56de\u8c03\u51fd\u6570\u5fc5\u987b\u662f\u4e00\u4e2a\u51fd\u6570");this.events[t]||(this.events[t]=[]);const o={callback:e,context:n};return this.events[t].push(o),()=>this.off(t,e,n)}once(t,e,n=null){const o=(...r)=>{this.off(t,o,n),e.apply(n,r)};return this.on(t,o,n)}off(t,e=null,n=null){this.events[t]&&(e?(this.events[t]=this.events[t].filter((t=>!(t.callback===e&&t.context===n))),0===this.events[t].length&&delete this.events[t]):delete this.events[t])}emit(t,...e){this.events[t]&&[...this.events[t]].forEach((t=>{try{t.callback.apply(t.context,e)}catch(n){}}))}listenerCount(t){return this.events[t]?this.events[t].length:0}eventNames(){return Object.keys(this.events)}removeAllListeners(){this.events={}}hasListeners(t){return this.listenerCount(t)>0}}function b(t,e){return function(){return t.apply(e,arguments)}}const{toString:v}=Object.prototype,{getPrototypeOf:g}=Object,{iterator:x,toStringTag:R}=Symbol,O=(k=Object.create(null),t=>{const e=v.call(t);return k[e]||(k[e]=e.slice(8,-1).toLowerCase())});var k;const T=t=>(t=t.toLowerCase(),e=>O(e)===t),E=t=>e=>typeof e===t,{isArray:S}=Array,A=E("undefined"),j=T("ArrayBuffer"),$=E("string"),N=E("function"),P=E("number"),C=t=>null!==t&&"object"==typeof t,U=t=>{if("object"!==O(t))return!1;const e=g(t);return!(null!==e&&e!==Object.prototype&&null!==Object.getPrototypeOf(e)||R in t||x in t)},F=T("Date"),D=T("File"),L=T("Blob"),I=T("FileList"),z=T("URLSearchParams"),[M,q,B,_]=["ReadableStream","Request","Response","Headers"].map(T);function H(t,e,{allOwnKeys:n=!1}={}){if(null==t)return;let o,r;if("object"!=typeof t&&(t=[t]),S(t))for(o=0,r=t.length;r>o;o++)e.call(null,t[o],o,t);else{const r=n?Object.getOwnPropertyNames(t):Object.keys(t),i=r.length;let s;for(o=0;i>o;o++)s=r[o],e.call(null,t[s],s,t)}}function V(t,e){e=e.toLowerCase();const n=Object.keys(t);let o,r=n.length;for(;r-- >0;)if(o=n[r],e===o.toLowerCase())return o;return null}const X="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,J=t=>!A(t)&&t!==X,W=(K="undefined"!=typeof Uint8Array&&g(Uint8Array),t=>K&&t instanceof K);var K;const G=T("HTMLFormElement"),Z=(({hasOwnProperty:t})=>(e,n)=>t.call(e,n))(Object.prototype),Y=T("RegExp"),Q=(t,e)=>{const n=Object.getOwnPropertyDescriptors(t),o={};H(n,((n,r)=>{let i;!1!==(i=e(n,r,t))&&(o[r]=i||n)})),Object.defineProperties(t,o)},tt=T("AsyncFunction"),et=(nt="function"==typeof setImmediate,ot=N(X.postMessage),nt?setImmediate:ot?(rt="axios@"+Math.random(),it=[],X.addEventListener("message",(({source:t,data:e})=>{t===X&&e===rt&&it.length&&it.shift()()}),!1),t=>{it.push(t),X.postMessage(rt,"*")}):t=>setTimeout(t));var nt,ot,rt,it;const st="undefined"!=typeof queueMicrotask?queueMicrotask.bind(X):"undefined"!=typeof process&&process.nextTick||et,at={isArray:S,isArrayBuffer:j,isBuffer:function(t){return null!==t&&!A(t)&&null!==t.constructor&&!A(t.constructor)&&N(t.constructor.isBuffer)&&t.constructor.isBuffer(t)},isFormData:t=>{let e;return t&&("function"==typeof FormData&&t instanceof FormData||N(t.append)&&("formdata"===(e=O(t))||"object"===e&&N(t.toString)&&"[object FormData]"===t.toString()))},isArrayBufferView:function(t){let e;return e="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(t):t&&t.buffer&&j(t.buffer),e},isString:$,isNumber:P,isBoolean:t=>!0===t||!1===t,isObject:C,isPlainObject:U,isReadableStream:M,isRequest:q,isResponse:B,isHeaders:_,isUndefined:A,isDate:F,isFile:D,isBlob:L,isRegExp:Y,isFunction:N,isStream:t=>C(t)&&N(t.pipe),isURLSearchParams:z,isTypedArray:W,isFileList:I,forEach:H,merge:function t(){const{caseless:e}=J(this)&&this||{},n={},o=(o,r)=>{const i=e&&V(n,r)||r;U(n[i])&&U(o)?n[i]=t(n[i],o):U(o)?n[i]=t({},o):S(o)?n[i]=o.slice():n[i]=o};for(let r=0,i=arguments.length;i>r;r++)arguments[r]&&H(arguments[r],o);return n},extend:(t,e,n,{allOwnKeys:o}={})=>(H(e,((e,o)=>{n&&N(e)?t[o]=b(e,n):t[o]=e}),{allOwnKeys:o}),t),trim:t=>t.trim?t.trim():t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:t=>(65279===t.charCodeAt(0)&&(t=t.slice(1)),t),inherits:(t,e,n,o)=>{t.prototype=Object.create(e.prototype,o),t.prototype.constructor=t,Object.defineProperty(t,"super",{value:e.prototype}),n&&Object.assign(t.prototype,n)},toFlatObject:(t,e,n,o)=>{let r,i,s;const a={};if(e=e||{},null==t)return e;do{for(r=Object.getOwnPropertyNames(t),i=r.length;i-- >0;)s=r[i],o&&!o(s,t,e)||a[s]||(e[s]=t[s],a[s]=!0);t=!1!==n&&g(t)}while(t&&(!n||n(t,e))&&t!==Object.prototype);return e},kindOf:O,kindOfTest:T,endsWith:(t,e,n)=>{t+="",(void 0===n||n>t.length)&&(n=t.length),n-=e.length;const o=t.indexOf(e,n);return-1!==o&&o===n},toArray:t=>{if(!t)return null;if(S(t))return t;let e=t.length;if(!P(e))return null;const n=Array(e);for(;e-- >0;)n[e]=t[e];return n},forEachEntry:(t,e)=>{const n=(t&&t[x]).call(t);let o;for(;(o=n.next())&&!o.done;){const n=o.value;e.call(t,n[0],n[1])}},matchAll:(t,e)=>{let n;const o=[];for(;null!==(n=t.exec(e));)o.push(n);return o},isHTMLForm:G,hasOwnProperty:Z,hasOwnProp:Z,reduceDescriptors:Q,freezeMethods:t=>{Q(t,((e,n)=>{if(N(t)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const o=t[n];N(o)&&(e.enumerable=!1,"writable"in e?e.writable=!1:e.set||(e.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))}))},toObjectSet:(t,e)=>{const n={},o=t=>{t.forEach((t=>{n[t]=!0}))};return S(t)?o(t):o((t+"").split(e)),n},toCamelCase:t=>t.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(t,e,n){return e.toUpperCase()+n})),noop:()=>{},toFiniteNumber:(t,e)=>null!=t&&Number.isFinite(t=+t)?t:e,findKey:V,global:X,isContextDefined:J,isSpecCompliantForm:function(t){return!!(t&&N(t.append)&&"FormData"===t[R]&&t[x])},toJSONObject:t=>{const e=[,,,,,,,,,,],n=(t,o)=>{if(C(t)){if(e.indexOf(t)>=0)return;if(!("toJSON"in t)){e[o]=t;const r=S(t)?[]:{};return H(t,((t,e)=>{const i=n(t,o+1);!A(i)&&(r[e]=i)})),e[o]=void 0,r}}return t};return n(t,0)},isAsyncFn:tt,isThenable:t=>t&&(C(t)||N(t))&&N(t.then)&&N(t.catch),setImmediate:et,asap:st,isIterable:t=>null!=t&&N(t[x])};function ct(t,e,n,o,r){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=Error().stack,this.message=t,this.name="AxiosError",e&&(this.code=e),n&&(this.config=n),o&&(this.request=o),r&&(this.response=r,this.status=r.status?r.status:null)}at.inherits(ct,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:at.toJSONObject(this.config),code:this.code,status:this.status}}});const lt=ct.prototype,ut={};function ft(t){return at.isPlainObject(t)||at.isArray(t)}function ht(t){return at.endsWith(t,"[]")?t.slice(0,-2):t}function dt(t,e,n){return t?t.concat(e).map((function(t,e){return t=ht(t),!n&&e?"["+t+"]":t})).join(n?".":""):e}["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((t=>{ut[t]={value:t}})),Object.defineProperties(ct,ut),Object.defineProperty(lt,"isAxiosError",{value:!0}),ct.from=(t,e,n,o,r,i)=>{const s=Object.create(lt);return at.toFlatObject(t,s,(function(t){return t!==Error.prototype}),(t=>"isAxiosError"!==t)),ct.call(s,t.message,e,n,o,r),s.cause=t,s.name=t.name,i&&Object.assign(s,i),s};const pt=at.toFlatObject(at,{},null,(function(t){return/^is[A-Z]/.test(t)}));function mt(t,e,n){if(!at.isObject(t))throw new TypeError("target must be an object");e=e||new FormData;const o=(n=at.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(t,e){return!at.isUndefined(e[t])}))).metaTokens,r=n.visitor||l,i=n.dots,s=n.indexes,a=(n.Blob||"undefined"!=typeof Blob&&Blob)&&at.isSpecCompliantForm(e);if(!at.isFunction(r))throw new TypeError("visitor must be a function");function c(t){if(null===t)return"";if(at.isDate(t))return t.toISOString();if(at.isBoolean(t))return t.toString();if(!a&&at.isBlob(t))throw new ct("Blob is not supported. Use a Buffer instead.");return at.isArrayBuffer(t)||at.isTypedArray(t)?a&&"function"==typeof Blob?new Blob([t]):Buffer.from(t):t}function l(t,n,r){let a=t;if(t&&!r&&"object"==typeof t)if(at.endsWith(n,"{}"))n=o?n:n.slice(0,-2),t=JSON.stringify(t);else if(at.isArray(t)&&function(t){return at.isArray(t)&&!t.some(ft)}(t)||(at.isFileList(t)||at.endsWith(n,"[]"))&&(a=at.toArray(t)))return n=ht(n),a.forEach((function(t,o){!at.isUndefined(t)&&null!==t&&e.append(!0===s?dt([n],o,i):null===s?n:n+"[]",c(t))})),!1;return!!ft(t)||(e.append(dt(r,n,i),c(t)),!1)}const u=[],f=Object.assign(pt,{defaultVisitor:l,convertValue:c,isVisitable:ft});if(!at.isObject(t))throw new TypeError("data must be an object");return function t(n,o){if(!at.isUndefined(n)){if(-1!==u.indexOf(n))throw Error("Circular reference detected in "+o.join("."));u.push(n),at.forEach(n,(function(n,i){!0===(!(at.isUndefined(n)||null===n)&&r.call(e,n,at.isString(i)?i.trim():i,o,f))&&t(n,o?o.concat(i):[i])})),u.pop()}}(t),e}function wt(t){const e={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(t).replace(/[!'()~]|%20|%00/g,(function(t){return e[t]}))}function yt(t,e){this.o=[],t&&mt(t,this,e)}const bt=yt.prototype;function vt(t){return encodeURIComponent(t).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function gt(t,e,n){if(!e)return t;const o=n&&n.encode||vt;at.isFunction(n)&&(n={serialize:n});const r=n&&n.serialize;let i;if(i=r?r(e,n):at.isURLSearchParams(e)?e.toString():new yt(e,n).toString(o),i){const e=t.indexOf("#");-1!==e&&(t=t.slice(0,e)),t+=(-1===t.indexOf("?")?"?":"&")+i}return t}bt.append=function(t,e){this.o.push([t,e])},bt.toString=function(t){const e=t?function(e){return t.call(this,e,wt)}:wt;return this.o.map((function(t){return e(t[0])+"="+e(t[1])}),"").join("&")};const xt=class{constructor(){this.handlers=[]}use(t,e,n){return this.handlers.push({fulfilled:t,rejected:e,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){at.forEach(this.handlers,(function(e){null!==e&&t(e)}))}},Rt={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},Ot={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:yt,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]},kt="undefined"!=typeof window&&"undefined"!=typeof document,Tt="object"==typeof navigator&&navigator||void 0,Et=kt&&(!Tt||0>["ReactNative","NativeScript","NS"].indexOf(Tt.product)),St="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts,At=kt&&window.location.href||"http://localhost",jt={...Object.freeze({__proto__:null,hasBrowserEnv:kt,hasStandardBrowserWebWorkerEnv:St,hasStandardBrowserEnv:Et,navigator:Tt,origin:At}),...Ot};function $t(t){function e(t,n,o,r){let i=t[r++];if("__proto__"===i)return!0;const s=Number.isFinite(+i),a=r>=t.length;return i=!i&&at.isArray(o)?o.length:i,a?(at.hasOwnProp(o,i)?o[i]=[o[i],n]:o[i]=n,!s):(o[i]&&at.isObject(o[i])||(o[i]=[]),e(t,n,o[i],r)&&at.isArray(o[i])&&(o[i]=function(t){const e={},n=Object.keys(t);let o;const r=n.length;let i;for(o=0;r>o;o++)i=n[o],e[i]=t[i];return e}(o[i])),!s)}if(at.isFormData(t)&&at.isFunction(t.entries)){const n={};return at.forEachEntry(t,((t,o)=>{e(function(t){return at.matchAll(/\w+|\[(\w*)]/g,t).map((t=>"[]"===t[0]?"":t[1]||t[0]))}(t),o,n,0)})),n}return null}const Nt={transitional:Rt,adapter:["xhr","http","fetch"],transformRequest:[function(t,e){const n=e.getContentType()||"",o=n.indexOf("application/json")>-1,r=at.isObject(t);if(r&&at.isHTMLForm(t)&&(t=new FormData(t)),at.isFormData(t))return o?JSON.stringify($t(t)):t;if(at.isArrayBuffer(t)||at.isBuffer(t)||at.isStream(t)||at.isFile(t)||at.isBlob(t)||at.isReadableStream(t))return t;if(at.isArrayBufferView(t))return t.buffer;if(at.isURLSearchParams(t))return e.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let i;if(r){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(t,e){return mt(t,new jt.classes.URLSearchParams,Object.assign({visitor:function(t,e,n,o){return jt.isNode&&at.isBuffer(t)?(this.append(e,t.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)}},e))}(t,this.formSerializer).toString();if((i=at.isFileList(t))||n.indexOf("multipart/form-data")>-1){const e=this.env&&this.env.FormData;return mt(i?{"files[]":t}:t,e&&new e,this.formSerializer)}}return r||o?(e.setContentType("application/json",!1),function(t){if(at.isString(t))try{return(0,JSON.parse)(t),at.trim(t)}catch(t){if("SyntaxError"!==t.name)throw t}return(0,JSON.stringify)(t)}(t)):t}],transformResponse:[function(t){const e=this.transitional||Nt.transitional,n=e&&e.forcedJSONParsing,o="json"===this.responseType;if(at.isResponse(t)||at.isReadableStream(t))return t;if(t&&at.isString(t)&&(n&&!this.responseType||o)){const n=!(e&&e.silentJSONParsing)&&o;try{return JSON.parse(t)}catch(t){if(n){if("SyntaxError"===t.name)throw ct.from(t,ct.ERR_BAD_RESPONSE,this,null,this.response);throw t}}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:jt.classes.FormData,Blob:jt.classes.Blob},validateStatus:function(t){return t>=200&&300>t},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};at.forEach(["delete","get","head","post","put","patch"],(t=>{Nt.headers[t]={}}));const Pt=Nt,Ct=at.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Ut=Symbol("internals");function Ft(t){return t&&(t+"").trim().toLowerCase()}function Dt(t){return!1===t||null==t?t:at.isArray(t)?t.map(Dt):t+""}function Lt(t,e,n,o,r){return at.isFunction(o)?o.call(this,e,n):(r&&(e=n),at.isString(e)?at.isString(o)?-1!==e.indexOf(o):at.isRegExp(o)?o.test(e):void 0:void 0)}class It{constructor(t){t&&this.set(t)}set(t,e,n){const o=this;function r(t,e,n){const r=Ft(e);if(!r)throw Error("header name must be a non-empty string");const i=at.findKey(o,r);(!i||void 0===o[i]||!0===n||void 0===n&&!1!==o[i])&&(o[i||e]=Dt(t))}const i=(t,e)=>at.forEach(t,((t,n)=>r(t,n,e)));if(at.isPlainObject(t)||t instanceof this.constructor)i(t,e);else if(at.isString(t)&&(t=t.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(t.trim()))i((t=>{const e={};let n,o,r;return t&&t.split("\n").forEach((function(t){r=t.indexOf(":"),n=t.substring(0,r).trim().toLowerCase(),o=t.substring(r+1).trim(),!n||e[n]&&Ct[n]||("set-cookie"===n?e[n]?e[n].push(o):e[n]=[o]:e[n]=e[n]?e[n]+", "+o:o)})),e})(t),e);else if(at.isObject(t)&&at.isIterable(t)){let n,o,r={};for(const e of t){if(!at.isArray(e))throw TypeError("Object iterator must return a key-value pair");r[o=e[0]]=(n=r[o])?at.isArray(n)?[...n,e[1]]:[n,e[1]]:e[1]}i(r,e)}else null!=t&&r(e,t,n);return this}get(t,e){if(t=Ft(t)){const n=at.findKey(this,t);if(n){const t=this[n];if(!e)return t;if(!0===e)return function(t){const e=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let o;for(;o=n.exec(t);)e[o[1]]=o[2];return e}(t);if(at.isFunction(e))return e.call(this,t,n);if(at.isRegExp(e))return e.exec(t);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,e){if(t=Ft(t)){const n=at.findKey(this,t);return!(!n||void 0===this[n]||e&&!Lt(0,this[n],n,e))}return!1}delete(t,e){const n=this;let o=!1;function r(t){if(t=Ft(t)){const r=at.findKey(n,t);!r||e&&!Lt(0,n[r],r,e)||(delete n[r],o=!0)}}return at.isArray(t)?t.forEach(r):r(t),o}clear(t){const e=Object.keys(this);let n=e.length,o=!1;for(;n--;){const r=e[n];t&&!Lt(0,this[r],r,t,!0)||(delete this[r],o=!0)}return o}normalize(t){const e=this,n={};return at.forEach(this,((o,r)=>{const i=at.findKey(n,r);if(i)return e[i]=Dt(o),void delete e[r];const s=t?function(t){return t.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,((t,e,n)=>e.toUpperCase()+n))}(r):(r+"").trim();s!==r&&delete e[r],e[s]=Dt(o),n[s]=!0})),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const e=Object.create(null);return at.forEach(this,((n,o)=>{null!=n&&!1!==n&&(e[o]=t&&at.isArray(n)?n.join(", "):n)})),e}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map((([t,e])=>t+": "+e)).join("\n")}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...e){const n=new this(t);return e.forEach((t=>n.set(t))),n}static accessor(t){const e=(this[Ut]=this[Ut]={accessors:{}}).accessors,n=this.prototype;function o(t){const o=Ft(t);e[o]||(function(t,e){const n=at.toCamelCase(" "+e);["get","set","has"].forEach((o=>{Object.defineProperty(t,o+n,{value:function(t,n,r){return this[o].call(this,e,t,n,r)},configurable:!0})}))}(n,t),e[o]=!0)}return at.isArray(t)?t.forEach(o):o(t),this}}It.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),at.reduceDescriptors(It.prototype,(({value:t},e)=>{let n=e[0].toUpperCase()+e.slice(1);return{get:()=>t,set(t){this[n]=t}}})),at.freezeMethods(It);const zt=It;function Mt(t,e){const n=this||Pt,o=e||n,r=zt.from(o.headers);let i=o.data;return at.forEach(t,(function(t){i=t.call(n,i,r.normalize(),e?e.status:void 0)})),r.normalize(),i}function qt(t){return!(!t||!t.i)}function Bt(t,e,n){ct.call(this,t??"canceled",ct.ERR_CANCELED,e,n),this.name="CanceledError"}function _t(t,e,n){const o=n.config.validateStatus;n.status&&o&&!o(n.status)?e(new ct("Request failed with status code "+n.status,[ct.ERR_BAD_REQUEST,ct.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):t(n)}at.inherits(Bt,ct,{i:!0});const Ht=(t,e,n=3)=>{let o=0;const r=function(t,e){const n=Array(t=t||10),o=Array(t);let r,i=0,s=0;return e=void 0!==e?e:1e3,function(a){const c=Date.now(),l=o[s];r||(r=c),n[i]=a,o[i]=c;let u=s,f=0;for(;u!==i;)f+=n[u++],u%=t;if(i=(i+1)%t,i===s&&(s=(s+1)%t),e>c-r)return;const h=l&&c-l;return h?Math.round(1e3*f/h):void 0}}(50,250);return function(t,e){let n,o,r=0,i=1e3/e;const s=(e,i=Date.now())=>{r=i,n=null,o&&(clearTimeout(o),o=null),t.apply(null,e)};return[(...t)=>{const e=Date.now(),a=e-r;i>a?(n=t,o||(o=setTimeout((()=>{o=null,s(n)}),i-a))):s(t,e)},()=>n&&s(n)]}((n=>{const i=n.loaded,s=n.lengthComputable?n.total:void 0,a=i-o,c=r(a);o=i,t({loaded:i,total:s,progress:s?i/s:void 0,bytes:a,rate:c||void 0,estimated:c&&s&&s>=i?(s-i)/c:void 0,event:n,lengthComputable:null!=s,[e?"download":"upload"]:!0})}),n)},Vt=(t,e)=>{const n=null!=t;return[o=>e[0]({lengthComputable:n,total:t,loaded:o}),e[1]]},Xt=t=>(...e)=>at.asap((()=>t(...e))),Jt=jt.hasStandardBrowserEnv?((t,e)=>n=>(n=new URL(n,jt.origin),t.protocol===n.protocol&&t.host===n.host&&(e||t.port===n.port)))(new URL(jt.origin),jt.navigator&&/(msie|trident)/i.test(jt.navigator.userAgent)):()=>!0,Wt=jt.hasStandardBrowserEnv?{write(t,e,n,o,r,i){const s=[t+"="+encodeURIComponent(e)];at.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),at.isString(o)&&s.push("path="+o),at.isString(r)&&s.push("domain="+r),!0===i&&s.push("secure"),document.cookie=s.join("; ")},read(t){const e=document.cookie.match(RegExp("(^|;\\s*)("+t+")=([^;]*)"));return e?decodeURIComponent(e[3]):null},remove(t){this.write(t,"",Date.now()-864e5)}}:{write(){},read:()=>null,remove(){}};function Kt(t,e,n){return!t||/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)&&0!=n?e:function(t,e){return e?t.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):t}(t,e)}const Gt=t=>t instanceof zt?{...t}:t;function Zt(t,e){e=e||{};const n={};function o(t,e,n,o){return at.isPlainObject(t)&&at.isPlainObject(e)?at.merge.call({caseless:o},t,e):at.isPlainObject(e)?at.merge({},e):at.isArray(e)?e.slice():e}function r(t,e,n,r){return at.isUndefined(e)?at.isUndefined(t)?void 0:o(void 0,t,0,r):o(t,e,0,r)}function i(t,e){if(!at.isUndefined(e))return o(void 0,e)}function s(t,e){return at.isUndefined(e)?at.isUndefined(t)?void 0:o(void 0,t):o(void 0,e)}function a(n,r,i){return i in e?o(n,r):i in t?o(void 0,n):void 0}const c={url:i,method:i,data:i,baseURL:s,transformRequest:s,transformResponse:s,paramsSerializer:s,timeout:s,timeoutMessage:s,withCredentials:s,withXSRFToken:s,adapter:s,responseType:s,xsrfCookieName:s,xsrfHeaderName:s,onUploadProgress:s,onDownloadProgress:s,decompress:s,maxContentLength:s,maxBodyLength:s,beforeRedirect:s,transport:s,httpAgent:s,httpsAgent:s,cancelToken:s,socketPath:s,responseEncoding:s,validateStatus:a,headers:(t,e,n)=>r(Gt(t),Gt(e),0,!0)};return at.forEach(Object.keys(Object.assign({},t,e)),(function(o){const i=c[o]||r,s=i(t[o],e[o],o);at.isUndefined(s)&&i!==a||(n[o]=s)})),n}const Yt=t=>{const e=Zt({},t);let n,{data:o,withXSRFToken:r,xsrfHeaderName:i,xsrfCookieName:s,headers:a,auth:c}=e;if(e.headers=a=zt.from(a),e.url=gt(Kt(e.baseURL,e.url,e.allowAbsoluteUrls),t.params,t.paramsSerializer),c&&a.set("Authorization","Basic "+btoa((c.username||"")+":"+(c.password?unescape(encodeURIComponent(c.password)):""))),at.isFormData(o))if(jt.hasStandardBrowserEnv||jt.hasStandardBrowserWebWorkerEnv)a.setContentType(void 0);else if(!1!==(n=a.getContentType())){const[t,...e]=n?n.split(";").map((t=>t.trim())).filter(Boolean):[];a.setContentType([t||"multipart/form-data",...e].join("; "))}if(jt.hasStandardBrowserEnv&&(r&&at.isFunction(r)&&(r=r(e)),r||!1!==r&&Jt(e.url))){const t=i&&s&&Wt.read(s);t&&a.set(i,t)}return e},Qt="undefined"!=typeof XMLHttpRequest&&function(t){return new Promise((function(e,n){const o=Yt(t);let r=o.data;const i=zt.from(o.headers).normalize();let s,a,c,l,u,{responseType:f,onUploadProgress:h,onDownloadProgress:d}=o;function p(){l&&l(),u&&u(),o.cancelToken&&o.cancelToken.unsubscribe(s),o.signal&&o.signal.removeEventListener("abort",s)}let m=new XMLHttpRequest;function w(){if(!m)return;const o=zt.from("getAllResponseHeaders"in m&&m.getAllResponseHeaders());_t((function(t){e(t),p()}),(function(t){n(t),p()}),{data:f&&"text"!==f&&"json"!==f?m.response:m.responseText,status:m.status,statusText:m.statusText,headers:o,config:t,request:m}),m=null}m.open(o.method.toUpperCase(),o.url,!0),m.timeout=o.timeout,"onloadend"in m?m.onloadend=w:m.onreadystatechange=function(){m&&4===m.readyState&&(0!==m.status||m.responseURL&&0===m.responseURL.indexOf("file:"))&&setTimeout(w)},m.onabort=function(){m&&(n(new ct("Request aborted",ct.ECONNABORTED,t,m)),m=null)},m.onerror=function(){n(new ct("Network Error",ct.ERR_NETWORK,t,m)),m=null},m.ontimeout=function(){let e=o.timeout?"timeout of "+o.timeout+"ms exceeded":"timeout exceeded";const r=o.transitional||Rt;o.timeoutErrorMessage&&(e=o.timeoutErrorMessage),n(new ct(e,r.clarifyTimeoutError?ct.ETIMEDOUT:ct.ECONNABORTED,t,m)),m=null},void 0===r&&i.setContentType(null),"setRequestHeader"in m&&at.forEach(i.toJSON(),(function(t,e){m.setRequestHeader(e,t)})),at.isUndefined(o.withCredentials)||(m.withCredentials=!!o.withCredentials),f&&"json"!==f&&(m.responseType=o.responseType),d&&([c,u]=Ht(d,!0),m.addEventListener("progress",c)),h&&m.upload&&([a,l]=Ht(h),m.upload.addEventListener("progress",a),m.upload.addEventListener("loadend",l)),(o.cancelToken||o.signal)&&(s=e=>{m&&(n(!e||e.type?new Bt(null,t,m):e),m.abort(),m=null)},o.cancelToken&&o.cancelToken.subscribe(s),o.signal&&(o.signal.aborted?s():o.signal.addEventListener("abort",s)));const y=function(t){const e=/^([-+\w]{1,25})(:?\/\/|:)/.exec(t);return e&&e[1]||""}(o.url);y&&-1===jt.protocols.indexOf(y)?n(new ct("Unsupported protocol "+y+":",ct.ERR_BAD_REQUEST,t)):m.send(r||null)}))},te=(t,e)=>{const{length:n}=t=t?t.filter(Boolean):[];if(e||n){let n,o=new AbortController;const r=function(t){if(!n){n=!0,s();const e=t instanceof Error?t:this.reason;o.abort(e instanceof ct?e:new Bt(e instanceof Error?e.message:e))}};let i=e&&setTimeout((()=>{i=null,r(new ct(`timeout ${e} of ms exceeded`,ct.ETIMEDOUT))}),e);const s=()=>{t&&(i&&clearTimeout(i),i=null,t.forEach((t=>{t.unsubscribe?t.unsubscribe(r):t.removeEventListener("abort",r)})),t=null)};t.forEach((t=>t.addEventListener("abort",r)));const{signal:a}=o;return a.unsubscribe=()=>at.asap(s),a}},ee=function*(t,e){let n=t.byteLength;if(e>n)return void(yield t);let o,r=0;for(;n>r;)o=r+e,yield t.slice(r,o),r=o},ne=(t,e,n,o)=>{const r=async function*(t,e){for await(const n of async function*(t){if(t[Symbol.asyncIterator])return void(yield*t);const e=t.getReader();try{for(;;){const{done:t,value:n}=await e.read();if(t)break;yield n}}finally{await e.cancel()}}(t))yield*ee(n,e)}(t,e);let i,s=0,a=t=>{i||(i=!0,o&&o(t))};return new ReadableStream({async pull(t){try{const{done:e,value:o}=await r.next();if(e)return a(),void t.close();let i=o.byteLength;if(n){let t=s+=i;n(t)}t.enqueue(new Uint8Array(o))}catch(t){throw a(t),t}},cancel:t=>(a(t),r.return())},{highWaterMark:2})},oe="function"==typeof fetch&&"function"==typeof Request&&"function"==typeof Response,re=oe&&"function"==typeof ReadableStream,ie=oe&&("function"==typeof TextEncoder?(se=new TextEncoder,t=>se.encode(t)):async t=>new Uint8Array(await new Response(t).arrayBuffer()));var se;const ae=(t,...e)=>{try{return!!t(...e)}catch(t){return!1}},ce=re&&ae((()=>{let t=!1;const e=new Request(jt.origin,{body:new ReadableStream,method:"POST",get duplex(){return t=!0,"half"}}).headers.has("Content-Type");return t&&!e})),le=re&&ae((()=>at.isReadableStream(new Response("").body))),ue={stream:le&&(t=>t.body)};var fe;oe&&(fe=new Response,["text","arrayBuffer","blob","formData","stream"].forEach((t=>{!ue[t]&&(ue[t]=at.isFunction(fe[t])?e=>e[t]():(e,n)=>{throw new ct(`Response type '${t}' is not supported`,ct.ERR_NOT_SUPPORT,n)})})));const he={http:null,xhr:Qt,fetch:oe&&(async t=>{let{url:e,method:n,data:o,signal:r,cancelToken:i,timeout:s,onDownloadProgress:a,onUploadProgress:c,responseType:l,headers:u,withCredentials:f="same-origin",fetchOptions:h}=Yt(t);l=l?(l+"").toLowerCase():"text";let d,p=te([r,i&&i.toAbortSignal()],s);const m=p&&p.unsubscribe&&(()=>{p.unsubscribe()});let w;try{if(c&&ce&&"get"!==n&&"head"!==n&&0!==(w=await(async(t,e)=>at.toFiniteNumber(t.getContentLength())??(async t=>{if(null==t)return 0;if(at.isBlob(t))return t.size;if(at.isSpecCompliantForm(t)){const e=new Request(jt.origin,{method:"POST",body:t});return(await e.arrayBuffer()).byteLength}return at.isArrayBufferView(t)||at.isArrayBuffer(t)?t.byteLength:(at.isURLSearchParams(t)&&(t+=""),at.isString(t)?(await ie(t)).byteLength:void 0)})(e))(u,o))){let t,n=new Request(e,{method:"POST",body:o,duplex:"half"});if(at.isFormData(o)&&(t=n.headers.get("content-type"))&&u.setContentType(t),n.body){const[t,e]=Vt(w,Ht(Xt(c)));o=ne(n.body,65536,t,e)}}at.isString(f)||(f=f?"include":"omit");const r="credentials"in Request.prototype;d=new Request(e,{...h,signal:p,method:n.toUpperCase(),headers:u.normalize().toJSON(),body:o,duplex:"half",credentials:r?f:void 0});let i=await fetch(d,h);const s=le&&("stream"===l||"response"===l);if(le&&(a||s&&m)){const t={};["status","statusText","headers"].forEach((e=>{t[e]=i[e]}));const e=at.toFiniteNumber(i.headers.get("content-length")),[n,o]=a&&Vt(e,Ht(Xt(a),!0))||[];i=new Response(ne(i.body,65536,n,(()=>{o&&o(),m&&m()})),t)}l=l||"text";let y=await ue[at.findKey(ue,l)||"text"](i,t);return!s&&m&&m(),await new Promise(((e,n)=>{_t(e,n,{data:y,headers:zt.from(i.headers),status:i.status,statusText:i.statusText,config:t,request:d})}))}catch(e){if(m&&m(),e&&"TypeError"===e.name&&/Load failed|fetch/i.test(e.message))throw Object.assign(new ct("Network Error",ct.ERR_NETWORK,t,d),{cause:e.cause||e});throw ct.from(e,e&&e.code,t,d)}})};at.forEach(he,((t,e)=>{if(t){try{Object.defineProperty(t,"name",{value:e})}catch(t){}Object.defineProperty(t,"adapterName",{value:e})}}));const de=t=>"- "+t,pe=t=>at.isFunction(t)||null===t||!1===t,me=t=>{t=at.isArray(t)?t:[t];const{length:e}=t;let n,o;const r={};for(let i=0;e>i;i++){let e;if(n=t[i],o=n,!pe(n)&&(o=he[(e=n+"").toLowerCase()],void 0===o))throw new ct(`Unknown adapter '${e}'`);if(o)break;r[e||"#"+i]=o}if(!o){const t=Object.entries(r).map((([t,e])=>`adapter ${t} `+(!1===e?"is not supported by the environment":"is not available in the build")));throw new ct("There is no suitable adapter to dispatch the request "+(e?t.length>1?"since :\n"+t.map(de).join("\n"):" "+de(t[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return o};function we(t){if(t.cancelToken&&t.cancelToken.throwIfRequested(),t.signal&&t.signal.aborted)throw new Bt(null,t)}function ye(t){return we(t),t.headers=zt.from(t.headers),t.data=Mt.call(t,t.transformRequest),-1!==["post","put","patch"].indexOf(t.method)&&t.headers.setContentType("application/x-www-form-urlencoded",!1),me(t.adapter||Pt.adapter)(t).then((function(e){return we(t),e.data=Mt.call(t,t.transformResponse,e),e.headers=zt.from(e.headers),e}),(function(e){return qt(e)||(we(t),e&&e.response&&(e.response.data=Mt.call(t,t.transformResponse,e.response),e.response.headers=zt.from(e.response.headers))),Promise.reject(e)}))}const be={};["object","boolean","number","function","string","symbol"].forEach(((t,e)=>{be[t]=function(n){return typeof n===t||"a"+(1>e?"n ":" ")+t}}));const ve={};be.transitional=function(t,e,n){function o(t,e){return"[Axios v1.10.0] Transitional option '"+t+"'"+e+(n?". "+n:"")}return(n,r,i)=>{if(!1===t)throw new ct(o(r," has been removed"+(e?" in "+e:"")),ct.ERR_DEPRECATED);return e&&!ve[r]&&(ve[r]=!0),!t||t(n,r,i)}},be.spelling=function(t){return(t,e)=>!0};const ge={assertOptions:function(t,e,n){if("object"!=typeof t)throw new ct("options must be an object",ct.ERR_BAD_OPTION_VALUE);const o=Object.keys(t);let r=o.length;for(;r-- >0;){const i=o[r],s=e[i];if(s){const e=t[i],n=void 0===e||s(e,i,t);if(!0!==n)throw new ct("option "+i+" must be "+n,ct.ERR_BAD_OPTION_VALUE)}else if(!0!==n)throw new ct("Unknown option "+i,ct.ERR_BAD_OPTION)}},validators:be},xe=ge.validators;class Re{constructor(t){this.defaults=t||{},this.interceptors={request:new xt,response:new xt}}async request(t,e){try{return await this.l(t,e)}catch(t){if(t instanceof Error){let e={};Error.captureStackTrace?Error.captureStackTrace(e):e=Error();const n=e.stack?e.stack.replace(/^.+\n/,""):"";try{t.stack?n&&!(t.stack+"").endsWith(n.replace(/^.+\n.+\n/,""))&&(t.stack+="\n"+n):t.stack=n}catch(t){}}throw t}}l(t,e){"string"==typeof t?(e=e||{}).url=t:e=t||{},e=Zt(this.defaults,e);const{transitional:n,paramsSerializer:o,headers:r}=e;void 0!==n&&ge.assertOptions(n,{silentJSONParsing:xe.transitional(xe.boolean),forcedJSONParsing:xe.transitional(xe.boolean),clarifyTimeoutError:xe.transitional(xe.boolean)},!1),null!=o&&(at.isFunction(o)?e.paramsSerializer={serialize:o}:ge.assertOptions(o,{encode:xe.function,serialize:xe.function},!0)),void 0!==e.allowAbsoluteUrls||(void 0!==this.defaults.allowAbsoluteUrls?e.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:e.allowAbsoluteUrls=!0),ge.assertOptions(e,{baseUrl:xe.spelling("baseURL"),withXsrfToken:xe.spelling("withXSRFToken")},!0),e.method=(e.method||this.defaults.method||"get").toLowerCase();let i=r&&at.merge(r.common,r[e.method]);r&&at.forEach(["delete","get","head","post","put","patch","common"],(t=>{delete r[t]})),e.headers=zt.concat(i,r);const s=[];let a=!0;this.interceptors.request.forEach((function(t){"function"==typeof t.runWhen&&!1===t.runWhen(e)||(a=a&&t.synchronous,s.unshift(t.fulfilled,t.rejected))}));const c=[];let l;this.interceptors.response.forEach((function(t){c.push(t.fulfilled,t.rejected)}));let u,f=0;if(!a){const t=[ye.bind(this),void 0];for(t.unshift.apply(t,s),t.push.apply(t,c),u=t.length,l=Promise.resolve(e);u>f;)l=l.then(t[f++],t[f++]);return l}u=s.length;let h=e;for(f=0;u>f;){const e=s[f++],n=s[f++];try{h=e(h)}catch(t){n.call(this,t);break}}try{l=ye(h)}catch(t){return Promise.reject(t)}for(f=0,u=c.length;u>f;)l=l.then(c[f++],c[f++]);return l}getUri(t){return gt(Kt((t=Zt(this.defaults,t)).baseURL,t.url,t.allowAbsoluteUrls),t.params,t.paramsSerializer)}}at.forEach(["delete","get","head","options"],(function(t){Re.prototype[t]=function(e,n){return this.request(Zt(n||{},{method:t,url:e,data:(n||{}).data}))}})),at.forEach(["post","put","patch"],(function(t){function e(e){return function(n,o,r){return this.request(Zt(r||{},{method:t,headers:e?{"Content-Type":"multipart/form-data"}:{},url:n,data:o}))}}Re.prototype[t]=e(),Re.prototype[t+"Form"]=e(!0)}));const Oe=Re;class ke{constructor(t){if("function"!=typeof t)throw new TypeError("executor must be a function.");let e;this.promise=new Promise((function(t){e=t}));const n=this;this.promise.then((t=>{if(!n.u)return;let e=n.u.length;for(;e-- >0;)n.u[e](t);n.u=null})),this.promise.then=t=>{let e;const o=new Promise((t=>{n.subscribe(t),e=t})).then(t);return o.cancel=function(){n.unsubscribe(e)},o},t((function(t,o,r){n.reason||(n.reason=new Bt(t,o,r),e(n.reason))}))}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){this.reason?t(this.reason):this.u?this.u.push(t):this.u=[t]}unsubscribe(t){if(!this.u)return;const e=this.u.indexOf(t);-1!==e&&this.u.splice(e,1)}toAbortSignal(){const t=new AbortController,e=e=>{t.abort(e)};return this.subscribe(e),t.signal.unsubscribe=()=>this.unsubscribe(e),t.signal}static source(){let t;return{token:new ke((function(e){t=e})),cancel:t}}}const Te=ke,Ee={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Ee).forEach((([t,e])=>{Ee[e]=t}));const Se=Ee,Ae=function t(e){const n=new Oe(e),o=b(Oe.prototype.request,n);return at.extend(o,Oe.prototype,n,{allOwnKeys:!0}),at.extend(o,n,null,{allOwnKeys:!0}),o.create=function(n){return t(Zt(e,n))},o}(Pt);Ae.Axios=Oe,Ae.CanceledError=Bt,Ae.CancelToken=Te,Ae.isCancel=qt,Ae.VERSION="1.10.0",Ae.toFormData=mt,Ae.AxiosError=ct,Ae.Cancel=Ae.CanceledError,Ae.all=function(t){return Promise.all(t)},Ae.spread=function(t){return function(e){return t.apply(null,e)}},Ae.isAxiosError=function(t){return at.isObject(t)&&!0===t.isAxiosError},Ae.mergeConfig=Zt,Ae.AxiosHeaders=zt,Ae.formToJSON=t=>$t(at.isHTMLForm(t)?new FormData(t):t),Ae.getAdapter=me,Ae.HttpStatusCode=Se,Ae.default=Ae;const je=Ae,{Axios:$e,AxiosError:Ne,CanceledError:Pe,isCancel:Ce,CancelToken:Ue,VERSION:Fe,all:De,Cancel:Le,isAxiosError:Ie,spread:ze,toFormData:Me,AxiosHeaders:qe,HttpStatusCode:Be,formToJSON:_e,getAdapter:He,mergeConfig:Ve}=je,Xe=new class{constructor(){this.scopeAttribute="",this.scopeBody="",this.scopedKeyframes=new Map}parse(t,e){return this.scopeAttribute=`[vrefof="${e}"]`,this.scopeBody=`[vref="${e}"]`,this.scopedKeyframes.clear(),this.scopeSuffix=e.replace(/[^a-zA-Z0-9]/g,""),t=this.removeComments(t),this.collectKeyframes(t),this.parseRules(t)}collectKeyframes(t){const e=/@keyframes\s+([^\s{]+)/gi;let n;for(;null!==(n=e.exec(t));){const t=n[1],e=t+"-"+this.scopeSuffix;this.scopedKeyframes.set(t,e)}}removeComments(t){return t.replace(/\/\*[\s\S]*?\*\//g,"")}parseRules(t){let e="",n=0;for(;n=t.length)break;if("@"===t[n]){const o=this.parseAtRule(t,n);e+=o.content,n=o.endIndex}else{const o=this.parseNormalRule(t,n);e+=o.content,n=o.endIndex}}return e}parseAtRule(t,e){let n=e,o="";for(;n=t.length)return{content:o,endIndex:n};const r=o.toLowerCase().trim();if(r.startsWith("@keyframes"))return this.parseKeyframes(t,e);if(r.startsWith("@media"))return this.parseMedia(t,e);if(r.startsWith("@supports"))return this.parseSupports(t,e);{const e=this.findMatchingBrace(t,n);return{content:o+e.content,endIndex:e.endIndex}}}parseKeyframes(t,e){let n=e,o="";for(;n=t.length)return{content:o,endIndex:n};const r=this.findMatchingBrace(t,n),i=r.content,s=this.extractKeyframeName(o),a=this.scopedKeyframes.get(s);return a&&(o=o.replace(s,a)),o+=i,{content:o,endIndex:r.endIndex}}extractKeyframeName(t){const e=t.match(/@keyframes\s+([^\s{]+)/i);return e?e[1]:""}parseMedia(t,e){let n=e,o="";for(;n=t.length)return{content:o,endIndex:n};o+="{",n++;let r=1,i="";for(;n0;){if("{"===t[n])r++;else if("}"===t[n]&&(r--,0===r))break;i+=t[n],n++}return o+=this.parseRules(i),n=t.length)return{content:o,endIndex:n};const r=this.addScopeToSelector(o.trim()),i=this.findMatchingBrace(t,n);return{content:r+this.processRuleContent(i.content),endIndex:i.endIndex}}processRuleContent(t){let e=t;return e=e.replace(/animation\s*:\s*([^;]+);/gi,((t,e)=>`animation: ${this.processAnimationValue(e)};`)),e=e.replace(/animation-name\s*:\s*([^;]+);/gi,((t,e)=>`animation-name: ${this.processAnimationNames(e)};`)),e}processAnimationValue(t){return t.split(",").map((t=>t.trim())).map((t=>{const e=t.split(/\s+/);for(let n=0;n{const e=t.trim();return this.scopedKeyframes.get(e)||e})).join(", ")}addScopeToSelector(t){return t.trim()?t.split(",").map((t=>t.trim())).map((t=>this.addScopeToSingleSelector(t))).join(", "):t}addScopeToSingleSelector(t){if(!t.trim())return t;if(t.includes("::")){const e=t.split("::"),n=e[0],o="::"+e.slice(1).join("::");return this.addScopeToSelectorPart(n)+o}if(t.includes(":")&&!t.includes("::")){const e=t.match(/^([^:]+)(:.+)$/);if(e){const t=e[1],n=e[2];return this.addScopeToSelectorPart(t)+n}}return"*"===t||t.startsWith("@")?t:this.addScopeToSelectorPart(t)}addScopeToSelectorPart(t){const e=/(\s*[>+~]\s*|\s+)/;if(e.test(t)){const n=t.split(e);if(/^body(?:$|[:\[ ])/.test(n[0]))return n[0]=this.scopeBody+n[0].slice(4),n.join("");if(/^:root(?:$|[:\[ ])/.test(n[0]))return n[0]=this.scopeBody+n[0].slice(5),n.join("");for(let t=n.length-1;t>=0;t--)if(n[t].trim()&&!e.test(n[t])){let e=n[t].trim();n[t]=/^body(?:$|[:\[ ])/.test(e)?this.scopeBody+e.slice(4):/^:root(?:$:[$:\[ ])/.test(e)?this.scopeBody+e.slice(5):n[t].trim()+this.scopeAttribute;break}return n.join("")}let n=(t=t.trim()).trim();return/^body(?:$|[:\[ ])/.test(n)?this.scopeBody+n.slice(4):/^:root(?:$:[$:\[ ])/.test(n)?this.scopeBody+n.slice(5):n+this.scopeAttribute}findMatchingBrace(t,e){let n=e,o="",r=0;for(;n{this.removeMessage(s),i&&i()},s.appendChild(t)}return this.container.appendChild(s),setTimeout((()=>{s.classList.add("show")}),10),o>0&&setTimeout((()=>{this.removeMessage(s),i&&i()}),o),s}removeMessage(t){t&&t.parentNode&&(t.classList.remove("show"),setTimeout((()=>{t.parentNode&&t.parentNode.removeChild(t)}),300))}success(t,e={}){return this.createMessage("success",t,e)}warning(t,e={}){return this.createMessage("warning",t,e)}error(t,e={}){return this.createMessage("error",t,e)}info(t,e={}){return this.createMessage("info",t,e)}h(t,e={}){return new Promise(((n,o)=>{const{title:r="\u63d0\u793a",type:i="confirm",inputValue:s="",confirmText:a="\u786e\u5b9a",cancelText:c="\u53d6\u6d88",onConfirm:l=null,onCancel:u=()=>{n("")}}=e,f=document.createElement("div");f.className="prompt-overlay";const h=document.createElement("div");h.className="prompt-dialog";const d=document.createElement("div");d.className="prompt-header";const p=document.createElement("h3");p.className="prompt-title",p.textContent=r;const m=document.createElement("button");m.className="prompt-close",m.innerHTML="×",d.appendChild(p),d.appendChild(m);const w=document.createElement("div");w.className="prompt-body";const y=document.createElement("div");y.className="prompt-content",y.textContent=t,w.appendChild(y);let b=null;"input"===i&&(b=document.createElement("input"),b.className="prompt-input",b.type="text",b.value=s,w.appendChild(b));const v=document.createElement("div");v.className="prompt-footer";const g=document.createElement("button");g.className="prompt-btn prompt-btn-cancel",g.textContent=c;const x=document.createElement("button");x.className="prompt-btn prompt-btn-confirm",x.textContent=a,v.appendChild(g),v.appendChild(x),h.appendChild(d),h.appendChild(w),h.appendChild(v),f.appendChild(h),document.body.appendChild(f),setTimeout((()=>{f.classList.add("show")}),10),b&&setTimeout((()=>{b.focus()}),300);const R=(t=null)=>(f.classList.remove("show"),setTimeout((()=>{f.parentNode&&f.parentNode.removeChild(f)}),300),t);m.onclick=()=>{R(),u?u():o(Error("cancelled"))},g.onclick=()=>{R(),u?u():o(Error("cancelled"))},x.onclick=()=>{const t=!b||b.value;R(),n(t),l&&l(t)};const O=t=>{"Escape"===t.key&&(R(),u?u():o(Error("cancelled")),document.removeEventListener("keydown",O))};document.addEventListener("keydown",O),f.onclick=t=>{t.target===f&&(R(),u?u():o(Error("cancelled")))}}))}confirm(t,e={}){return this.h(t,{...e,type:"confirm"})}prompt(t,e,n={}){return this.h(t,{...n,type:"input",inputValue:e})}};var We={},Ke={};const Ge={};function Ze(t,e){Array.from(t.childNodes).forEach((t=>{1===t.nodeType&&(t.setAttribute("vrefof",e),Ze(t,e))}))}async function Ye(t,e,n,o){void 0===n&&(n="#"+function(){let t=(new Date).getTime().toString(36);t.length>4&&(t=t.substring(t.length-4));let e="";for(let n=0;4>n;n++)e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".charAt(Math.floor(52*Math.random()));return e+t.padStart(4,"0")}()),n.endsWith(".html")&&(n=n.slice(0,-5));let r=(new DOMParser).parseFromString(t,"text/html");if(r.body.hasAttribute("root")&&!o)throw Error("HTTP error! status: 404");let i={url:n,heads:[],body:document.createElement("div"),setup:void 0,scripts:[],styles:"",txt:t,env:e,tmp:r,customAttrs:{}};if(i.heads=Array.from(r.querySelector("head")?.children),n&&(r.querySelectorAll("style").forEach((t=>{null===t.getAttribute("unscoped")?i.styles+=Xe.parse(t.innerHTML,n):i.styles+=t.innerHTML})),i.styles)){const t=document.createElement("style");t.innerHTML=i.styles,t.setAttribute("vref",n),document.head.appendChild(t)}return i.body.append(...r.querySelector("body").childNodes),i.body.querySelectorAll("script").forEach((t=>{""!=t.innerHTML.trim()?(t.hasAttribute("setup")?i.setup=t:t.hasAttribute("novyes")||i.scripts.push(t),t.remove()):t.remove()})),Array.from(r.body.attributes).forEach((t=>{/^[a-zA-Z]/.test(t.name)?i.body.setAttribute(t.name,t.value):i.customAttrs[t.name]=t.value})),i.body.setAttribute("vref",n),Ze(i.body,n),o||await async function(t,e){for(let n of t.heads){let o=n.nodeName.toLowerCase();"link"===o?tn(n,e):"script"===o?await Qe(n,e):"title"===o&&(t.title=n.innerText)}}(i,e),i}function Qe(t,e){let n=t.getAttribute("src"),o=t.getAttribute("key"),r=e?.root;if(r&&n.startsWith("/")&&(n=r+n),n.startsWith("@")&&(n=n.slice(1)),n&&document.querySelector(`script[src="${n}"]`))return;if(o&&document.querySelector(`script[key="${o}"]`))return;let i=document.createElement("script");return i.src=n,i.key=o,i.type=t.getAttribute("type")||"text/javascript",new Promise(((t,e)=>{i.onload=()=>{t(i)},i.onerror=()=>e(Error("Failed to load script "+n)),document.head.appendChild(i)}))}async function tn(t,e){let n=t.getAttribute("href"),o=t.getAttribute("key"),r=e?.root;r&&n.startsWith("/")&&(n=r+n),n.startsWith("@")&&(n=n.slice(1)),n&&document.querySelector(`link[href="${n}"]`)||o&&document.querySelector(`link[key="${o}"]`)||(t.setAttribute("href",n),document.head.append(t))}const en={FetchUI:async function(t,e,n){t&&"/"!==t||(t="/root.html"),t.startsWith("http")||t.startsWith("@")||t.startsWith("/")||(t="/"+t);let o=e?.root;if(o&&t.startsWith("/")&&(t=o+t),t.startsWith("@")&&(t=t.slice(1)),We[t])return Promise.resolve(We[t]);if(Ke[t])return Ke[t];let r={};const i=fetch(t+"?random="+Math.random()).then((async e=>{if(!e.ok)throw Error("HTTP error! status: "+e.status);for(const[t,i]of e.headers.entries())t.startsWith("vyes-")&&(r[t.slice(5)]=i);let n=r.root||"";t.startsWith("http")&&(n=new URL(t).origin+n,r.root=n);let o=await async function(t,e){if(!Ge[t=t||""]){let n=t.startsWith("http")?t:window.location.origin+t;Ge[t]=Object.assign({},e,{root:t,$G:w.Wrap({}),$bus:new y,$axios:je.create({baseURL:n}),$message:Je,$router:null,$emit:null}),t===$vyes.root||null===$vyes.root?Ge[t].$router=$vyes.$router:Ge[t].$router={addRoutes:()=>{},beforeEnter:()=>{}};try{await(await import(n+"/env.js")).default(Ge[t])}catch(b){}}return Ge[t]}(n,r);return Object.assign(r,o),e.text()})).then((e=>Ye(e,r,t,n))).then((e=>(We[t]=e,e))).catch((e=>{e.message;let n=document.createElement("div");n.style.cssText="\n backgound:#aaa;\n height:100%;\n width: 100%;\n display:grid;\n place-items: center;\n",n.innerHTML=`\n
\n
404
\n

${t}

\n
\n`;let o={heads:[],body:n,setup:"",scripts:[],styles:"",txt:"",tmp:"",env:r,err:e};return We[t]=o,o})).finally((()=>{delete Ke[t]}));return Ke[t]=i,i},FetchFile:async function(t){return fetch(t).then((t=>{if(!t.ok)throw Error("HTTP error! status: "+t.status);return t.text()}))},LoadScript:Qe,LoadLink:tn,ParseUI:Ye};function nn(t,e){let n,o;if(t.startsWith("http://")||t.startsWith("https://")){if(n=new URL(t),n.origin!==window.location.origin)return null;n.pathname.startsWith(e)&&(o=n.pathname.slice(e.length))}else n=new URL(t,window.location.href),o=n.pathname;const r={};return n.searchParams.forEach(((t,e)=>{r[e]=t})),{path:o,query:r,hash:n.hash}}class on{constructor(t,e){this.originalPath=t,this.name=e,this.keys=[],this.regexp=this.pathToRegexp(t)}pathToRegexp(t){let e=t.replace(/:([^(/]+)/g,((t,e)=>(this.keys.push(e),`(?<${e}>[^/]+)`)));return e=e.replace(/\*(\w+)/g,((t,e)=>(this.keys.push(e),`(?<${e}>.*)`))),e=e.replace(/\*/g,".*"),RegExp(`^${e}$`)}match(t){let e;if("string"==typeof t)e=t;else{if(!t||"object"!=typeof t)return null;if(!t.path)return t.name&&t.name===this.name?{path:this.originalPath,params:t.params||{},matched:this.originalPath}:null;e=t.path}const n=this.regexp.exec(e);if(!n)return null;const o={};return this.keys.forEach((t=>{n.groups?.[t]&&(o[t]=n.groups[t])})),{path:this.originalPath,params:o,matched:n[0]}}}const rn=new Map;class sn{constructor(t,e,n){this.vyes=t,this.node=e,this.layoutDom=void 0,this.matchedRoute=n,this.htmlPath=this.resolveHtmlPath(n)}resolveHtmlPath(t){let e=t.route.component||t.route.path;return"function"==typeof e&&(e=e(t.path)),Object.entries(t.params).forEach((([t,n])=>{e=e.replace(":"+t,n)})),e.startsWith("/")||(e="/"+e),e.endsWith("/")&&(e=e.slice(0,-1)),e.endsWith(".html")||(e+=".html"),e}async mount(t,e,n){const o=await en.FetchUI(this.htmlPath,t);if(o.err){let n=document.createElement("div");return Object.assign(n.style,{width:"100%",height:"100%"}),n.append(...e),this.node.innerHTML="",this.node.append(n),void this.vyes.parseRef(this.htmlPath,n,{},t,null,!0)}this.title=o.title||"";const r={},i=document.createElement("div");if(i.setAttribute("vsrc",this.htmlPath),r[""]=[i],this.slots=r,!n)return this.node.innerHTML="",this.node.append(i),void this.vyes.parseRef(this.htmlPath,i,{},t,null);let s=rn.get(n);if(s)this.layoutDom=s,this.activate();else{let e=n;e.startsWith("/")||(e="/"+n),e.endsWith(".html")||(e+=".html"),e.startsWith("/layout")||(e="/layout"+e);const o=await en.FetchUI(e,t);if(o.err)return this.node.innerHTML="",this.node.append(i),void this.vyes.parseRef(this.htmlPath,i,{},t,null);s=o.body.cloneNode(!0),rn.set(n,s),i.$refData=w.Wrap({}),s.$refSlots=w.Wrap({...r}),this.node.innerHTML="",this.node.append(s),this.layoutDom=s,this.vyes.parseRef("/layout/"+n,s,{},t,null,!0)}}activate(){this.title&&(document.title=this.title);const t=this.layoutDom;if(t)t.querySelectorAll("vslot").forEach((e=>{e.closest("[vref]")===t&&this.slots[e.getAttribute("name")||""]&&(e.innerHTML="")})),Object.keys(t.$refSlots).forEach((e=>{delete t.$refSlots[e]})),Object.assign(t.$refSlots,this.slots),t.isConnected||(this.node.innerHTML=""),this.node.append(t);else{this.node.innerHTML="";const t=this.slots[""];t instanceof Array?this.node.append(...t):this.node.append(t)}}}const an=new class{#t=[];#e=[];#n=null;#o="";#r=[];#i=new Map;#s=null;#a=null;#c=[];#l=!1;#u=null;#f=new Map;constructor(){this.init()}get routes(){return this.#t.slice()}get history(){return this.#e.slice()}get current(){return this.#n}get query(){return this.#n?.query||{}}get params(){return this.#n?.params||{}}get root(){return this.#o}onChange(t){this.#r.push(t)}addRoute(t){if(!t.path)throw Error("Route must have a path");"/"!=t.path&&t.path.endsWith("/")&&(t.path=t.path.slice(0,-1));const e={path:t.path,component:t.component,name:t.name,meta:t.meta||{},children:t.children||[],matcher:new on(t.path,t.name),description:t.description||"",layout:t.layout||""};this.#t.push(e),t.name&&this.#f.set(t.name,e),t.children?.length>0&&t.children.forEach((n=>{const o=t.path+(n.path.startsWith("/")?n.path:"/"+n.path),r=n.layout||t.layout||"",i={...t.meta,...n.meta};this.addRoute({...n,path:o,parent:e,layout:r,meta:i})}))}addRoutes(t){t.forEach((t=>this.addRoute(t)))}#h(t,e){this.#r.forEach((n=>{if("function"==typeof n)try{n(t,e)}catch(o){}}))}#d(t){const e=this.#n;this.#n={path:t.path,fullPath:t.fullPath,params:t.params||{},query:t.query||{},hash:new URL(t.fullPath,window.location.origin).hash,meta:t.route?.meta||{},description:t.route?.description||"",layout:t.route?.layout||"",name:t.route?.name,matched:t.route?[t.route]:[]},this.#e.push(this.#n),this.#o&&!t.fullPath.startsWith("http")?history.pushState({},"",this.#o+t.fullPath):history.pushState({},"",t.fullPath),this.#h(this.#n,e)}matchRoute(t){const e=this.normalizeRouteTarget(t);if(!e)return null;const{path:n,query:o,params:r,name:i}=e;if(i){const t=this.#f.get(i);if(!t)return null;let e=t.path;Object.entries(r).forEach((([t,n])=>{e=e.replace(":"+t,n)}));const n=t.matcher.match(e);return n?{route:t,params:{...n.params,...r},matched:n.matched,path:e,query:o,name:i}:null}for(const s of this.#t){const t=s.matcher.match(n);if(t&&s.component)return{route:s,params:{...t.params,...r},matched:t.matched,description:s.description,layout:s.layout,path:n,query:o,name:s.name}}return null}normalizeRouteTarget(t){let e,n,o={},r={},i="";if("string"==typeof t){const n=nn(t,this.#o);if(!n)return null;e=n.path,o={...n.query},i=n.hash}else{if(!t||"object"!=typeof t)return null;if(t.path){const n=nn(t.path,this.#o);if(!n)return null;e=n.path,o={...n.query,...t.query||{}},i=t.hash||n.hash,r=t.params||{}}else{if(!t.name)return null;n=t.name,o=t.query||{},r=t.params||{},i=t.hash||""}}return e&&!e.startsWith("/")&&(e="/"+e),this.#o&&(e=e.startsWith(this.#o)?e.slice(this.#o.length):e),e.startsWith("/")||(e="/"+e),"/"!=e&&e.endsWith("/")&&(e=e.slice(0,-1)),{path:e,query:o,params:r,hash:i,name:n}}matchTo(t){const e=this.matchRoute(t);if(!e)return null;const{route:n,params:o,query:r,path:i,name:s}=e;let a="";r&&Object.keys(r).length>0&&(a="?"+Object.entries(r).map((([t,e])=>`${encodeURIComponent(t)}=${encodeURIComponent(e)}`)).join("&"));const c=(i||e.path)+a;return{route:n,params:o,query:r,name:s||n.name,path:i||e.path,fullPath:c,matched:[n]}}buildUrl(t,e={}){const n=new URL(t,window.location.origin);return Object.entries(e).forEach((([t,e])=>{n.searchParams.append(t,e)})),n}resolveRoutePath(t,e={}){let n=t.component||t.path;return Object.entries(e).forEach((([t,e])=>{n=n.replace(":"+t,e)})),"/"!==n&&""!==n||(n="/index"),n.startsWith("/")||(n="/"+n),n.endsWith(".html")&&(n=n.slice(0,-5)),n.endsWith("/")&&(n=n.slice(0,-1)),n}async#p(t){if(!t)return;const{route:e,params:n,query:o}=t,r={path:t.path,fullPath:t.fullPath,params:n,query:o,hash:new URL(t.fullPath,window.location.origin).hash,meta:e.meta,description:e.description,layout:e.layout,name:e.name,matched:[e]};if(this.beforeEnter)try{let t=!0;if(!1===await this.beforeEnter(r,this.#n,(e=>{e&&(t=!1,this.push(e))}))||!t)return}catch(a){return}const i=t.fullPath;let s=this.#i.get(i);s?s.activate():(s=new sn(this.#u,this.#s,t),await s.mount(this.#a,this.#c,r.layout),this.#i.set(i,s)),this.#d(t)}async push(t){const e=this.matchTo(t);e?await this.#p(e):"string"==typeof t||t.path||t.name}replace(t){this.push(t),this.#e.length>1&&this.#e.splice(-2,1)}go(t){history.go(t)}back(){history.back()}forward(){history.forward()}init(){this.#l||(this.#l=!0,document.body.addEventListener("click",(t=>{const e=t.target.closest("a");if(!e)return;const n=e.getAttribute("href");if(!n||n.startsWith("http")||n.startsWith("#"))return;t.preventDefault();const o=e.hasAttribute("reload"),r=e.getAttribute("vrefof")||"",i=e.closest(`[vref='${r}']`),s=i?.$env?.root||"";o||this.#o!==s?window.location.href=n:this.push(n)}),!0),window.addEventListener("popstate",(()=>{this.push(window.location.href)})))}ParseVrouter(t,e,n){this.#s=e,this.#a=n,this.#o=n.root||"",this.#c=Array.from(e.childNodes),this.#u=t,this.push(window.location.href)}},cn={$router:an},ln=[];document.addEventListener("click",(t=>{ln.forEach((e=>{e?.dom instanceof Element&&"function"==typeof e?.callback&&(e.dom.contains(t.target)||e.callback(t))}))}));const un={CamelToKebabCase:function(t){return 0===t.length?"":t.charAt(0).toLowerCase()+t.slice(1).replace(/([A-Z])/g,(function(t,e){return"-"+e.toLowerCase()}))},EventsList:["load","unload","beforeunload","resize","scroll","submit","reset","input","change","focus","blur","keydown","keypress","keyup","click","dblclick","contextmenu","mousedown","mouseup","mousemove","mouseover","mouseout","mouseenter","mouseleave","touchstart","touchmove","touchend","touchcancel","drag","dragstart","dragend","dragover","dragenter","dragleave","drop","copy","cut","paste","animationstart","animationend","animationiteration","transitionend","abort","error","loadstart","progress","play","pause","ended","volumechange","timeupdate","loadeddata","waiting","playing","online","offline","storage","visibilitychange"],BindInputDomValue:function(t,e,n,o){const r="string"==typeof t?document.querySelector(t):t;if(r){switch(r.type||r.tagName.toLowerCase()){case"text":case"password":case"email":case"tel":case"url":case"search":case"number":case"range":case"color":case"date":case"time":case"datetime-local":case"month":case"week":case"hidden":case"textarea":o((()=>{r.value=e[n]})),r.addEventListener("input",(function(){e[n]=this.value}));break;case"checkbox":o((function(){r.checked=!!e[n]})),r.addEventListener("change",(function(){e[n]=this.checked}));break;case"radio":o((()=>{r.checked=r.value===e[n]})),r.addEventListener("change",(function(){this.checked&&(e[n]=this.value)}));break;case"select-one":case"select-multiple":o((()=>{let t=e[n];if(r.multiple){const e=Array.isArray(t)?t:[];for(let t=0;t{if("outer"===e){let e=ln.length;return ln.push({dom:t,callback:n}),()=>{ln[e]=null}}}},fn=async t=>navigator.clipboard&&navigator.clipboard.writeText?navigator.clipboard.writeText(t):(prompt("http\u73af\u5883\u65e0\u6cd5\u81ea\u52a8\u590d\u5236\uff0c\u8bf7\u624b\u52a8\u590d\u5236\u5185\u5bb9\u5230\u526a\u8d34\u677f:",t),new Promise((t=>{})));class hn{postMessage=(t,e)=>{};constructor(t={}){this.options={highlightColor:"#007bff",overlayColor:"rgba(0, 123, 255, 0.1)",borderWidth:"2px",zIndex:1e4,showTagName:!0,...t},this.isActive=!1,this.selectedElement=null,this.currentHoverElement=null,this.overlay=null,this.selectedOverlay=null,this.tooltip=null,this.selectedTooltip=null,this.actionPanel=null,this.originalCursor="",this.init()}init(){this.createStyles(),this.bindEvents()}createStyles(){const t=document.createElement("style");t.textContent=`\n .div-selector-overlay {\n position: fixed;\n pointer-events: none;\n border: ${this.options.borderWidth} solid ${this.options.highlightColor};\n background: ${this.options.overlayColor};\n z-index: ${this.options.zIndex};\n transition: all 0.2s ease;\n box-sizing: border-box;\n }\n \n .div-selector-selected {\n position: fixed;\n pointer-events: none;\n border: ${this.options.borderWidth} solid #28a745;\n background: rgba(40, 167, 69, 0.1);\n z-index: ${this.options.zIndex-1};\n box-sizing: border-box;\n }\n \n .div-selector-tooltip {\n position: fixed;\n background: rgba(51, 51, 51, 0.95);\n cursor:pointer;\n color: white;\n padding: 8px 12px;\n border-radius: 6px;\n font-size: 12px;\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n z-index: ${this.options.zIndex+1};\n user-select: none;\n box-shadow: 0 2px 8px rgba(0,0,0,0.3);\n border: 1px solid rgba(255,255,255,0.1);\n backdrop-filter: blur(4px);\n }\n \n .div-selector-tooltip.hover {\n background: rgba(0, 123, 255, 0.9);\n }\n \n .div-selector-tooltip.selected {\n background: rgba(40, 167, 69, 0.9);\n border-color: rgba(40, 167, 69, 0.3);\n }\n \n .div-selector-actions {\n position: fixed;\n background: white;\n border: 1px solid #ddd;\n border-radius: 8px;\n padding: 8px;\n z-index: ${this.options.zIndex+2};\n box-shadow: 0 4px 16px rgba(0,0,0,0.15);\n display: flex;\n gap: 6px;\n min-width: 30px;\n backdrop-filter: blur(8px);\n }\n \n .div-selector-btn {\n padding: 4px 6px;\n border: 1px solid #ddd;\n background: white;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n transition: all 0.2s ease;\n text-align: left;\n white-space: nowrap;\n }\n \n .div-selector-btn:hover {\n background: #f8f9fa;\n transform: translateX(2px);\n }\n \n .div-selector-btn.danger {\n color: #dc3545;\n border-color: #dc3545;\n }\n \n .div-selector-btn.danger:hover {\n background: #dc3545;\n color: white;\n }\n \n .div-selector-btn.primary {\n background: #007bff;\n color: white;\n border-color: #007bff;\n }\n \n .div-selector-btn.primary:hover {\n background: #0056b3;\n }\n \n .div-selector-active {\n cursor: crosshair !important;\n }\n `,document.head.appendChild(t)}bindEvents(){this.handleMouseMove=this.handleMouseMove.bind(this),this.handleClick=this.handleClick.bind(this),this.handleScroll=this.handleScroll.bind(this),this.handleResize=this.handleResize.bind(this)}activate(){this.isActive||(this.isActive=!0,this.originalCursor=document.body.style.cursor,document.body.classList.add("div-selector-active"),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("click",this.handleClick),window.addEventListener("scroll",this.handleScroll),window.addEventListener("resize",this.handleResize),this.createOverlay(),this.createTooltip())}deactivate(){this.isActive&&(this.isActive=!1,document.body.style.cursor=this.originalCursor,document.body.classList.remove("div-selector-active"),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("click",this.handleClick),window.removeEventListener("scroll",this.handleScroll),window.removeEventListener("resize",this.handleResize),this.removeOverlay(),this.removeTooltip())}handleMouseMove(t){if(!this.isActive)return;const e=document.elementFromPoint(t.clientX,t.clientY);if(!e)return;if(this.isPluginElement(e))return;const n="DIV"===e.tagName?e:e.closest("div,[vref]");n&&!this.isPluginElement(n)&&this.selectedElement!==n&&(this.currentHoverElement=n,this.highlightElement(n),this.updateHoverTooltip(n))}handleClick(t){if(!this.isActive)return;const e=document.elementFromPoint(t.clientX,t.clientY);if(!e)return;if(this.isPluginElement(e))return;t.preventDefault(),t.stopPropagation();const n="DIV"===e.tagName?e:e.closest("div");n&&!this.isPluginElement(n)&&(this.selectElement(n),this.deactivate())}handleScroll(){this.selectedElement&&(this.updateSelectedOverlay(),this.updateSelectedTooltip(),this.updateActionPanelPosition()),this.currentHoverElement&&!this.selectedElement&&(this.highlightElement(this.currentHoverElement),this.updateHoverTooltip(this.currentHoverElement))}handleResize(){this.selectedElement&&(this.updateSelectedOverlay(),this.updateSelectedTooltip(),this.updateActionPanelPosition())}isPluginElement(t){return t.closest(".div-selector-overlay, .div-selector-selected, .div-selector-tooltip, .div-selector-actions")}createOverlay(){this.overlay=document.createElement("div"),this.overlay.className="div-selector-overlay",this.overlay.style.display="none",document.body.appendChild(this.overlay)}createSelectedOverlay(){this.selectedOverlay=document.createElement("div"),this.selectedOverlay.className="div-selector-selected",document.body.appendChild(this.selectedOverlay)}createTooltip(){this.tooltip=document.createElement("div"),this.tooltip.className="div-selector-tooltip hover",this.tooltip.style.display="none",document.body.appendChild(this.tooltip)}createSelectedTooltip(){this.selectedTooltip=document.createElement("div"),this.selectedTooltip.className="div-selector-tooltip selected",document.body.appendChild(this.selectedTooltip)}highlightElement(t){if(!this.overlay)return;const e=t.getBoundingClientRect();this.overlay.style.display="block",this.overlay.style.left=e.left+"px",this.overlay.style.top=e.top+"px",this.overlay.style.width=e.width+"px",this.overlay.style.height=e.height+"px"}updateHoverTooltip(t){if(!this.tooltip)return;const e=this.getElementInfo(t),n=t.getBoundingClientRect();this.tooltip.textContent=e,this.tooltip.style.display="block";let o=n.left-8,r=n.top-this.tooltip.offsetHeight-8;0>o&&(o=8),0>r&&(r=n.top+8),this.tooltip.style.left=o+"px",this.tooltip.style.top=r+"px"}selectElement(t){this.clearSelection(),this.selectedElement=t,this.createSelectedOverlay(),this.createSelectedTooltip(),this.updateSelectedOverlay(),this.updateSelectedTooltip(),this.overlay&&(this.overlay.style.display="none"),this.tooltip&&(this.tooltip.style.display="none"),this.showActionPanel()}updateSelectedOverlay(){if(!this.selectedOverlay||!this.selectedElement)return;const t=this.selectedElement.getBoundingClientRect();this.selectedOverlay.style.left=t.left+"px",this.selectedOverlay.style.top=t.top+"px",this.selectedOverlay.style.width=t.width+"px",this.selectedOverlay.style.height=t.height+"px"}updateSelectedTooltip(){if(!this.selectedTooltip||!this.selectedElement)return;const t=this.getElementInfo(this.selectedElement);let e=this.getFilePath(this.selectedElement);const n=this.selectedElement.getBoundingClientRect();this.selectedTooltip.addEventListener("click",(t=>{e&&this.postMessage("fs-open",e),t.preventDefault(),t.stopPropagation()})),this.selectedTooltip.textContent="\u2713 "+t;let o=n.left-8,r=n.top-this.selectedTooltip.offsetHeight-8;0>o&&(o=8),0>r&&(r=n.top+8),this.selectedTooltip.style.left=o+"px",this.selectedTooltip.style.top=r+"px"}showActionPanel(){this.removeActionPanel();const t=this.selectedElement.getBoundingClientRect();this.actionPanel=document.createElement("div"),this.actionPanel.className="div-selector-actions";let e=t.right-180,n=t.top+6;e+180>window.innerWidth&&(e=t.left-180-8),0>e&&(e=8),n+40>window.innerHeight&&(n=window.innerHeight-40-8),0>n&&(n=8),this.actionPanel.style.left=e+"px",this.actionPanel.style.top=n+"px",[{text:"\ud83d\udccb",action:()=>this.copySelector(this.selectedElement)},{text:"x",action:()=>this.clearSelection()}].forEach((t=>{const e=document.createElement("button");e.className="div-selector-btn "+(t.class||""),e.textContent=t.text,e.onclick=t.action,this.actionPanel.appendChild(e)})),document.body.appendChild(this.actionPanel)}updateActionPanelPosition(){if(!this.actionPanel||!this.selectedElement)return;const t=this.selectedElement.getBoundingClientRect(),e=this.actionPanel.offsetWidth,n=this.actionPanel.offsetHeight;let o=t.right-e+8,r=t.top-8;o+e>window.innerWidth&&(o=t.left-e-8),0>o&&(o=8),r+n>window.innerHeight&&(r=window.innerHeight-n-8),0>r&&(r=8),this.actionPanel.style.left=o+"px",this.actionPanel.style.top=r+"px"}clearSelection(){this.selectedElement=null,this.selectedOverlay&&(this.selectedOverlay.remove(),this.selectedOverlay=null),this.selectedTooltip&&(this.selectedTooltip.remove(),this.selectedTooltip=null),this.removeActionPanel()}getElementInfo(t){const e=t.getBoundingClientRect();let n=t.getAttribute("vref");return n||(n=t.closest("[vref]").getAttribute("vref"),n+="."+t.tagName.toLowerCase()),`${n} (${Math.round(e.width)}\xd7${Math.round(e.height)})`}getFilePath(t){let e=t.getAttribute("vref");return e||(e=t.closest("[vref]").getAttribute("vref")),e&&(e="/ui"+e+".html"),e}copySelector(t){let e=this.getFilePath(t);fn(e).then((()=>{this.showNotification("\ud83d\udccb CSS\u9009\u62e9\u5668\u5df2\u590d\u5236\u5230\u526a\u8d34\u677f")}))}copyXPath(t){const e=this.generateXPath(t);fn(e).then((()=>{this.showNotification("\ud83d\udd0d XPath\u5df2\u590d\u5236\u5230\u526a\u8d34\u677f")}))}viewStyles(t){const e=window.getComputedStyle(t);let n="\ud83d\udcca \u91cd\u8981\u6837\u5f0f\u5c5e\u6027:\n\n";["display","position","width","height","margin","padding","background-color","color","font-size","border","z-index","opacity"].forEach((t=>{n+=`${t}: ${e.getPropertyValue(t)}\n`})),alert(n)}showNotification(t){const e=document.createElement("div");e.style.cssText=`\n position: fixed;\n top: 20px;\n right: 20px;\n background: linear-gradient(135deg, #28a745, #20c997);\n color: white;\n padding: 12px 18px;\n border-radius: 8px;\n z-index: ${this.options.zIndex+10};\n font-size: 14px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.2);\n transform: translateX(100%);\n transition: transform 0.3s ease;\n `,e.textContent=t,document.body.appendChild(e),setTimeout((()=>{e.style.transform="translateX(0)"}),100),setTimeout((()=>{e.style.transform="translateX(100%)",setTimeout((()=>{e.remove()}),300)}),2500)}generateXPath(t){if(t.id)return`//*[@id="${t.id}"]`;const e=[];for(;t&&t.nodeType===Node.ELEMENT_NODE;){let n=0,o=!1,r=!1;for(let e=t.previousSibling;e;e=e.previousSibling)e.nodeType===Node.ELEMENT_NODE&&e.nodeName===t.nodeName&&(r=!0,n++);for(let e=t.nextSibling;e&&!o;e=e.nextSibling)e.nodeType===Node.ELEMENT_NODE&&e.nodeName===t.nodeName&&(o=!0);const i=t.nodeName.toLowerCase(),s=r||o?`[${n+1}]`:"";if(e.unshift(i+s),(t=t.parentNode)===document.body)break}return e.length?"/"+e.join("/"):null}removeOverlay(){this.overlay&&(this.overlay.remove(),this.overlay=null)}removeTooltip(){this.tooltip&&(this.tooltip.remove(),this.tooltip=null)}removeActionPanel(){this.actionPanel&&(this.actionPanel.remove(),this.actionPanel=null)}}let dn=!1,pn=null;const mn=(t,e)=>{dn&&("string"!=typeof e&&"number"!=typeof e||(e={value:e}),window.parent.postMessage(Object.assign({type:t,from:"vdev"},e),"*"))};!async function(){const t=document.createElement("style");t.innerHTML="\n [vref] {\n display: block;\n }\n [vparsing] {\n display: none;\n -webkit-text-fill-color: transparent;\n }\n vslot, vrouter {\n display: block;\n }\n",document.head.firstChild?document.head.insertBefore(t,document.head.firstChild):document.head.appendChild(t);const e=[],n=t=>{if(!t.isConnected)return;let n=t.getAttribute("vdelay");if(n){let o=e[n];o&&o(t)}};function o(t,e){const n=Function("sandbox",t=`with (sandbox) { ${t} }`);let o={data:null,key:null};const r=t=>new Proxy(t,{has:(t,e)=>!0,get(t,e,n){if(e===Symbol.unscopables)return;let i=Reflect.get(t,e,n);return o.data=t,o.key=e,"object"==typeof i&&i&&i[w.DataID]?r(i):i},set:(t,e,n,o)=>!1});return n(r(e)),o}new MutationObserver((function(t,e){t.forEach((function(t){for(let e of t.addedNodes)1===e.nodeType&&(n(e),e.querySelectorAll("*[vdelay]").forEach(n))}))})).observe(document.body,{attributes:!1,childList:!0,subtree:!0,characterData:!1});const r=/{{|}}/g,i=/^(\s*(\w+)\s+in\s+|\((\w+),\s*(\w+)\)\s+in\s+)([\w\$\.\[\]\(\)'"]+)$/;window.$vyes||(window.$vyes=new class{app=null;root=null;vget=en;vproxy=w;t=!0;$router=cn.$router;constructor(t){"string"==typeof t?this.app=document.getElementById(t):t instanceof HTMLElement?this.app=t:this.app=document.body,this.app&&(async()=>{let t=await en.FetchUI(window.location.pathname,{},!0);this.root=t.env?.root||"",t.env?.vdev&&window.self!==window.top&&(dn||(dn=!0,pn=new hn,mn("iframe-loaded"),pn.postMessage=mn,window.addEventListener("keyup",(t=>{"Escape"===t.key&&mn("key-esc")})),setTimeout((()=>{window.$vyes&&window.$vyes.$router&&$vyes.$router.onChange((t=>{mn("url-change",t.fullPath)}))}),100),window.addEventListener("message",(t=>{const e=t.data;if("vyes"==e.from)switch(e.type){case"reload":window.location.reload();break;case"magic":pn&&pn.isActive?pn.deactivate():pn&&pn.activate()}})))),this.parseRef("root",this.app,{},t.env||{},t,!0)})()}async parseDom(t,e={},n){if(n instanceof HTMLElement)throw Error("env error");let o=t.nodeName.toLowerCase();if(3===t.nodeType)return void this.parseTextNode(t,e,n);if(8===t.nodeType)return;if(1!==t.nodeType)return;if(t.hasAttribute("novyes")||t.vparsed)return;let r=t.getAttribute("v-for");if(null!==r)return void this.parseVfor(r,t,e,n);if(-1!==o.indexOf("-")){let r="/"+o.split("-").join("/"),i=t.hasAttribute("single");return this.parseRef(r,t,e,n,null,i),void(t.vparsed=!0)}if(t.getAttribute(":vsrc")){let o=t.getAttribute(":vsrc");t.removeAttribute(":vsrc");let r=Array.from(t.attributes).map((t=>({name:t.name,value:t.value}))),i=Array.from(t.childNodes);return void w.Watch((()=>{delete t.vparsed,t.setAttribute("vparsing","");let s=w.Run(o,e,n);s&&(Array.from(t.attributes).forEach((e=>{t.removeAttribute(e.name)})),t.innerHTML="",r.forEach((e=>{t.setAttribute(e.name,e.value)})),i.forEach((e=>{t.appendChild(e.cloneNode(!0))})),this.parseRef(s,t,e,n,null,!1),t.vparsed=!0)}))}if(t.getAttribute("vsrc")){let o=t.hasAttribute("single");return this.parseRef(t.getAttribute("vsrc"),t,e,n,null,o),void(t.vparsed=!0)}if("vslot"===o)return this.parseSlots(t,e,n),void(t.vparsed=!0);if("vrouter"===o)return this.parseAttrs(t,e,n),void cn.$router.ParseVrouter(this,t,n);this.parseAttrs(t,e,n);let i=this.parseVif(Array.from(t.childNodes),e,n);for(let s of i)this.parseDom(s,e,n);t.vparsed=!0}onMountedRun(t,n,o=!0){if(o){if(t.isConnected)return void n(t);let o=e.push((t=>{t.removeAttribute("vdelay"),n(t)}));return void t.setAttribute("vdelay",o-1)}t.isConnected&&n(t);let r=e.push(n);t.setAttribute("vdelay",r-1)}AllENVs={};async parseRef(t,e,n,o,r,i=!1){e.setAttribute("vparsing","");let s=o,a=e.getAttribute("vrefof"),c=e.closest(`*[vref='${a}']`);c&&(o=c.$env),!r&&t&&(t.endsWith(".html")||(t+=".html"),r=await en.FetchUI(t,o,e.hasAttribute("root"))),o=Object.assign({},o,r?.env||{}),e.$env=o,e.$vsrc=t,o.$router=cn.$router,o.$emit=(t,...n)=>{if(t=t.toLowerCase(),!e.$vevent)return;let o=e.$vevent[t];o&&"function"==typeof o&&o(...n)};let l=await this.setupRef(e,n,s,r,i);i?this.parseAttrs(e,l,o,r?.customAttrs):this.parseAttrs(e,n,s,r?.customAttrs);let u=this.parseVif(Array.from(e.childNodes),l,o);for(let f of u)this.parseDom(f,l,o);e.removeAttribute("vparsing"),this.mountRef(e,l,o,r)}async setupRef(t,e,n,r,i=!1){let s=w.Wrap({});if(r.setup){let e=r.setup.innerHTML;e=await w.ParseImport(e,s,t.$env,t.$vsrc),await w.AsyncRun(e,s,t.$env,{$node:t,$watch:t=>{setTimeout((()=>{w.Watch(t)}),50)}})}if(t.$refScope=e,t.$refData=s,i)return s;if(!t.$refSlots){let e=w.Wrap({});t.childNodes.forEach((t=>{let n=t.getAttribute?t.getAttribute("vslot"):"";n=n||"",e[n]||(e[n]=[]),e[n].push(t)})),t.$refSlots=e}t.innerHTML="";let a=r.body.cloneNode(!0);t.append(...a.childNodes),Object.keys(s).forEach((r=>{const i=un.CamelToKebabCase(r);if(t.hasAttribute(r)?s[r]=t.getAttribute(r):t.hasAttribute(i)&&(s[r]=t.getAttribute(i)),t.hasAttribute(":"+r)||t.hasAttribute(":"+i)){let o=t.getAttribute(":"+r)||t.getAttribute(":"+i);t.removeAttribute(":"+r),t.removeAttribute(":"+i),w.Watch((()=>{s[r]=o?w.Run(o,e,n):e[r]}))}if(t.hasAttribute("v:"+r)||t.hasAttribute("v:"+i)){let n=t.getAttribute("v:"+r)||t.getAttribute("v:"+i);t.removeAttribute("v:"+r),t.removeAttribute("v:"+i),n||(n=r);let a=o(n,e);if(a.data&&a.key){let t=a.key,e=a.data;void 0!==e[t]&&null!==e[t]||(e[t]=s[r]),w.Watch((()=>{s[r]=e[t]})),w.Watch((()=>{e[t]=s[r]}))}}}));let c=Array.from(a.attributes);return c=c.filter((e=>!this.parseAttr(t,e.name,e.value,s,n)||(a.removeAttribute(e.name),!1))),c.forEach((e=>{if("class"===e.name)t.classList.add(...e.value.trim().split(/\s+/));else if("style"===e.name){let n=e.value.split(";");for(let e of n){let n=e.split(":");if(2===n.length&&!t.style[n[0]]){let e=n[0].trim();e.startsWith("--")?t.style.setProperty(e,n[1].trim()):t.style[e]=n[1].trim()}}}else t.getAttribute(e.name)||t.setAttribute(e.name,e.value)})),s}async mountRef(t,e,n,o){for(let r of o.scripts)r.hasAttribute("active")?this.onMountedRun(t,(()=>{w.AsyncRun(r.innerHTML,e,n,{$node:t,$watch:w.Watch})}),!1):w.AsyncRun(r.innerHTML,e,n,{$node:t,$watch:w.Watch})}parseAttrs(t,e,n,o){if("A"===t.nodeName&&this.parseAHref(t,e,n),Array.from(t.attributes).forEach((o=>{this.parseAttr(t,o.name,o.value,e,n)&&t.removeAttribute(o.name)})),o&&Object.keys(o).forEach((e=>{this.parseAttr(t,e,o[e],t.$refData,n)})),t.hasAttribute("v-show")){let o=t.getAttribute("v-show"),r=t.style.display;w.Watch((()=>{let i=w.Run(o,e,n);t.style.display=i?r:"none"}))}}parseAHref(t,e,n){if(!t.hasAttribute("href")&&!t.hasAttribute(":href"))return;w.Watch((()=>{let o=t.getAttribute("href");if(t.hasAttribute(":href")){let r=t.getAttribute(":href");t.removeAttribute(":href"),o=w.Run(r,e,n)}if(o&&!o.startsWith("#")&&!o.startsWith("http"))if(o.startsWith("@"))t.hasAttribute("reload")||t.setAttribute("reload",""),t.setAttribute("href",o.slice(1));else if(o){let e=n?.root;e&&(o=e+o),t.setAttribute("href",o)}}));const o=e=>{let o=e?.fullPath;n.root&&(o=n.root+o),t.getAttribute("href")===o?t.setAttribute("active",""):t.removeAttribute("active")};o(cn.$router.current),cn.$router.onChange(o)}parseAttr(t,e,n,r,i){if(e.startsWith(":")){let o=e.slice(1);return"class"===o||"style"===o?this.handleStyle(t,o,n,r,i):w.Watch((()=>{let e;e=n?w.Run(n,r,i):r[o],un.SetAttr(t,o,e)})),!0}if(e.startsWith("@"))return this.handleEvent(t,e,n,r,i),!0;if(e.indexOf("!")>-1);else if(e.startsWith("v:")){let e=o(n,r);if(e.data&&e.key){let n=e.key,o=e.data;return un.BindInputDomValue(t,o,n,w.Watch)}}else if("vdom"===e){let e=o(n,r);return e.data&&e.key&&(e.data[e.key]=t),!0}return!1}handleStyle(t,e,n,o,r){let i="";w.Watch((()=>{let s=w.Run(n,o,r);if("function"==typeof s&&(s=s()),"class"===e){if(i&&(t.classList.remove(...i.split(/\s+/)),i=""),s instanceof Array)i="",s.forEach((t=>{if("string"==typeof t&&t.length)i+=" "+t;else if("object"==typeof t)for(let e in t)t[e]&&(i+=" "+e)}));else if("string"==typeof s&&s.length)i=s.trim();else if("object"==typeof s){i="";for(let t in s)s[t]&&(i+=" "+t)}i=i.trim(),i&&t.classList.add(...i.split(/\s+/))}else if("style"===e){if(i)if("object"==typeof i)for(let e in i)e.startsWith("--")?t.style.removeProperty(e):t.style[e]="";else if("string"==typeof i){let e=i.split(";");for(let n of e){let e=n.split(":");2===e.length&&(e[0].trim().startsWith("--")?t.style.removeProperty(e[0].trim()):t.style[e[0].trim()]="")}}if("object"==typeof s)for(let e in s)e.startsWith("--")?t.style.setProperty(e,s[e]):t.style[e]=s[e];else if("string"==typeof s){let e=s.split(";");for(let n of e){let e=n.split(":");2===e.length&&(e[0].trim().startsWith("--")?t.style.setProperty(e[0].trim(),e[1].trim()):t.style[e[0].trim()]=e[1].trim())}}i=s}}))}handleEvent(t,e,n,o,r){let i=e.slice(1).split("."),s={self:!1,prevent:!1,stop:!1},a=i[0];if("mounted"===a)this.onMountedRun(t,(t=>{let e=w.Run(n,o,r);"function"==typeof e&&e(t)}),!1);else if("outerclick"===a){let e=t=>{let e=w.Run(n,o,r,{$event:t});"function"==typeof e&&e(t)};un.AddClicker(t,"outer",e)}else if(-1!==un.EventsList.indexOf(a)){"keydown"!==a&&"keyup"!==a&&"keypress"!==a||"INPUT"!==t.tagName&&"TEXTAREA"!==t.tagName&&t.setAttribute("tabindex","0");let e=t=>{let e=w.Run(n,o,r,{$event:t});"function"==typeof e&&e(t)};i.slice(1).forEach((i=>{if(i.startsWith("delay")){let s=i.slice(5);s=s?s.endsWith("ms")?+s.slice(0,-2):s.endsWith("s")?1e3*+s.slice(0,-1):+s:1e3,isNaN(s)&&(s=1e3),e=e=>{let i=t["_"+a];i&&"number"==typeof i&&clearTimeout(i),t["_"+a]=setTimeout((()=>{let t=w.Run(n,o,r,{$event:e});"function"==typeof t&&t(e)}),s)}}s[i]=!0})),t.addEventListener(a,(t=>{(1>=i.length||"keydown"!==a&&"keyup"!=a&&"keypress"!=a||i[1]===t.key.toLowerCase())&&(s.self&&t.currentTarget!==t.target||(s.prevent&&t.preventDefault(),s.stop&&t.stopPropagation(),e(t)))}))}else t.$vevent=t.$vevent||{},t.$vevent[a]=(...t)=>{let e=w.Run(n,o,r,{});"function"==typeof e&&e(...t)}}parseTextNode(t,e,n){let o,i=t.nodeValue.trim();if(!i)return;let s=0,a=-1,c=[];for(;null!==(o=r.exec(i));)if("{{"===o[0])a=o.index;else if("}}"===o[0]&&a>=0){s!==a&&c.push(i.slice(s,a)),c.push("");let r=i.slice(a+2,o.index),l=c.length;a=-1,s=o.index+2,w.Watch((()=>{c[l-1]=w.Run(r,e,n),"object"==typeof c[l-1]&&(c[l-1]=JSON.stringify(c[l-1])),t.nodeValue=c.join("")}))}c.push(i.slice(s)),t.nodeValue=c.join("")}vforDomCache={};parseVfor(t,e,n,o){e.removeAttribute("v-for");let r=i.exec(t);if(6===r?.length){let t=document.createElement("div");t.style.display="none";let i=w.GenUniqueID();this.vforDomCache[i]={},e.parentNode.replaceChild(t,e),w.Watch((()=>{let s=r[3]||r[2],a=r[4],c=w.Run(r[5],n,o),l=this.vforDomCache[i],u={};if("function"==typeof c?c=c():"number"==typeof c&&(c=Array.from({length:c},((t,e)=>e))),null==c&&(c=[]),c.length,"object"==typeof c){let r=Object.keys(c);for(let f in r){let h=r[f],d="";if(d=c[h]&&c[h][w.DataID]?c[h][w.DataID]:h+"."+c[h],d=i+"."+d,u[d]=!0,l[d]){a&&(l[d].$vforData[a]="0"===h?0:+h||h),document.body.contains(l[d])&&t.parentNode.insertBefore(l[d],t);continue}let p=e.cloneNode(!0);l[d]=p;let m={[s]:c[h]};a&&(m[a]="0"===h?0:+h||h),m=w.Wrap(m,n),p.$vforData=m,t.parentNode.insertBefore(p,t);let y=e.getAttribute("v-if");if(!y){this.parseDom(p,m,o);continue}l[d].removeAttribute("v-if");let b=-1;b=w.Watch((()=>{let e=l[d];if(e)if(w.Run(y,m,o)){if(e.vparsed||this.parseDom(e,m,o),!e.isConnected){let n=!1,o=t;for(let t in l)if(t!==d){if(n&&l[t].isConnected){o=l[t];break}}else n=!0;t.parentNode.insertBefore(e,o)}}else e.isConnected?e.remove():this.onMountedRun(e,(t=>{e.remove()}));else w.Cancel(b)}))}for(let t of Object.keys(l))u[t]||(l[t]instanceof Array?l[t].forEach((t=>t.remove())):l[t].remove(),delete l[t])}}))}}parseVif(t,e,n){let o={now:document.createElement("div"),conds:[],doms:[]};const r=t=>{let o={now:t.now,conds:t.conds,doms:t.doms},r=[];for(let e in o.conds){let t=o.conds[e];t=""===t?"true":"Boolean("+t+")",r.push(t)}let i=`let res = [${r.join(",")}]\n return res.indexOf(true)`;w.Watch((()=>{let t=w.Run(i,e,n),r=o.doms[t];return r||(r=document.createElement("div"),r.style.display="none"),r}),(t=>{t&&(this.onMountedRun(o.now,(e=>{e.replaceWith(t),o.now=t})),t?.vparsed||this.parseDom(t,e,n))}))};let i=t.filter((t=>!(t.getAttribute&&!t.getAttribute("v-for")&&(null!==t.getAttribute("v-if")?(o.conds.length>0&&(r(o),o={now:document.createElement("div"),conds:[],doms:[]}),t.replaceWith(o.now),o.conds.push(t.getAttribute("v-if")),t.removeAttribute("v-if"),o.doms.push(t),1):null!==t.getAttribute("v-else-if")?(o.conds.push(t.getAttribute("v-else-if")),t.removeAttribute("v-else-if"),o.doms.push(t),t.remove(),1):null!==t.getAttribute("v-else")&&(o.conds.push(""),t.removeAttribute("v-else"),o.doms.push(t),t.remove(),1)))));return o.conds.length>0&&r(o),i}parseSlots(t,e,n){let o=t.getAttribute("vrefof"),r=t.closest(`*[vref='${o}']`);if(!r)return void this.onMountedRun(t,(t=>{this.parseSlots(t,e,n)}));for(;;){let t=r?.parentNode.closest("*[vref]");if(!t)break;if(t.getAttribute("vref")!==o)break;r=t}let i=t.getAttribute("name")||"";if(t.getAttribute(":name")){let o=t.getAttribute(":name");t.removeAttribute(":name"),i=w.Run(o,e,n)}return t.originContent||(t.$originContent=Array.from(t.childNodes),t.innerHTML=""),t.$slotCache={},w.Watch((()=>{let o=r.$refSlots||{},s=r.$refScope||{},a=o[i];if(a&&a.length>0){let o=a[0].hashID;if(o){if(t.$slotCache[o])return t.innerHTML="",void t.append(...t.$slotCache[o])}else o=w.GenUniqueID(),a[0].hashID=o;t.innerHTML="",a=a.map((t=>t.cloneNode(!0))),t.append(...a);let r=s;null!==t.getAttribute("v")&&(r=function(t,e){const n=Function("sandbox",t=`with (sandbox) { ${t} }`);let o=w.Wrap({}),r=[];const i=new Proxy(e,{has:(t,e)=>!0,get(t,e,n){if(e===Symbol.unscopables)return;let o=Reflect.get(t,e,n);return-1===r.indexOf(e)&&r.push(e),o},set:(t,e,n,o)=>!1});return n(i),w.Watch((()=>{r.forEach((t=>{o[t]!==e[t]&&(o[t]=e[t])}))})),o}(t.getAttribute("v"),e),w.SetDataRoot(r,s));let i="";a.find((t=>!(!t.getAttribute||!t.getAttribute("vrefof")||(i=t.getAttribute("vrefof"),0))));let c=n;if(i){let e=t.closest(`*[vref='${i}']`);c=e?.$env||n}a=this.parseVif(a,r,c),a.forEach((t=>this.parseDom(t,r,c))),t.$slotCache[o]=a}else{t.innerHTML="",t.append(...t.$originContent);let o=!1;t.$originContent.forEach((t=>{t.hasAttribute&&t.vparsed&&(o=!0)})),o||(t.$originContent=this.parseVif(t.$originContent,e,n),t.$originContent.forEach((t=>this.parseDom(t,e,n))))}})),this.parseAttrs(t,e,n),t}}(document.body))}()},"function"==typeof define&&define.amd?define(t):t(); \ No newline at end of file +var t;t=function(){const t=[],e=[];function n(){return`${performance.now().toString(36)}-${Math.random().toString(36).substring(2,5)}`}setInterval((()=>{let n=new Set(e.splice(0)),o=0;for(let e of n)t[e]&&(window.vdev||t[e](),o++);return o}),25),window.$vupdate=e=>{t[e]()};var o=[];const r=Symbol("isProxy"),i=Symbol("DataID"),s=Symbol("bind"),a=Symbol("root"),c=Symbol("root arg");function l(t,e){t[a]=e,Object.keys(e).forEach((e=>{e in t||(t[e]=c)}))}function u(t){return!(!t||"object"!=typeof t||t instanceof Node||t instanceof Date||t instanceof RegExp||t instanceof Event||t.t||t.constructor!==Object&&t.constructor!==Array)}function f(t,e){if(!t||!t[r]||!u(e))return e;let n=t[s];if(!e[r]){if(Array.isArray(e)&&Array.isArray(t)){t.length=0;for(let n=0;n{e.hasOwnProperty(n)||delete t[n]})),Object.keys(e).forEach((n=>{t[n]?.[r]?t[n]=f(t[n],e[n]):t[n]=e[n]})),t}if(e[i]===t[i])return e;for(let o in n)if(e[s][o]?.indexOf){const t=e[s][o],r=new Set(t);for(let e of n[o])r.has(e)||(t.push(e),r.add(e))}else e[s][o]=n[o];for(let o in e)o in t&&t[o]?.[r]&&(e[o]=f(t[o],e[o]));return e}const h={console,window,prompt:prompt.bind(window),alert:alert.bind(window),confirm:confirm.bind(window),RegExp,document,Array,Object,Math,Date,JSON,Symbol,Number,eval,isNaN,parseInt,parseFloat,setTimeout:setTimeout.bind(window),setInterval:setInterval.bind(window),clearTimeout:clearTimeout.bind(window),clearInterval:clearInterval.bind(window),encodeURIComponent,btoa:btoa.bind(window),fetch:fetch.bind(window),TextDecoder,history,requestAnimationFrame:requestAnimationFrame.bind(window)};function d(t,e,n){const o=new Proxy(t,{has:(t,e)=>!0,get(o,r,i){let s;return"$data"===r?s=t:"$env"===r?s=e:r in o?s=Reflect.get(o,r,i):r in e?s=e[r]:n&&r in n?s=n[r]:r in h?s=h[r]:r in window&&(s=window[r]),s},set:(t,e,n,o)=>Reflect.set(t,e,n,o)});return o}const p=Object.getPrototypeOf((async function(){})).constructor;function m(t,e){if(t.startsWith("/"))return t;const n=e.substring(0,e.lastIndexOf("/")).split("/").filter((t=>""!==t)),o=t.split("/").filter((t=>""!==t));for(const r of o)if(".."===r)n.length>0&&n.pop();else{if("."===r)continue;n.push(r)}return"/"+n.join("/")}const w={Wrap:function h(d,p=void 0){const m=n();let w=!1;"[object Array]"==={}.toString.call(d)&&(w=!0),p&&l(d,p);const y={},b={get(t,e,n){if(e===i)return m;if(e===r)return!0;if(e===s)return y;if("hasOwnProperty"===e)return t.hasOwnProperty.bind(t);const l=Reflect.get(t,e,n);if(l===c)return t[a][e];if("symbol"==typeof e)return l;let f=-1;if(o.length>0){let t=e;f=o[o.length-1],w&&(t=""),y.hasOwnProperty(t)?-1==y[t].indexOf(f)&&y[t].push(f):y[t]=[f]}if(window.vdev,u(l)&&!l[r]){let o=h(l,void 0);return Reflect.set(t,e,o,n),o}return l},set(n,i,s,l){const h=Reflect.get(n,i,l);if(h===c)return n[a][i]=s,!0;if(h===s)return!0;let d=!0;if(Array.isArray(s)&&Array.isArray(h)?(h.length=0,h.push(...s)):h&&h[r]&&u(s)?(s=f(h,s),d=Reflect.set(n,i,s,l)):d=Reflect.set(n,i,s,l),d&&0===o.length){let n=i;if(w&&(n=""),y[n]){let o=0;for(;o{n(e())})):t.push(e);try{r=e()}catch(b){}finally{o.pop()}return"function"==typeof n&&n(r),i},Cancel:function(e){e>=0&&et.trim()))}const i=await import(t);"string"==typeof o?i.default?e[o]=i.default:e[o]=i:o.forEach((t=>{t in i?e[t]=i[t]:t in i.default&&(e[t]=i.default[t])}))}catch(l){}}return s.trim()}};class y{constructor(){this.events={}}on(t,e,n=null){if("function"!=typeof e)throw Error("\u56de\u8c03\u51fd\u6570\u5fc5\u987b\u662f\u4e00\u4e2a\u51fd\u6570");this.events[t]||(this.events[t]=[]);const o={callback:e,context:n};return this.events[t].push(o),()=>this.off(t,e,n)}once(t,e,n=null){const o=(...r)=>{this.off(t,o,n),e.apply(n,r)};return this.on(t,o,n)}off(t,e=null,n=null){this.events[t]&&(e?(this.events[t]=this.events[t].filter((t=>!(t.callback===e&&t.context===n))),0===this.events[t].length&&delete this.events[t]):delete this.events[t])}emit(t,...e){this.events[t]&&[...this.events[t]].forEach((t=>{try{t.callback.apply(t.context,e)}catch(n){}}))}listenerCount(t){return this.events[t]?this.events[t].length:0}eventNames(){return Object.keys(this.events)}removeAllListeners(){this.events={}}hasListeners(t){return this.listenerCount(t)>0}}function b(t,e){return function(){return t.apply(e,arguments)}}const{toString:v}=Object.prototype,{getPrototypeOf:g}=Object,{iterator:x,toStringTag:R}=Symbol,O=(k=Object.create(null),t=>{const e=v.call(t);return k[e]||(k[e]=e.slice(8,-1).toLowerCase())});var k;const T=t=>(t=t.toLowerCase(),e=>O(e)===t),E=t=>e=>typeof e===t,{isArray:S}=Array,A=E("undefined"),j=T("ArrayBuffer"),$=E("string"),N=E("function"),P=E("number"),C=t=>null!==t&&"object"==typeof t,U=t=>{if("object"!==O(t))return!1;const e=g(t);return!(null!==e&&e!==Object.prototype&&null!==Object.getPrototypeOf(e)||R in t||x in t)},F=T("Date"),D=T("File"),L=T("Blob"),I=T("FileList"),z=T("URLSearchParams"),[M,q,B,_]=["ReadableStream","Request","Response","Headers"].map(T);function H(t,e,{allOwnKeys:n=!1}={}){if(null==t)return;let o,r;if("object"!=typeof t&&(t=[t]),S(t))for(o=0,r=t.length;r>o;o++)e.call(null,t[o],o,t);else{const r=n?Object.getOwnPropertyNames(t):Object.keys(t),i=r.length;let s;for(o=0;i>o;o++)s=r[o],e.call(null,t[s],s,t)}}function V(t,e){e=e.toLowerCase();const n=Object.keys(t);let o,r=n.length;for(;r-- >0;)if(o=n[r],e===o.toLowerCase())return o;return null}const X="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,J=t=>!A(t)&&t!==X,W=(K="undefined"!=typeof Uint8Array&&g(Uint8Array),t=>K&&t instanceof K);var K;const G=T("HTMLFormElement"),Z=(({hasOwnProperty:t})=>(e,n)=>t.call(e,n))(Object.prototype),Y=T("RegExp"),Q=(t,e)=>{const n=Object.getOwnPropertyDescriptors(t),o={};H(n,((n,r)=>{let i;!1!==(i=e(n,r,t))&&(o[r]=i||n)})),Object.defineProperties(t,o)},tt=T("AsyncFunction"),et=(nt="function"==typeof setImmediate,ot=N(X.postMessage),nt?setImmediate:ot?(rt="axios@"+Math.random(),it=[],X.addEventListener("message",(({source:t,data:e})=>{t===X&&e===rt&&it.length&&it.shift()()}),!1),t=>{it.push(t),X.postMessage(rt,"*")}):t=>setTimeout(t));var nt,ot,rt,it;const st="undefined"!=typeof queueMicrotask?queueMicrotask.bind(X):"undefined"!=typeof process&&process.nextTick||et,at={isArray:S,isArrayBuffer:j,isBuffer:function(t){return null!==t&&!A(t)&&null!==t.constructor&&!A(t.constructor)&&N(t.constructor.isBuffer)&&t.constructor.isBuffer(t)},isFormData:t=>{let e;return t&&("function"==typeof FormData&&t instanceof FormData||N(t.append)&&("formdata"===(e=O(t))||"object"===e&&N(t.toString)&&"[object FormData]"===t.toString()))},isArrayBufferView:function(t){let e;return e="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(t):t&&t.buffer&&j(t.buffer),e},isString:$,isNumber:P,isBoolean:t=>!0===t||!1===t,isObject:C,isPlainObject:U,isReadableStream:M,isRequest:q,isResponse:B,isHeaders:_,isUndefined:A,isDate:F,isFile:D,isBlob:L,isRegExp:Y,isFunction:N,isStream:t=>C(t)&&N(t.pipe),isURLSearchParams:z,isTypedArray:W,isFileList:I,forEach:H,merge:function t(){const{caseless:e}=J(this)&&this||{},n={},o=(o,r)=>{const i=e&&V(n,r)||r;U(n[i])&&U(o)?n[i]=t(n[i],o):U(o)?n[i]=t({},o):S(o)?n[i]=o.slice():n[i]=o};for(let r=0,i=arguments.length;i>r;r++)arguments[r]&&H(arguments[r],o);return n},extend:(t,e,n,{allOwnKeys:o}={})=>(H(e,((e,o)=>{n&&N(e)?t[o]=b(e,n):t[o]=e}),{allOwnKeys:o}),t),trim:t=>t.trim?t.trim():t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:t=>(65279===t.charCodeAt(0)&&(t=t.slice(1)),t),inherits:(t,e,n,o)=>{t.prototype=Object.create(e.prototype,o),t.prototype.constructor=t,Object.defineProperty(t,"super",{value:e.prototype}),n&&Object.assign(t.prototype,n)},toFlatObject:(t,e,n,o)=>{let r,i,s;const a={};if(e=e||{},null==t)return e;do{for(r=Object.getOwnPropertyNames(t),i=r.length;i-- >0;)s=r[i],o&&!o(s,t,e)||a[s]||(e[s]=t[s],a[s]=!0);t=!1!==n&&g(t)}while(t&&(!n||n(t,e))&&t!==Object.prototype);return e},kindOf:O,kindOfTest:T,endsWith:(t,e,n)=>{t+="",(void 0===n||n>t.length)&&(n=t.length),n-=e.length;const o=t.indexOf(e,n);return-1!==o&&o===n},toArray:t=>{if(!t)return null;if(S(t))return t;let e=t.length;if(!P(e))return null;const n=Array(e);for(;e-- >0;)n[e]=t[e];return n},forEachEntry:(t,e)=>{const n=(t&&t[x]).call(t);let o;for(;(o=n.next())&&!o.done;){const n=o.value;e.call(t,n[0],n[1])}},matchAll:(t,e)=>{let n;const o=[];for(;null!==(n=t.exec(e));)o.push(n);return o},isHTMLForm:G,hasOwnProperty:Z,hasOwnProp:Z,reduceDescriptors:Q,freezeMethods:t=>{Q(t,((e,n)=>{if(N(t)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const o=t[n];N(o)&&(e.enumerable=!1,"writable"in e?e.writable=!1:e.set||(e.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))}))},toObjectSet:(t,e)=>{const n={},o=t=>{t.forEach((t=>{n[t]=!0}))};return S(t)?o(t):o((t+"").split(e)),n},toCamelCase:t=>t.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(t,e,n){return e.toUpperCase()+n})),noop:()=>{},toFiniteNumber:(t,e)=>null!=t&&Number.isFinite(t=+t)?t:e,findKey:V,global:X,isContextDefined:J,isSpecCompliantForm:function(t){return!!(t&&N(t.append)&&"FormData"===t[R]&&t[x])},toJSONObject:t=>{const e=[,,,,,,,,,,],n=(t,o)=>{if(C(t)){if(e.indexOf(t)>=0)return;if(!("toJSON"in t)){e[o]=t;const r=S(t)?[]:{};return H(t,((t,e)=>{const i=n(t,o+1);!A(i)&&(r[e]=i)})),e[o]=void 0,r}}return t};return n(t,0)},isAsyncFn:tt,isThenable:t=>t&&(C(t)||N(t))&&N(t.then)&&N(t.catch),setImmediate:et,asap:st,isIterable:t=>null!=t&&N(t[x])};function ct(t,e,n,o,r){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=Error().stack,this.message=t,this.name="AxiosError",e&&(this.code=e),n&&(this.config=n),o&&(this.request=o),r&&(this.response=r,this.status=r.status?r.status:null)}at.inherits(ct,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:at.toJSONObject(this.config),code:this.code,status:this.status}}});const lt=ct.prototype,ut={};function ft(t){return at.isPlainObject(t)||at.isArray(t)}function ht(t){return at.endsWith(t,"[]")?t.slice(0,-2):t}function dt(t,e,n){return t?t.concat(e).map((function(t,e){return t=ht(t),!n&&e?"["+t+"]":t})).join(n?".":""):e}["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((t=>{ut[t]={value:t}})),Object.defineProperties(ct,ut),Object.defineProperty(lt,"isAxiosError",{value:!0}),ct.from=(t,e,n,o,r,i)=>{const s=Object.create(lt);return at.toFlatObject(t,s,(function(t){return t!==Error.prototype}),(t=>"isAxiosError"!==t)),ct.call(s,t.message,e,n,o,r),s.cause=t,s.name=t.name,i&&Object.assign(s,i),s};const pt=at.toFlatObject(at,{},null,(function(t){return/^is[A-Z]/.test(t)}));function mt(t,e,n){if(!at.isObject(t))throw new TypeError("target must be an object");e=e||new FormData;const o=(n=at.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(t,e){return!at.isUndefined(e[t])}))).metaTokens,r=n.visitor||l,i=n.dots,s=n.indexes,a=(n.Blob||"undefined"!=typeof Blob&&Blob)&&at.isSpecCompliantForm(e);if(!at.isFunction(r))throw new TypeError("visitor must be a function");function c(t){if(null===t)return"";if(at.isDate(t))return t.toISOString();if(at.isBoolean(t))return t.toString();if(!a&&at.isBlob(t))throw new ct("Blob is not supported. Use a Buffer instead.");return at.isArrayBuffer(t)||at.isTypedArray(t)?a&&"function"==typeof Blob?new Blob([t]):Buffer.from(t):t}function l(t,n,r){let a=t;if(t&&!r&&"object"==typeof t)if(at.endsWith(n,"{}"))n=o?n:n.slice(0,-2),t=JSON.stringify(t);else if(at.isArray(t)&&function(t){return at.isArray(t)&&!t.some(ft)}(t)||(at.isFileList(t)||at.endsWith(n,"[]"))&&(a=at.toArray(t)))return n=ht(n),a.forEach((function(t,o){!at.isUndefined(t)&&null!==t&&e.append(!0===s?dt([n],o,i):null===s?n:n+"[]",c(t))})),!1;return!!ft(t)||(e.append(dt(r,n,i),c(t)),!1)}const u=[],f=Object.assign(pt,{defaultVisitor:l,convertValue:c,isVisitable:ft});if(!at.isObject(t))throw new TypeError("data must be an object");return function t(n,o){if(!at.isUndefined(n)){if(-1!==u.indexOf(n))throw Error("Circular reference detected in "+o.join("."));u.push(n),at.forEach(n,(function(n,i){!0===(!(at.isUndefined(n)||null===n)&&r.call(e,n,at.isString(i)?i.trim():i,o,f))&&t(n,o?o.concat(i):[i])})),u.pop()}}(t),e}function wt(t){const e={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(t).replace(/[!'()~]|%20|%00/g,(function(t){return e[t]}))}function yt(t,e){this.o=[],t&&mt(t,this,e)}const bt=yt.prototype;function vt(t){return encodeURIComponent(t).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function gt(t,e,n){if(!e)return t;const o=n&&n.encode||vt;at.isFunction(n)&&(n={serialize:n});const r=n&&n.serialize;let i;if(i=r?r(e,n):at.isURLSearchParams(e)?e.toString():new yt(e,n).toString(o),i){const e=t.indexOf("#");-1!==e&&(t=t.slice(0,e)),t+=(-1===t.indexOf("?")?"?":"&")+i}return t}bt.append=function(t,e){this.o.push([t,e])},bt.toString=function(t){const e=t?function(e){return t.call(this,e,wt)}:wt;return this.o.map((function(t){return e(t[0])+"="+e(t[1])}),"").join("&")};const xt=class{constructor(){this.handlers=[]}use(t,e,n){return this.handlers.push({fulfilled:t,rejected:e,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){at.forEach(this.handlers,(function(e){null!==e&&t(e)}))}},Rt={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},Ot={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:yt,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]},kt="undefined"!=typeof window&&"undefined"!=typeof document,Tt="object"==typeof navigator&&navigator||void 0,Et=kt&&(!Tt||0>["ReactNative","NativeScript","NS"].indexOf(Tt.product)),St="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts,At=kt&&window.location.href||"http://localhost",jt={...Object.freeze({__proto__:null,hasBrowserEnv:kt,hasStandardBrowserWebWorkerEnv:St,hasStandardBrowserEnv:Et,navigator:Tt,origin:At}),...Ot};function $t(t){function e(t,n,o,r){let i=t[r++];if("__proto__"===i)return!0;const s=Number.isFinite(+i),a=r>=t.length;return i=!i&&at.isArray(o)?o.length:i,a?(at.hasOwnProp(o,i)?o[i]=[o[i],n]:o[i]=n,!s):(o[i]&&at.isObject(o[i])||(o[i]=[]),e(t,n,o[i],r)&&at.isArray(o[i])&&(o[i]=function(t){const e={},n=Object.keys(t);let o;const r=n.length;let i;for(o=0;r>o;o++)i=n[o],e[i]=t[i];return e}(o[i])),!s)}if(at.isFormData(t)&&at.isFunction(t.entries)){const n={};return at.forEachEntry(t,((t,o)=>{e(function(t){return at.matchAll(/\w+|\[(\w*)]/g,t).map((t=>"[]"===t[0]?"":t[1]||t[0]))}(t),o,n,0)})),n}return null}const Nt={transitional:Rt,adapter:["xhr","http","fetch"],transformRequest:[function(t,e){const n=e.getContentType()||"",o=n.indexOf("application/json")>-1,r=at.isObject(t);if(r&&at.isHTMLForm(t)&&(t=new FormData(t)),at.isFormData(t))return o?JSON.stringify($t(t)):t;if(at.isArrayBuffer(t)||at.isBuffer(t)||at.isStream(t)||at.isFile(t)||at.isBlob(t)||at.isReadableStream(t))return t;if(at.isArrayBufferView(t))return t.buffer;if(at.isURLSearchParams(t))return e.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let i;if(r){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(t,e){return mt(t,new jt.classes.URLSearchParams,Object.assign({visitor:function(t,e,n,o){return jt.isNode&&at.isBuffer(t)?(this.append(e,t.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)}},e))}(t,this.formSerializer).toString();if((i=at.isFileList(t))||n.indexOf("multipart/form-data")>-1){const e=this.env&&this.env.FormData;return mt(i?{"files[]":t}:t,e&&new e,this.formSerializer)}}return r||o?(e.setContentType("application/json",!1),function(t){if(at.isString(t))try{return(0,JSON.parse)(t),at.trim(t)}catch(t){if("SyntaxError"!==t.name)throw t}return(0,JSON.stringify)(t)}(t)):t}],transformResponse:[function(t){const e=this.transitional||Nt.transitional,n=e&&e.forcedJSONParsing,o="json"===this.responseType;if(at.isResponse(t)||at.isReadableStream(t))return t;if(t&&at.isString(t)&&(n&&!this.responseType||o)){const n=!(e&&e.silentJSONParsing)&&o;try{return JSON.parse(t)}catch(t){if(n){if("SyntaxError"===t.name)throw ct.from(t,ct.ERR_BAD_RESPONSE,this,null,this.response);throw t}}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:jt.classes.FormData,Blob:jt.classes.Blob},validateStatus:function(t){return t>=200&&300>t},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};at.forEach(["delete","get","head","post","put","patch"],(t=>{Nt.headers[t]={}}));const Pt=Nt,Ct=at.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Ut=Symbol("internals");function Ft(t){return t&&(t+"").trim().toLowerCase()}function Dt(t){return!1===t||null==t?t:at.isArray(t)?t.map(Dt):t+""}function Lt(t,e,n,o,r){return at.isFunction(o)?o.call(this,e,n):(r&&(e=n),at.isString(e)?at.isString(o)?-1!==e.indexOf(o):at.isRegExp(o)?o.test(e):void 0:void 0)}class It{constructor(t){t&&this.set(t)}set(t,e,n){const o=this;function r(t,e,n){const r=Ft(e);if(!r)throw Error("header name must be a non-empty string");const i=at.findKey(o,r);(!i||void 0===o[i]||!0===n||void 0===n&&!1!==o[i])&&(o[i||e]=Dt(t))}const i=(t,e)=>at.forEach(t,((t,n)=>r(t,n,e)));if(at.isPlainObject(t)||t instanceof this.constructor)i(t,e);else if(at.isString(t)&&(t=t.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(t.trim()))i((t=>{const e={};let n,o,r;return t&&t.split("\n").forEach((function(t){r=t.indexOf(":"),n=t.substring(0,r).trim().toLowerCase(),o=t.substring(r+1).trim(),!n||e[n]&&Ct[n]||("set-cookie"===n?e[n]?e[n].push(o):e[n]=[o]:e[n]=e[n]?e[n]+", "+o:o)})),e})(t),e);else if(at.isObject(t)&&at.isIterable(t)){let n,o,r={};for(const e of t){if(!at.isArray(e))throw TypeError("Object iterator must return a key-value pair");r[o=e[0]]=(n=r[o])?at.isArray(n)?[...n,e[1]]:[n,e[1]]:e[1]}i(r,e)}else null!=t&&r(e,t,n);return this}get(t,e){if(t=Ft(t)){const n=at.findKey(this,t);if(n){const t=this[n];if(!e)return t;if(!0===e)return function(t){const e=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let o;for(;o=n.exec(t);)e[o[1]]=o[2];return e}(t);if(at.isFunction(e))return e.call(this,t,n);if(at.isRegExp(e))return e.exec(t);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,e){if(t=Ft(t)){const n=at.findKey(this,t);return!(!n||void 0===this[n]||e&&!Lt(0,this[n],n,e))}return!1}delete(t,e){const n=this;let o=!1;function r(t){if(t=Ft(t)){const r=at.findKey(n,t);!r||e&&!Lt(0,n[r],r,e)||(delete n[r],o=!0)}}return at.isArray(t)?t.forEach(r):r(t),o}clear(t){const e=Object.keys(this);let n=e.length,o=!1;for(;n--;){const r=e[n];t&&!Lt(0,this[r],r,t,!0)||(delete this[r],o=!0)}return o}normalize(t){const e=this,n={};return at.forEach(this,((o,r)=>{const i=at.findKey(n,r);if(i)return e[i]=Dt(o),void delete e[r];const s=t?function(t){return t.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,((t,e,n)=>e.toUpperCase()+n))}(r):(r+"").trim();s!==r&&delete e[r],e[s]=Dt(o),n[s]=!0})),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const e=Object.create(null);return at.forEach(this,((n,o)=>{null!=n&&!1!==n&&(e[o]=t&&at.isArray(n)?n.join(", "):n)})),e}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map((([t,e])=>t+": "+e)).join("\n")}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...e){const n=new this(t);return e.forEach((t=>n.set(t))),n}static accessor(t){const e=(this[Ut]=this[Ut]={accessors:{}}).accessors,n=this.prototype;function o(t){const o=Ft(t);e[o]||(function(t,e){const n=at.toCamelCase(" "+e);["get","set","has"].forEach((o=>{Object.defineProperty(t,o+n,{value:function(t,n,r){return this[o].call(this,e,t,n,r)},configurable:!0})}))}(n,t),e[o]=!0)}return at.isArray(t)?t.forEach(o):o(t),this}}It.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),at.reduceDescriptors(It.prototype,(({value:t},e)=>{let n=e[0].toUpperCase()+e.slice(1);return{get:()=>t,set(t){this[n]=t}}})),at.freezeMethods(It);const zt=It;function Mt(t,e){const n=this||Pt,o=e||n,r=zt.from(o.headers);let i=o.data;return at.forEach(t,(function(t){i=t.call(n,i,r.normalize(),e?e.status:void 0)})),r.normalize(),i}function qt(t){return!(!t||!t.i)}function Bt(t,e,n){ct.call(this,t??"canceled",ct.ERR_CANCELED,e,n),this.name="CanceledError"}function _t(t,e,n){const o=n.config.validateStatus;n.status&&o&&!o(n.status)?e(new ct("Request failed with status code "+n.status,[ct.ERR_BAD_REQUEST,ct.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):t(n)}at.inherits(Bt,ct,{i:!0});const Ht=(t,e,n=3)=>{let o=0;const r=function(t,e){const n=Array(t=t||10),o=Array(t);let r,i=0,s=0;return e=void 0!==e?e:1e3,function(a){const c=Date.now(),l=o[s];r||(r=c),n[i]=a,o[i]=c;let u=s,f=0;for(;u!==i;)f+=n[u++],u%=t;if(i=(i+1)%t,i===s&&(s=(s+1)%t),e>c-r)return;const h=l&&c-l;return h?Math.round(1e3*f/h):void 0}}(50,250);return function(t,e){let n,o,r=0,i=1e3/e;const s=(e,i=Date.now())=>{r=i,n=null,o&&(clearTimeout(o),o=null),t.apply(null,e)};return[(...t)=>{const e=Date.now(),a=e-r;i>a?(n=t,o||(o=setTimeout((()=>{o=null,s(n)}),i-a))):s(t,e)},()=>n&&s(n)]}((n=>{const i=n.loaded,s=n.lengthComputable?n.total:void 0,a=i-o,c=r(a);o=i,t({loaded:i,total:s,progress:s?i/s:void 0,bytes:a,rate:c||void 0,estimated:c&&s&&s>=i?(s-i)/c:void 0,event:n,lengthComputable:null!=s,[e?"download":"upload"]:!0})}),n)},Vt=(t,e)=>{const n=null!=t;return[o=>e[0]({lengthComputable:n,total:t,loaded:o}),e[1]]},Xt=t=>(...e)=>at.asap((()=>t(...e))),Jt=jt.hasStandardBrowserEnv?((t,e)=>n=>(n=new URL(n,jt.origin),t.protocol===n.protocol&&t.host===n.host&&(e||t.port===n.port)))(new URL(jt.origin),jt.navigator&&/(msie|trident)/i.test(jt.navigator.userAgent)):()=>!0,Wt=jt.hasStandardBrowserEnv?{write(t,e,n,o,r,i){const s=[t+"="+encodeURIComponent(e)];at.isNumber(n)&&s.push("expires="+new Date(n).toGMTString()),at.isString(o)&&s.push("path="+o),at.isString(r)&&s.push("domain="+r),!0===i&&s.push("secure"),document.cookie=s.join("; ")},read(t){const e=document.cookie.match(RegExp("(^|;\\s*)("+t+")=([^;]*)"));return e?decodeURIComponent(e[3]):null},remove(t){this.write(t,"",Date.now()-864e5)}}:{write(){},read:()=>null,remove(){}};function Kt(t,e,n){return!t||/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)&&0!=n?e:function(t,e){return e?t.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):t}(t,e)}const Gt=t=>t instanceof zt?{...t}:t;function Zt(t,e){e=e||{};const n={};function o(t,e,n,o){return at.isPlainObject(t)&&at.isPlainObject(e)?at.merge.call({caseless:o},t,e):at.isPlainObject(e)?at.merge({},e):at.isArray(e)?e.slice():e}function r(t,e,n,r){return at.isUndefined(e)?at.isUndefined(t)?void 0:o(void 0,t,0,r):o(t,e,0,r)}function i(t,e){if(!at.isUndefined(e))return o(void 0,e)}function s(t,e){return at.isUndefined(e)?at.isUndefined(t)?void 0:o(void 0,t):o(void 0,e)}function a(n,r,i){return i in e?o(n,r):i in t?o(void 0,n):void 0}const c={url:i,method:i,data:i,baseURL:s,transformRequest:s,transformResponse:s,paramsSerializer:s,timeout:s,timeoutMessage:s,withCredentials:s,withXSRFToken:s,adapter:s,responseType:s,xsrfCookieName:s,xsrfHeaderName:s,onUploadProgress:s,onDownloadProgress:s,decompress:s,maxContentLength:s,maxBodyLength:s,beforeRedirect:s,transport:s,httpAgent:s,httpsAgent:s,cancelToken:s,socketPath:s,responseEncoding:s,validateStatus:a,headers:(t,e,n)=>r(Gt(t),Gt(e),0,!0)};return at.forEach(Object.keys(Object.assign({},t,e)),(function(o){const i=c[o]||r,s=i(t[o],e[o],o);at.isUndefined(s)&&i!==a||(n[o]=s)})),n}const Yt=t=>{const e=Zt({},t);let n,{data:o,withXSRFToken:r,xsrfHeaderName:i,xsrfCookieName:s,headers:a,auth:c}=e;if(e.headers=a=zt.from(a),e.url=gt(Kt(e.baseURL,e.url,e.allowAbsoluteUrls),t.params,t.paramsSerializer),c&&a.set("Authorization","Basic "+btoa((c.username||"")+":"+(c.password?unescape(encodeURIComponent(c.password)):""))),at.isFormData(o))if(jt.hasStandardBrowserEnv||jt.hasStandardBrowserWebWorkerEnv)a.setContentType(void 0);else if(!1!==(n=a.getContentType())){const[t,...e]=n?n.split(";").map((t=>t.trim())).filter(Boolean):[];a.setContentType([t||"multipart/form-data",...e].join("; "))}if(jt.hasStandardBrowserEnv&&(r&&at.isFunction(r)&&(r=r(e)),r||!1!==r&&Jt(e.url))){const t=i&&s&&Wt.read(s);t&&a.set(i,t)}return e},Qt="undefined"!=typeof XMLHttpRequest&&function(t){return new Promise((function(e,n){const o=Yt(t);let r=o.data;const i=zt.from(o.headers).normalize();let s,a,c,l,u,{responseType:f,onUploadProgress:h,onDownloadProgress:d}=o;function p(){l&&l(),u&&u(),o.cancelToken&&o.cancelToken.unsubscribe(s),o.signal&&o.signal.removeEventListener("abort",s)}let m=new XMLHttpRequest;function w(){if(!m)return;const o=zt.from("getAllResponseHeaders"in m&&m.getAllResponseHeaders());_t((function(t){e(t),p()}),(function(t){n(t),p()}),{data:f&&"text"!==f&&"json"!==f?m.response:m.responseText,status:m.status,statusText:m.statusText,headers:o,config:t,request:m}),m=null}m.open(o.method.toUpperCase(),o.url,!0),m.timeout=o.timeout,"onloadend"in m?m.onloadend=w:m.onreadystatechange=function(){m&&4===m.readyState&&(0!==m.status||m.responseURL&&0===m.responseURL.indexOf("file:"))&&setTimeout(w)},m.onabort=function(){m&&(n(new ct("Request aborted",ct.ECONNABORTED,t,m)),m=null)},m.onerror=function(){n(new ct("Network Error",ct.ERR_NETWORK,t,m)),m=null},m.ontimeout=function(){let e=o.timeout?"timeout of "+o.timeout+"ms exceeded":"timeout exceeded";const r=o.transitional||Rt;o.timeoutErrorMessage&&(e=o.timeoutErrorMessage),n(new ct(e,r.clarifyTimeoutError?ct.ETIMEDOUT:ct.ECONNABORTED,t,m)),m=null},void 0===r&&i.setContentType(null),"setRequestHeader"in m&&at.forEach(i.toJSON(),(function(t,e){m.setRequestHeader(e,t)})),at.isUndefined(o.withCredentials)||(m.withCredentials=!!o.withCredentials),f&&"json"!==f&&(m.responseType=o.responseType),d&&([c,u]=Ht(d,!0),m.addEventListener("progress",c)),h&&m.upload&&([a,l]=Ht(h),m.upload.addEventListener("progress",a),m.upload.addEventListener("loadend",l)),(o.cancelToken||o.signal)&&(s=e=>{m&&(n(!e||e.type?new Bt(null,t,m):e),m.abort(),m=null)},o.cancelToken&&o.cancelToken.subscribe(s),o.signal&&(o.signal.aborted?s():o.signal.addEventListener("abort",s)));const y=function(t){const e=/^([-+\w]{1,25})(:?\/\/|:)/.exec(t);return e&&e[1]||""}(o.url);y&&-1===jt.protocols.indexOf(y)?n(new ct("Unsupported protocol "+y+":",ct.ERR_BAD_REQUEST,t)):m.send(r||null)}))},te=(t,e)=>{const{length:n}=t=t?t.filter(Boolean):[];if(e||n){let n,o=new AbortController;const r=function(t){if(!n){n=!0,s();const e=t instanceof Error?t:this.reason;o.abort(e instanceof ct?e:new Bt(e instanceof Error?e.message:e))}};let i=e&&setTimeout((()=>{i=null,r(new ct(`timeout ${e} of ms exceeded`,ct.ETIMEDOUT))}),e);const s=()=>{t&&(i&&clearTimeout(i),i=null,t.forEach((t=>{t.unsubscribe?t.unsubscribe(r):t.removeEventListener("abort",r)})),t=null)};t.forEach((t=>t.addEventListener("abort",r)));const{signal:a}=o;return a.unsubscribe=()=>at.asap(s),a}},ee=function*(t,e){let n=t.byteLength;if(e>n)return void(yield t);let o,r=0;for(;n>r;)o=r+e,yield t.slice(r,o),r=o},ne=(t,e,n,o)=>{const r=async function*(t,e){for await(const n of async function*(t){if(t[Symbol.asyncIterator])return void(yield*t);const e=t.getReader();try{for(;;){const{done:t,value:n}=await e.read();if(t)break;yield n}}finally{await e.cancel()}}(t))yield*ee(n,e)}(t,e);let i,s=0,a=t=>{i||(i=!0,o&&o(t))};return new ReadableStream({async pull(t){try{const{done:e,value:o}=await r.next();if(e)return a(),void t.close();let i=o.byteLength;if(n){let t=s+=i;n(t)}t.enqueue(new Uint8Array(o))}catch(t){throw a(t),t}},cancel:t=>(a(t),r.return())},{highWaterMark:2})},oe="function"==typeof fetch&&"function"==typeof Request&&"function"==typeof Response,re=oe&&"function"==typeof ReadableStream,ie=oe&&("function"==typeof TextEncoder?(se=new TextEncoder,t=>se.encode(t)):async t=>new Uint8Array(await new Response(t).arrayBuffer()));var se;const ae=(t,...e)=>{try{return!!t(...e)}catch(t){return!1}},ce=re&&ae((()=>{let t=!1;const e=new Request(jt.origin,{body:new ReadableStream,method:"POST",get duplex(){return t=!0,"half"}}).headers.has("Content-Type");return t&&!e})),le=re&&ae((()=>at.isReadableStream(new Response("").body))),ue={stream:le&&(t=>t.body)};var fe;oe&&(fe=new Response,["text","arrayBuffer","blob","formData","stream"].forEach((t=>{!ue[t]&&(ue[t]=at.isFunction(fe[t])?e=>e[t]():(e,n)=>{throw new ct(`Response type '${t}' is not supported`,ct.ERR_NOT_SUPPORT,n)})})));const he={http:null,xhr:Qt,fetch:oe&&(async t=>{let{url:e,method:n,data:o,signal:r,cancelToken:i,timeout:s,onDownloadProgress:a,onUploadProgress:c,responseType:l,headers:u,withCredentials:f="same-origin",fetchOptions:h}=Yt(t);l=l?(l+"").toLowerCase():"text";let d,p=te([r,i&&i.toAbortSignal()],s);const m=p&&p.unsubscribe&&(()=>{p.unsubscribe()});let w;try{if(c&&ce&&"get"!==n&&"head"!==n&&0!==(w=await(async(t,e)=>at.toFiniteNumber(t.getContentLength())??(async t=>{if(null==t)return 0;if(at.isBlob(t))return t.size;if(at.isSpecCompliantForm(t)){const e=new Request(jt.origin,{method:"POST",body:t});return(await e.arrayBuffer()).byteLength}return at.isArrayBufferView(t)||at.isArrayBuffer(t)?t.byteLength:(at.isURLSearchParams(t)&&(t+=""),at.isString(t)?(await ie(t)).byteLength:void 0)})(e))(u,o))){let t,n=new Request(e,{method:"POST",body:o,duplex:"half"});if(at.isFormData(o)&&(t=n.headers.get("content-type"))&&u.setContentType(t),n.body){const[t,e]=Vt(w,Ht(Xt(c)));o=ne(n.body,65536,t,e)}}at.isString(f)||(f=f?"include":"omit");const r="credentials"in Request.prototype;d=new Request(e,{...h,signal:p,method:n.toUpperCase(),headers:u.normalize().toJSON(),body:o,duplex:"half",credentials:r?f:void 0});let i=await fetch(d,h);const s=le&&("stream"===l||"response"===l);if(le&&(a||s&&m)){const t={};["status","statusText","headers"].forEach((e=>{t[e]=i[e]}));const e=at.toFiniteNumber(i.headers.get("content-length")),[n,o]=a&&Vt(e,Ht(Xt(a),!0))||[];i=new Response(ne(i.body,65536,n,(()=>{o&&o(),m&&m()})),t)}l=l||"text";let y=await ue[at.findKey(ue,l)||"text"](i,t);return!s&&m&&m(),await new Promise(((e,n)=>{_t(e,n,{data:y,headers:zt.from(i.headers),status:i.status,statusText:i.statusText,config:t,request:d})}))}catch(e){if(m&&m(),e&&"TypeError"===e.name&&/Load failed|fetch/i.test(e.message))throw Object.assign(new ct("Network Error",ct.ERR_NETWORK,t,d),{cause:e.cause||e});throw ct.from(e,e&&e.code,t,d)}})};at.forEach(he,((t,e)=>{if(t){try{Object.defineProperty(t,"name",{value:e})}catch(t){}Object.defineProperty(t,"adapterName",{value:e})}}));const de=t=>"- "+t,pe=t=>at.isFunction(t)||null===t||!1===t,me=t=>{t=at.isArray(t)?t:[t];const{length:e}=t;let n,o;const r={};for(let i=0;e>i;i++){let e;if(n=t[i],o=n,!pe(n)&&(o=he[(e=n+"").toLowerCase()],void 0===o))throw new ct(`Unknown adapter '${e}'`);if(o)break;r[e||"#"+i]=o}if(!o){const t=Object.entries(r).map((([t,e])=>`adapter ${t} `+(!1===e?"is not supported by the environment":"is not available in the build")));throw new ct("There is no suitable adapter to dispatch the request "+(e?t.length>1?"since :\n"+t.map(de).join("\n"):" "+de(t[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return o};function we(t){if(t.cancelToken&&t.cancelToken.throwIfRequested(),t.signal&&t.signal.aborted)throw new Bt(null,t)}function ye(t){return we(t),t.headers=zt.from(t.headers),t.data=Mt.call(t,t.transformRequest),-1!==["post","put","patch"].indexOf(t.method)&&t.headers.setContentType("application/x-www-form-urlencoded",!1),me(t.adapter||Pt.adapter)(t).then((function(e){return we(t),e.data=Mt.call(t,t.transformResponse,e),e.headers=zt.from(e.headers),e}),(function(e){return qt(e)||(we(t),e&&e.response&&(e.response.data=Mt.call(t,t.transformResponse,e.response),e.response.headers=zt.from(e.response.headers))),Promise.reject(e)}))}const be={};["object","boolean","number","function","string","symbol"].forEach(((t,e)=>{be[t]=function(n){return typeof n===t||"a"+(1>e?"n ":" ")+t}}));const ve={};be.transitional=function(t,e,n){function o(t,e){return"[Axios v1.10.0] Transitional option '"+t+"'"+e+(n?". "+n:"")}return(n,r,i)=>{if(!1===t)throw new ct(o(r," has been removed"+(e?" in "+e:"")),ct.ERR_DEPRECATED);return e&&!ve[r]&&(ve[r]=!0),!t||t(n,r,i)}},be.spelling=function(t){return(t,e)=>!0};const ge={assertOptions:function(t,e,n){if("object"!=typeof t)throw new ct("options must be an object",ct.ERR_BAD_OPTION_VALUE);const o=Object.keys(t);let r=o.length;for(;r-- >0;){const i=o[r],s=e[i];if(s){const e=t[i],n=void 0===e||s(e,i,t);if(!0!==n)throw new ct("option "+i+" must be "+n,ct.ERR_BAD_OPTION_VALUE)}else if(!0!==n)throw new ct("Unknown option "+i,ct.ERR_BAD_OPTION)}},validators:be},xe=ge.validators;class Re{constructor(t){this.defaults=t||{},this.interceptors={request:new xt,response:new xt}}async request(t,e){try{return await this.l(t,e)}catch(t){if(t instanceof Error){let e={};Error.captureStackTrace?Error.captureStackTrace(e):e=Error();const n=e.stack?e.stack.replace(/^.+\n/,""):"";try{t.stack?n&&!(t.stack+"").endsWith(n.replace(/^.+\n.+\n/,""))&&(t.stack+="\n"+n):t.stack=n}catch(t){}}throw t}}l(t,e){"string"==typeof t?(e=e||{}).url=t:e=t||{},e=Zt(this.defaults,e);const{transitional:n,paramsSerializer:o,headers:r}=e;void 0!==n&&ge.assertOptions(n,{silentJSONParsing:xe.transitional(xe.boolean),forcedJSONParsing:xe.transitional(xe.boolean),clarifyTimeoutError:xe.transitional(xe.boolean)},!1),null!=o&&(at.isFunction(o)?e.paramsSerializer={serialize:o}:ge.assertOptions(o,{encode:xe.function,serialize:xe.function},!0)),void 0!==e.allowAbsoluteUrls||(void 0!==this.defaults.allowAbsoluteUrls?e.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:e.allowAbsoluteUrls=!0),ge.assertOptions(e,{baseUrl:xe.spelling("baseURL"),withXsrfToken:xe.spelling("withXSRFToken")},!0),e.method=(e.method||this.defaults.method||"get").toLowerCase();let i=r&&at.merge(r.common,r[e.method]);r&&at.forEach(["delete","get","head","post","put","patch","common"],(t=>{delete r[t]})),e.headers=zt.concat(i,r);const s=[];let a=!0;this.interceptors.request.forEach((function(t){"function"==typeof t.runWhen&&!1===t.runWhen(e)||(a=a&&t.synchronous,s.unshift(t.fulfilled,t.rejected))}));const c=[];let l;this.interceptors.response.forEach((function(t){c.push(t.fulfilled,t.rejected)}));let u,f=0;if(!a){const t=[ye.bind(this),void 0];for(t.unshift.apply(t,s),t.push.apply(t,c),u=t.length,l=Promise.resolve(e);u>f;)l=l.then(t[f++],t[f++]);return l}u=s.length;let h=e;for(f=0;u>f;){const e=s[f++],n=s[f++];try{h=e(h)}catch(t){n.call(this,t);break}}try{l=ye(h)}catch(t){return Promise.reject(t)}for(f=0,u=c.length;u>f;)l=l.then(c[f++],c[f++]);return l}getUri(t){return gt(Kt((t=Zt(this.defaults,t)).baseURL,t.url,t.allowAbsoluteUrls),t.params,t.paramsSerializer)}}at.forEach(["delete","get","head","options"],(function(t){Re.prototype[t]=function(e,n){return this.request(Zt(n||{},{method:t,url:e,data:(n||{}).data}))}})),at.forEach(["post","put","patch"],(function(t){function e(e){return function(n,o,r){return this.request(Zt(r||{},{method:t,headers:e?{"Content-Type":"multipart/form-data"}:{},url:n,data:o}))}}Re.prototype[t]=e(),Re.prototype[t+"Form"]=e(!0)}));const Oe=Re;class ke{constructor(t){if("function"!=typeof t)throw new TypeError("executor must be a function.");let e;this.promise=new Promise((function(t){e=t}));const n=this;this.promise.then((t=>{if(!n.u)return;let e=n.u.length;for(;e-- >0;)n.u[e](t);n.u=null})),this.promise.then=t=>{let e;const o=new Promise((t=>{n.subscribe(t),e=t})).then(t);return o.cancel=function(){n.unsubscribe(e)},o},t((function(t,o,r){n.reason||(n.reason=new Bt(t,o,r),e(n.reason))}))}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){this.reason?t(this.reason):this.u?this.u.push(t):this.u=[t]}unsubscribe(t){if(!this.u)return;const e=this.u.indexOf(t);-1!==e&&this.u.splice(e,1)}toAbortSignal(){const t=new AbortController,e=e=>{t.abort(e)};return this.subscribe(e),t.signal.unsubscribe=()=>this.unsubscribe(e),t.signal}static source(){let t;return{token:new ke((function(e){t=e})),cancel:t}}}const Te=ke,Ee={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Ee).forEach((([t,e])=>{Ee[e]=t}));const Se=Ee,Ae=function t(e){const n=new Oe(e),o=b(Oe.prototype.request,n);return at.extend(o,Oe.prototype,n,{allOwnKeys:!0}),at.extend(o,n,null,{allOwnKeys:!0}),o.create=function(n){return t(Zt(e,n))},o}(Pt);Ae.Axios=Oe,Ae.CanceledError=Bt,Ae.CancelToken=Te,Ae.isCancel=qt,Ae.VERSION="1.10.0",Ae.toFormData=mt,Ae.AxiosError=ct,Ae.Cancel=Ae.CanceledError,Ae.all=function(t){return Promise.all(t)},Ae.spread=function(t){return function(e){return t.apply(null,e)}},Ae.isAxiosError=function(t){return at.isObject(t)&&!0===t.isAxiosError},Ae.mergeConfig=Zt,Ae.AxiosHeaders=zt,Ae.formToJSON=t=>$t(at.isHTMLForm(t)?new FormData(t):t),Ae.getAdapter=me,Ae.HttpStatusCode=Se,Ae.default=Ae;const je=Ae,{Axios:$e,AxiosError:Ne,CanceledError:Pe,isCancel:Ce,CancelToken:Ue,VERSION:Fe,all:De,Cancel:Le,isAxiosError:Ie,spread:ze,toFormData:Me,AxiosHeaders:qe,HttpStatusCode:Be,formToJSON:_e,getAdapter:He,mergeConfig:Ve}=je,Xe=new class{constructor(){this.scopeAttribute="",this.scopeBody="",this.scopedKeyframes=new Map}parse(t,e){return this.scopeAttribute=`[vrefof="${e}"]`,this.scopeBody=`[vref="${e}"]`,this.scopedKeyframes.clear(),this.scopeSuffix=e.replace(/[^a-zA-Z0-9]/g,""),t=this.removeComments(t),this.collectKeyframes(t),this.parseRules(t)}collectKeyframes(t){const e=/@keyframes\s+([^\s{]+)/gi;let n;for(;null!==(n=e.exec(t));){const t=n[1],e=t+"-"+this.scopeSuffix;this.scopedKeyframes.set(t,e)}}removeComments(t){return t.replace(/\/\*[\s\S]*?\*\//g,"")}parseRules(t){let e="",n=0;for(;n=t.length)break;if("@"===t[n]){const o=this.parseAtRule(t,n);e+=o.content,n=o.endIndex}else{const o=this.parseNormalRule(t,n);e+=o.content,n=o.endIndex}}return e}parseAtRule(t,e){let n=e,o="";for(;n=t.length)return{content:o,endIndex:n};const r=o.toLowerCase().trim();if(r.startsWith("@keyframes"))return this.parseKeyframes(t,e);if(r.startsWith("@media"))return this.parseMedia(t,e);if(r.startsWith("@supports"))return this.parseSupports(t,e);{const e=this.findMatchingBrace(t,n);return{content:o+e.content,endIndex:e.endIndex}}}parseKeyframes(t,e){let n=e,o="";for(;n=t.length)return{content:o,endIndex:n};const r=this.findMatchingBrace(t,n),i=r.content,s=this.extractKeyframeName(o),a=this.scopedKeyframes.get(s);return a&&(o=o.replace(s,a)),o+=i,{content:o,endIndex:r.endIndex}}extractKeyframeName(t){const e=t.match(/@keyframes\s+([^\s{]+)/i);return e?e[1]:""}parseMedia(t,e){let n=e,o="";for(;n=t.length)return{content:o,endIndex:n};o+="{",n++;let r=1,i="";for(;n0;){if("{"===t[n])r++;else if("}"===t[n]&&(r--,0===r))break;i+=t[n],n++}return o+=this.parseRules(i),n=t.length)return{content:o,endIndex:n};const r=this.addScopeToSelector(o.trim()),i=this.findMatchingBrace(t,n);return{content:r+this.processRuleContent(i.content),endIndex:i.endIndex}}processRuleContent(t){let e=t;return e=e.replace(/animation\s*:\s*([^;]+);/gi,((t,e)=>`animation: ${this.processAnimationValue(e)};`)),e=e.replace(/animation-name\s*:\s*([^;]+);/gi,((t,e)=>`animation-name: ${this.processAnimationNames(e)};`)),e}processAnimationValue(t){return t.split(",").map((t=>t.trim())).map((t=>{const e=t.split(/\s+/);for(let n=0;n{const e=t.trim();return this.scopedKeyframes.get(e)||e})).join(", ")}addScopeToSelector(t){return t.trim()?t.split(",").map((t=>t.trim())).map((t=>this.addScopeToSingleSelector(t))).join(", "):t}addScopeToSingleSelector(t){if(!t.trim())return t;if(t.includes("::")){const e=t.split("::"),n=e[0],o="::"+e.slice(1).join("::");return this.addScopeToSelectorPart(n)+o}if(t.includes(":")&&!t.includes("::")){const e=t.match(/^([^:]+)(:.+)$/);if(e){const t=e[1],n=e[2];return this.addScopeToSelectorPart(t)+n}}return"*"===t||t.startsWith("@")?t:this.addScopeToSelectorPart(t)}addScopeToSelectorPart(t){const e=/(\s*[>+~]\s*|\s+)/;if(e.test(t)){const n=t.split(e);if(/^body(?:$|[:\[ ])/.test(n[0]))return n[0]=this.scopeBody+n[0].slice(4),n.join("");if(/^:root(?:$|[:\[ ])/.test(n[0]))return n[0]=this.scopeBody+n[0].slice(5),n.join("");for(let t=n.length-1;t>=0;t--)if(n[t].trim()&&!e.test(n[t])){let e=n[t].trim();n[t]=/^body(?:$|[:\[ ])/.test(e)?this.scopeBody+e.slice(4):/^:root(?:$:[$:\[ ])/.test(e)?this.scopeBody+e.slice(5):n[t].trim()+this.scopeAttribute;break}return n.join("")}let n=(t=t.trim()).trim();return/^body(?:$|[:\[ ])/.test(n)?this.scopeBody+n.slice(4):/^:root(?:$:[$:\[ ])/.test(n)?this.scopeBody+n.slice(5):n+this.scopeAttribute}findMatchingBrace(t,e){let n=e,o="",r=0;for(;n{this.removeMessage(s),i&&i()},s.appendChild(t)}return this.container.appendChild(s),setTimeout((()=>{s.classList.add("show")}),10),o>0&&setTimeout((()=>{this.removeMessage(s),i&&i()}),o),s}removeMessage(t){t&&t.parentNode&&(t.classList.remove("show"),setTimeout((()=>{t.parentNode&&t.parentNode.removeChild(t)}),300))}success(t,e={}){return this.createMessage("success",t,e)}warning(t,e={}){return this.createMessage("warning",t,e)}error(t,e={}){return this.createMessage("error",t,e)}info(t,e={}){return this.createMessage("info",t,e)}h(t,e={}){return new Promise(((n,o)=>{const{title:r="\u63d0\u793a",type:i="confirm",inputValue:s="",confirmText:a="\u786e\u5b9a",cancelText:c="\u53d6\u6d88",onConfirm:l=null,onCancel:u=()=>{n("")}}=e,f=document.createElement("div");f.className="prompt-overlay";const h=document.createElement("div");h.className="prompt-dialog";const d=document.createElement("div");d.className="prompt-header";const p=document.createElement("h3");p.className="prompt-title",p.textContent=r;const m=document.createElement("button");m.className="prompt-close",m.innerHTML="×",d.appendChild(p),d.appendChild(m);const w=document.createElement("div");w.className="prompt-body";const y=document.createElement("div");y.className="prompt-content",y.textContent=t,w.appendChild(y);let b=null;"input"===i&&(b=document.createElement("input"),b.className="prompt-input",b.type="text",b.value=s,w.appendChild(b));const v=document.createElement("div");v.className="prompt-footer";const g=document.createElement("button");g.className="prompt-btn prompt-btn-cancel",g.textContent=c;const x=document.createElement("button");x.className="prompt-btn prompt-btn-confirm",x.textContent=a,v.appendChild(g),v.appendChild(x),h.appendChild(d),h.appendChild(w),h.appendChild(v),f.appendChild(h),document.body.appendChild(f),setTimeout((()=>{f.classList.add("show")}),10),b&&setTimeout((()=>{b.focus()}),300);const R=(t=null)=>(f.classList.remove("show"),setTimeout((()=>{f.parentNode&&f.parentNode.removeChild(f)}),300),t);m.onclick=()=>{R(),u?u():o(Error("cancelled"))},g.onclick=()=>{R(),u?u():o(Error("cancelled"))},x.onclick=()=>{const t=!b||b.value;R(),n(t),l&&l(t)};const O=t=>{"Escape"===t.key&&(R(),u?u():o(Error("cancelled")),document.removeEventListener("keydown",O))};document.addEventListener("keydown",O),f.onclick=t=>{t.target===f&&(R(),u?u():o(Error("cancelled")))}}))}confirm(t,e={}){return this.h(t,{...e,type:"confirm"})}prompt(t,e,n={}){return this.h(t,{...n,type:"input",inputValue:e})}};var We={},Ke={};const Ge={};function Ze(t,e){Array.from(t.childNodes).forEach((t=>{1===t.nodeType&&(t.setAttribute("vrefof",e),Ze(t,e))}))}async function Ye(t,e,n,o){void 0===n&&(n="#"+function(){let t=(new Date).getTime().toString(36);t.length>4&&(t=t.substring(t.length-4));let e="";for(let n=0;4>n;n++)e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".charAt(Math.floor(52*Math.random()));return e+t.padStart(4,"0")}()),n.endsWith(".html")&&(n=n.slice(0,-5));let r=(new DOMParser).parseFromString(t,"text/html");if(r.body.hasAttribute("root")&&!o)throw Error("HTTP error! status: 404");let i={url:n,heads:[],body:document.createElement("div"),setup:void 0,scripts:[],styles:"",txt:t,env:e,tmp:r,customAttrs:{}};if(i.heads=Array.from(r.querySelector("head")?.children),n&&(r.querySelectorAll("style").forEach((t=>{null===t.getAttribute("unscoped")?i.styles+=Xe.parse(t.innerHTML,n):i.styles+=t.innerHTML})),i.styles)){const t=document.createElement("style");t.innerHTML=i.styles,t.setAttribute("vref",n),document.head.appendChild(t)}return i.body.append(...r.querySelector("body").childNodes),i.body.querySelectorAll("script").forEach((t=>{""!=t.innerHTML.trim()?(t.hasAttribute("setup")?i.setup=t:t.hasAttribute("novyes")||i.scripts.push(t),t.remove()):t.remove()})),Array.from(r.body.attributes).forEach((t=>{/^[a-zA-Z]/.test(t.name)?i.body.setAttribute(t.name,t.value):i.customAttrs[t.name]=t.value})),i.body.setAttribute("vref",n),Ze(i.body,n),o||await async function(t,e){for(let n of t.heads){let o=n.nodeName.toLowerCase();"link"===o?tn(n,e):"script"===o?await Qe(n,e):"title"===o&&(t.title=n.innerText)}}(i,e),i}function Qe(t,e){let n=t.getAttribute("src"),o=t.getAttribute("key"),r=e?.root;if(r&&n.startsWith("/")&&(n=r+n),n.startsWith("@")&&(n=n.slice(1)),n&&document.querySelector(`script[src="${n}"]`))return;if(o&&document.querySelector(`script[key="${o}"]`))return;let i=document.createElement("script");return i.src=n,i.key=o,i.type=t.getAttribute("type")||"text/javascript",new Promise(((t,e)=>{i.onload=()=>{t(i)},i.onerror=()=>e(Error("Failed to load script "+n)),document.head.appendChild(i)}))}async function tn(t,e){let n=t.getAttribute("href"),o=t.getAttribute("key"),r=e?.root;r&&n.startsWith("/")&&(n=r+n),n.startsWith("@")&&(n=n.slice(1)),n&&document.querySelector(`link[href="${n}"]`)||o&&document.querySelector(`link[key="${o}"]`)||(t.setAttribute("href",n),document.head.append(t))}const en={FetchUI:async function(t,e,n){t&&"/"!==t||(t="/root.html"),t.startsWith("http")||t.startsWith("@")||t.startsWith("/")||(t="/"+t);let o=e?.root;if(o&&t.startsWith("/")&&(t=o+t),t.startsWith("@")&&(t=t.slice(1)),We[t])return Promise.resolve(We[t]);if(Ke[t])return Ke[t];let r={};const i=fetch(t+"?random="+Math.random()).then((async e=>{if(!e.ok)throw Error("HTTP error! status: "+e.status);for(const[t,i]of e.headers.entries())t.startsWith("vyes-")&&(r[t.slice(5)]=i);let n=r.root||"";t.startsWith("http")&&(n=new URL(t).origin+n,r.root=n);let o=await async function(t,e){if(!Ge[t=t||""]){let n=t.startsWith("http")?t:window.location.origin+t;Ge[t]=Object.assign({},e,{root:t,$G:w.Wrap({}),$bus:new y,$axios:je.create({baseURL:n}),$message:Je,$router:null,$emit:null}),t===$vyes.root||null===$vyes.root?Ge[t].$router=$vyes.$router:Ge[t].$router={addRoutes:()=>{},beforeEnter:()=>{}};try{await(await import(n+"/env.js")).default(Ge[t])}catch(b){}}return Ge[t]}(n,r);return Object.assign(r,o),e.text()})).then((e=>Ye(e,r,t,n))).then((e=>(We[t]=e,e))).catch((e=>{e.message;let n=document.createElement("div");n.style.cssText="\n backgound:#aaa;\n height:100%;\n width: 100%;\n display:grid;\n place-items: center;\n",n.innerHTML=`\n
\n
404
\n

${t}

\n
\n`;let o={heads:[],body:n,setup:"",scripts:[],styles:"",txt:"",tmp:"",env:r,err:e};return We[t]=o,o})).finally((()=>{delete Ke[t]}));return Ke[t]=i,i},FetchFile:async function(t){return fetch(t).then((t=>{if(!t.ok)throw Error("HTTP error! status: "+t.status);return t.text()}))},LoadScript:Qe,LoadLink:tn,ParseUI:Ye};function nn(t,e){let n,o;if(t.startsWith("http://")||t.startsWith("https://")){if(n=new URL(t),n.origin!==window.location.origin)return null;n.pathname.startsWith(e)&&(o=n.pathname.slice(e.length))}else n=new URL(t,window.location.href),o=n.pathname;const r={};return n.searchParams.forEach(((t,e)=>{r[e]=t})),{path:o,query:r,hash:n.hash}}class on{constructor(t,e){this.originalPath=t,this.name=e,this.keys=[],this.regexp=this.pathToRegexp(t)}pathToRegexp(t){let e=t.replace(/:([^(/]+)/g,((t,e)=>(this.keys.push(e),`(?<${e}>[^/]+)`)));return e=e.replace(/\*(\w+)/g,((t,e)=>(this.keys.push(e),`(?<${e}>.*)`))),e=e.replace(/\*/g,".*"),RegExp(`^${e}$`)}match(t){let e;if("string"==typeof t)e=t;else{if(!t||"object"!=typeof t)return null;if(!t.path)return t.name&&t.name===this.name?{path:this.originalPath,params:t.params||{},matched:this.originalPath}:null;e=t.path}const n=this.regexp.exec(e);if(!n)return null;const o={};return this.keys.forEach((t=>{n.groups?.[t]&&(o[t]=n.groups[t])})),{path:this.originalPath,params:o,matched:n[0]}}}const rn=new Map;class sn{constructor(t,e,n){this.vyes=t,this.node=e,this.layoutDom=void 0,this.matchedRoute=n,this.htmlPath=this.resolveHtmlPath(n)}resolveHtmlPath(t){let e=t.route.component||t.route.path;return"function"==typeof e&&(e=e(t.path)),Object.entries(t.params).forEach((([t,n])=>{e=e.replace(":"+t,n)})),e.startsWith("/")||(e="/"+e),e.endsWith("/")&&(e=e.slice(0,-1)),e.endsWith(".html")||(e+=".html"),e}async mount(t,e,n){const o=await en.FetchUI(this.htmlPath,t);if(o.err){let n=document.createElement("div");return Object.assign(n.style,{width:"100%",height:"100%"}),n.append(...e),this.node.innerHTML="",this.node.append(n),void this.vyes.parseRef(this.htmlPath,n,{},t,null,!0)}this.title=o.title||"";const r={},i=document.createElement("div");if(i.setAttribute("vsrc",this.htmlPath),r[""]=[i],this.slots=r,!n)return this.node.innerHTML="",this.node.append(i),void this.vyes.parseRef(this.htmlPath,i,{},t,null);let s=rn.get(n);if(s)this.layoutDom=s,this.activate();else{let e=n;e.startsWith("/")||(e="/"+n),e.endsWith(".html")||(e+=".html"),e.startsWith("/layout")||(e="/layout"+e);const o=await en.FetchUI(e,t);if(o.err)return this.node.innerHTML="",this.node.append(i),void this.vyes.parseRef(this.htmlPath,i,{},t,null);s=o.body.cloneNode(!0),rn.set(n,s),i.$refData=w.Wrap({}),s.$refSlots=w.Wrap({...r}),this.node.innerHTML="",this.node.append(s),this.layoutDom=s,this.vyes.parseRef("/layout/"+n,s,{},t,null,!0)}}activate(){this.title&&(document.title=this.title);const t=this.layoutDom;if(t)t.querySelectorAll("vslot").forEach((e=>{e.closest("[vref]")===t&&this.slots[e.getAttribute("name")||""]&&(e.innerHTML="")})),Object.keys(t.$refSlots).forEach((e=>{delete t.$refSlots[e]})),Object.assign(t.$refSlots,this.slots),t.isConnected||(this.node.innerHTML=""),this.node.append(t);else{this.node.innerHTML="";const t=this.slots[""];t instanceof Array?this.node.append(...t):this.node.append(t)}}}const an=new class{#t=[];#e=[];#n=null;#o="";#r=[];#i=new Map;#s=null;#a=null;#c=[];#l=!1;#u=null;#f=new Map;constructor(){this.init()}get routes(){return this.#t.slice()}get history(){return this.#e.slice()}get current(){return this.#n}get query(){return this.#n?.query||{}}get params(){return this.#n?.params||{}}get root(){return this.#o}onChange(t){this.#r.push(t)}addRoute(t){if(!t.path)throw Error("Route must have a path");"/"!=t.path&&t.path.endsWith("/")&&(t.path=t.path.slice(0,-1));const e={path:t.path,component:t.component,name:t.name,meta:t.meta||{},children:t.children||[],matcher:new on(t.path,t.name),description:t.description||"",layout:t.layout||""};this.#t.push(e),t.name&&this.#f.set(t.name,e),t.children?.length>0&&t.children.forEach((n=>{const o=t.path+(n.path.startsWith("/")?n.path:"/"+n.path),r=n.layout||t.layout||"",i={...t.meta,...n.meta};this.addRoute({...n,path:o,parent:e,layout:r,meta:i})}))}addRoutes(t){t.forEach((t=>this.addRoute(t)))}#h(t,e){this.#r.forEach((n=>{if("function"==typeof n)try{n(t,e)}catch(o){}}))}#d(t){const e=this.#n;this.#n={path:t.path,fullPath:t.fullPath,params:t.params||{},query:t.query||{},hash:new URL(t.fullPath,window.location.origin).hash,meta:t.route?.meta||{},description:t.route?.description||"",layout:t.route?.layout||"",name:t.route?.name,matched:t.route?[t.route]:[]},this.#e.push(this.#n),this.#o&&!t.fullPath.startsWith("http")?history.pushState({},"",this.#o+t.fullPath):history.pushState({},"",t.fullPath),this.#h(this.#n,e)}matchRoute(t){const e=this.normalizeRouteTarget(t);if(!e)return null;const{path:n,query:o,params:r,name:i}=e;if(i){const t=this.#f.get(i);if(!t)return null;let e=t.path;Object.entries(r).forEach((([t,n])=>{e=e.replace(":"+t,n)}));const n=t.matcher.match(e);return n?{route:t,params:{...n.params,...r},matched:n.matched,path:e,query:o,name:i}:null}for(const s of this.#t){const t=s.matcher.match(n);if(t&&s.component)return{route:s,params:{...t.params,...r},matched:t.matched,description:s.description,layout:s.layout,path:n,query:o,name:s.name}}return null}normalizeRouteTarget(t){let e,n,o={},r={},i="";if("string"==typeof t){const n=nn(t,this.#o);if(!n)return null;e=n.path,o={...n.query},i=n.hash}else{if(!t||"object"!=typeof t)return null;if(t.path){const n=nn(t.path,this.#o);if(!n)return null;e=n.path,o={...n.query,...t.query||{}},i=t.hash||n.hash,r=t.params||{}}else{if(!t.name)return null;n=t.name,o=t.query||{},r=t.params||{},i=t.hash||""}}return e&&!e.startsWith("/")&&(e="/"+e),this.#o&&(e=e.startsWith(this.#o)?e.slice(this.#o.length):e),e.startsWith("/")||(e="/"+e),"/"!=e&&e.endsWith("/")&&(e=e.slice(0,-1)),{path:e,query:o,params:r,hash:i,name:n}}matchTo(t){const e=this.matchRoute(t);if(!e)return null;const{route:n,params:o,query:r,path:i,name:s}=e;let a="";r&&Object.keys(r).length>0&&(a="?"+Object.entries(r).map((([t,e])=>`${encodeURIComponent(t)}=${encodeURIComponent(e)}`)).join("&"));const c=(i||e.path)+a;return{route:n,params:o,query:r,name:s||n.name,path:i||e.path,fullPath:c,matched:[n]}}buildUrl(t,e={}){const n=new URL(t,window.location.origin);return Object.entries(e).forEach((([t,e])=>{n.searchParams.append(t,e)})),n}resolveRoutePath(t,e={}){let n=t.component||t.path;return Object.entries(e).forEach((([t,e])=>{n=n.replace(":"+t,e)})),"/"!==n&&""!==n||(n="/index"),n.startsWith("/")||(n="/"+n),n.endsWith(".html")&&(n=n.slice(0,-5)),n.endsWith("/")&&(n=n.slice(0,-1)),n}async#p(t){if(!t)return;const{route:e,params:n,query:o}=t,r={path:t.path,fullPath:t.fullPath,params:n,query:o,hash:new URL(t.fullPath,window.location.origin).hash,meta:e.meta,description:e.description,layout:e.layout,name:e.name,matched:[e]};if(this.beforeEnter)try{let t=!0;if(!1===await this.beforeEnter(r,this.#n,(e=>{e&&(t=!1,this.push(e))}))||!t)return}catch(a){return}const i=t.fullPath;let s=this.#i.get(i);this.#d(t),s?s.activate():(s=new sn(this.#u,this.#s,t),await s.mount(this.#a,this.#c,r.layout),this.#i.set(i,s))}async push(t){const e=this.matchTo(t);e?await this.#p(e):"string"==typeof t||t.path||t.name}replace(t){this.push(t),this.#e.length>1&&this.#e.splice(-2,1)}go(t){history.go(t)}back(){history.back()}forward(){history.forward()}init(){this.#l||(this.#l=!0,document.body.addEventListener("click",(t=>{const e=t.target.closest("a");if(!e)return;const n=e.getAttribute("href");!n||n.startsWith("http")||n.startsWith("#")||(t.preventDefault(),e.hasAttribute("reload")?window.location.href=n:this.push(n))}),!0),window.addEventListener("popstate",(()=>{this.push(window.location.href)})))}ParseVrouter(t,e,n){this.#s=e,this.#a=n,this.#o=n.root||"",this.#c=Array.from(e.childNodes),this.#u=t,this.push(window.location.href)}},cn={$router:an},ln=[];document.addEventListener("click",(t=>{ln.forEach((e=>{e?.dom instanceof Element&&"function"==typeof e?.callback&&(e.dom.contains(t.target)||e.callback(t))}))}));const un={CamelToKebabCase:function(t){return 0===t.length?"":t.charAt(0).toLowerCase()+t.slice(1).replace(/([A-Z])/g,(function(t,e){return"-"+e.toLowerCase()}))},EventsList:["load","unload","beforeunload","resize","scroll","submit","reset","input","change","focus","blur","keydown","keypress","keyup","click","dblclick","contextmenu","mousedown","mouseup","mousemove","mouseover","mouseout","mouseenter","mouseleave","touchstart","touchmove","touchend","touchcancel","drag","dragstart","dragend","dragover","dragenter","dragleave","drop","copy","cut","paste","animationstart","animationend","animationiteration","transitionend","abort","error","loadstart","progress","play","pause","ended","volumechange","timeupdate","loadeddata","waiting","playing","online","offline","storage","visibilitychange"],BindInputDomValue:function(t,e,n,o){const r="string"==typeof t?document.querySelector(t):t;if(r){switch(r.type||r.tagName.toLowerCase()){case"text":case"password":case"email":case"tel":case"url":case"search":case"number":case"range":case"color":case"date":case"time":case"datetime-local":case"month":case"week":case"hidden":case"textarea":o((()=>{r.value=e[n]})),r.addEventListener("input",(function(){e[n]=this.value}));break;case"checkbox":o((function(){r.checked=!!e[n]})),r.addEventListener("change",(function(){e[n]=this.checked}));break;case"radio":o((()=>{r.checked=r.value===e[n]})),r.addEventListener("change",(function(){this.checked&&(e[n]=this.value)}));break;case"select-one":case"select-multiple":o((()=>{let t=e[n];if(r.multiple){const e=Array.isArray(t)?t:[];for(let t=0;t{if("outer"===e){let e=ln.length;return ln.push({dom:t,callback:n}),()=>{ln[e]=null}}}},fn=async t=>navigator.clipboard&&navigator.clipboard.writeText?navigator.clipboard.writeText(t):(prompt("http\u73af\u5883\u65e0\u6cd5\u81ea\u52a8\u590d\u5236\uff0c\u8bf7\u624b\u52a8\u590d\u5236\u5185\u5bb9\u5230\u526a\u8d34\u677f:",t),new Promise((t=>{})));class hn{postMessage=(t,e)=>{};constructor(t={}){this.options={highlightColor:"#007bff",overlayColor:"rgba(0, 123, 255, 0.1)",borderWidth:"2px",zIndex:1e4,showTagName:!0,...t},this.isActive=!1,this.selectedElement=null,this.currentHoverElement=null,this.overlay=null,this.selectedOverlay=null,this.tooltip=null,this.selectedTooltip=null,this.actionPanel=null,this.originalCursor="",this.init()}init(){this.createStyles(),this.bindEvents()}createStyles(){const t=document.createElement("style");t.textContent=`\n .div-selector-overlay {\n position: fixed;\n pointer-events: none;\n border: ${this.options.borderWidth} solid ${this.options.highlightColor};\n background: ${this.options.overlayColor};\n z-index: ${this.options.zIndex};\n transition: all 0.2s ease;\n box-sizing: border-box;\n }\n \n .div-selector-selected {\n position: fixed;\n pointer-events: none;\n border: ${this.options.borderWidth} solid #28a745;\n background: rgba(40, 167, 69, 0.1);\n z-index: ${this.options.zIndex-1};\n box-sizing: border-box;\n }\n \n .div-selector-tooltip {\n position: fixed;\n background: rgba(51, 51, 51, 0.95);\n cursor:pointer;\n color: white;\n padding: 8px 12px;\n border-radius: 6px;\n font-size: 12px;\n font-family: 'Consolas', 'Monaco', 'Courier New', monospace;\n z-index: ${this.options.zIndex+1};\n user-select: none;\n box-shadow: 0 2px 8px rgba(0,0,0,0.3);\n border: 1px solid rgba(255,255,255,0.1);\n backdrop-filter: blur(4px);\n }\n \n .div-selector-tooltip.hover {\n background: rgba(0, 123, 255, 0.9);\n }\n \n .div-selector-tooltip.selected {\n background: rgba(40, 167, 69, 0.9);\n border-color: rgba(40, 167, 69, 0.3);\n }\n \n .div-selector-actions {\n position: fixed;\n background: white;\n border: 1px solid #ddd;\n border-radius: 8px;\n padding: 8px;\n z-index: ${this.options.zIndex+2};\n box-shadow: 0 4px 16px rgba(0,0,0,0.15);\n display: flex;\n gap: 6px;\n min-width: 30px;\n backdrop-filter: blur(8px);\n }\n \n .div-selector-btn {\n padding: 4px 6px;\n border: 1px solid #ddd;\n background: white;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n transition: all 0.2s ease;\n text-align: left;\n white-space: nowrap;\n }\n \n .div-selector-btn:hover {\n background: #f8f9fa;\n transform: translateX(2px);\n }\n \n .div-selector-btn.danger {\n color: #dc3545;\n border-color: #dc3545;\n }\n \n .div-selector-btn.danger:hover {\n background: #dc3545;\n color: white;\n }\n \n .div-selector-btn.primary {\n background: #007bff;\n color: white;\n border-color: #007bff;\n }\n \n .div-selector-btn.primary:hover {\n background: #0056b3;\n }\n \n .div-selector-active {\n cursor: crosshair !important;\n }\n `,document.head.appendChild(t)}bindEvents(){this.handleMouseMove=this.handleMouseMove.bind(this),this.handleClick=this.handleClick.bind(this),this.handleScroll=this.handleScroll.bind(this),this.handleResize=this.handleResize.bind(this)}activate(){this.isActive||(this.isActive=!0,this.originalCursor=document.body.style.cursor,document.body.classList.add("div-selector-active"),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("click",this.handleClick),window.addEventListener("scroll",this.handleScroll),window.addEventListener("resize",this.handleResize),this.createOverlay(),this.createTooltip())}deactivate(){this.isActive&&(this.isActive=!1,document.body.style.cursor=this.originalCursor,document.body.classList.remove("div-selector-active"),document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("click",this.handleClick),window.removeEventListener("scroll",this.handleScroll),window.removeEventListener("resize",this.handleResize),this.removeOverlay(),this.removeTooltip())}handleMouseMove(t){if(!this.isActive)return;const e=document.elementFromPoint(t.clientX,t.clientY);if(!e)return;if(this.isPluginElement(e))return;const n="DIV"===e.tagName?e:e.closest("div,[vref]");n&&!this.isPluginElement(n)&&this.selectedElement!==n&&(this.currentHoverElement=n,this.highlightElement(n),this.updateHoverTooltip(n))}handleClick(t){if(!this.isActive)return;const e=document.elementFromPoint(t.clientX,t.clientY);if(!e)return;if(this.isPluginElement(e))return;t.preventDefault(),t.stopPropagation();const n="DIV"===e.tagName?e:e.closest("div");n&&!this.isPluginElement(n)&&(this.selectElement(n),this.deactivate())}handleScroll(){this.selectedElement&&(this.updateSelectedOverlay(),this.updateSelectedTooltip(),this.updateActionPanelPosition()),this.currentHoverElement&&!this.selectedElement&&(this.highlightElement(this.currentHoverElement),this.updateHoverTooltip(this.currentHoverElement))}handleResize(){this.selectedElement&&(this.updateSelectedOverlay(),this.updateSelectedTooltip(),this.updateActionPanelPosition())}isPluginElement(t){return t.closest(".div-selector-overlay, .div-selector-selected, .div-selector-tooltip, .div-selector-actions")}createOverlay(){this.overlay=document.createElement("div"),this.overlay.className="div-selector-overlay",this.overlay.style.display="none",document.body.appendChild(this.overlay)}createSelectedOverlay(){this.selectedOverlay=document.createElement("div"),this.selectedOverlay.className="div-selector-selected",document.body.appendChild(this.selectedOverlay)}createTooltip(){this.tooltip=document.createElement("div"),this.tooltip.className="div-selector-tooltip hover",this.tooltip.style.display="none",document.body.appendChild(this.tooltip)}createSelectedTooltip(){this.selectedTooltip=document.createElement("div"),this.selectedTooltip.className="div-selector-tooltip selected",document.body.appendChild(this.selectedTooltip)}highlightElement(t){if(!this.overlay)return;const e=t.getBoundingClientRect();this.overlay.style.display="block",this.overlay.style.left=e.left+"px",this.overlay.style.top=e.top+"px",this.overlay.style.width=e.width+"px",this.overlay.style.height=e.height+"px"}updateHoverTooltip(t){if(!this.tooltip)return;const e=this.getElementInfo(t),n=t.getBoundingClientRect();this.tooltip.textContent=e,this.tooltip.style.display="block";let o=n.left-8,r=n.top-this.tooltip.offsetHeight-8;0>o&&(o=8),0>r&&(r=n.top+8),this.tooltip.style.left=o+"px",this.tooltip.style.top=r+"px"}selectElement(t){this.clearSelection(),this.selectedElement=t,this.createSelectedOverlay(),this.createSelectedTooltip(),this.updateSelectedOverlay(),this.updateSelectedTooltip(),this.overlay&&(this.overlay.style.display="none"),this.tooltip&&(this.tooltip.style.display="none"),this.showActionPanel()}updateSelectedOverlay(){if(!this.selectedOverlay||!this.selectedElement)return;const t=this.selectedElement.getBoundingClientRect();this.selectedOverlay.style.left=t.left+"px",this.selectedOverlay.style.top=t.top+"px",this.selectedOverlay.style.width=t.width+"px",this.selectedOverlay.style.height=t.height+"px"}updateSelectedTooltip(){if(!this.selectedTooltip||!this.selectedElement)return;const t=this.getElementInfo(this.selectedElement);let e=this.getFilePath(this.selectedElement);const n=this.selectedElement.getBoundingClientRect();this.selectedTooltip.addEventListener("click",(t=>{e&&this.postMessage("fs-open",e),t.preventDefault(),t.stopPropagation()})),this.selectedTooltip.textContent="\u2713 "+t;let o=n.left-8,r=n.top-this.selectedTooltip.offsetHeight-8;0>o&&(o=8),0>r&&(r=n.top+8),this.selectedTooltip.style.left=o+"px",this.selectedTooltip.style.top=r+"px"}showActionPanel(){this.removeActionPanel();const t=this.selectedElement.getBoundingClientRect();this.actionPanel=document.createElement("div"),this.actionPanel.className="div-selector-actions";let e=t.right-180,n=t.top+6;e+180>window.innerWidth&&(e=t.left-180-8),0>e&&(e=8),n+40>window.innerHeight&&(n=window.innerHeight-40-8),0>n&&(n=8),this.actionPanel.style.left=e+"px",this.actionPanel.style.top=n+"px",[{text:"\ud83d\udccb",action:()=>this.copySelector(this.selectedElement)},{text:"x",action:()=>this.clearSelection()}].forEach((t=>{const e=document.createElement("button");e.className="div-selector-btn "+(t.class||""),e.textContent=t.text,e.onclick=t.action,this.actionPanel.appendChild(e)})),document.body.appendChild(this.actionPanel)}updateActionPanelPosition(){if(!this.actionPanel||!this.selectedElement)return;const t=this.selectedElement.getBoundingClientRect(),e=this.actionPanel.offsetWidth,n=this.actionPanel.offsetHeight;let o=t.right-e+8,r=t.top-8;o+e>window.innerWidth&&(o=t.left-e-8),0>o&&(o=8),r+n>window.innerHeight&&(r=window.innerHeight-n-8),0>r&&(r=8),this.actionPanel.style.left=o+"px",this.actionPanel.style.top=r+"px"}clearSelection(){this.selectedElement=null,this.selectedOverlay&&(this.selectedOverlay.remove(),this.selectedOverlay=null),this.selectedTooltip&&(this.selectedTooltip.remove(),this.selectedTooltip=null),this.removeActionPanel()}getElementInfo(t){const e=t.getBoundingClientRect();let n=t.getAttribute("vref");return n||(n=t.closest("[vref]").getAttribute("vref"),n+="."+t.tagName.toLowerCase()),`${n} (${Math.round(e.width)}\xd7${Math.round(e.height)})`}getFilePath(t){let e=t.getAttribute("vref");return e||(e=t.closest("[vref]").getAttribute("vref")),e&&(e="/ui"+e+".html"),e}copySelector(t){let e=this.getFilePath(t);fn(e).then((()=>{this.showNotification("\ud83d\udccb CSS\u9009\u62e9\u5668\u5df2\u590d\u5236\u5230\u526a\u8d34\u677f")}))}copyXPath(t){const e=this.generateXPath(t);fn(e).then((()=>{this.showNotification("\ud83d\udd0d XPath\u5df2\u590d\u5236\u5230\u526a\u8d34\u677f")}))}viewStyles(t){const e=window.getComputedStyle(t);let n="\ud83d\udcca \u91cd\u8981\u6837\u5f0f\u5c5e\u6027:\n\n";["display","position","width","height","margin","padding","background-color","color","font-size","border","z-index","opacity"].forEach((t=>{n+=`${t}: ${e.getPropertyValue(t)}\n`})),alert(n)}showNotification(t){const e=document.createElement("div");e.style.cssText=`\n position: fixed;\n top: 20px;\n right: 20px;\n background: linear-gradient(135deg, #28a745, #20c997);\n color: white;\n padding: 12px 18px;\n border-radius: 8px;\n z-index: ${this.options.zIndex+10};\n font-size: 14px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.2);\n transform: translateX(100%);\n transition: transform 0.3s ease;\n `,e.textContent=t,document.body.appendChild(e),setTimeout((()=>{e.style.transform="translateX(0)"}),100),setTimeout((()=>{e.style.transform="translateX(100%)",setTimeout((()=>{e.remove()}),300)}),2500)}generateXPath(t){if(t.id)return`//*[@id="${t.id}"]`;const e=[];for(;t&&t.nodeType===Node.ELEMENT_NODE;){let n=0,o=!1,r=!1;for(let e=t.previousSibling;e;e=e.previousSibling)e.nodeType===Node.ELEMENT_NODE&&e.nodeName===t.nodeName&&(r=!0,n++);for(let e=t.nextSibling;e&&!o;e=e.nextSibling)e.nodeType===Node.ELEMENT_NODE&&e.nodeName===t.nodeName&&(o=!0);const i=t.nodeName.toLowerCase(),s=r||o?`[${n+1}]`:"";if(e.unshift(i+s),(t=t.parentNode)===document.body)break}return e.length?"/"+e.join("/"):null}removeOverlay(){this.overlay&&(this.overlay.remove(),this.overlay=null)}removeTooltip(){this.tooltip&&(this.tooltip.remove(),this.tooltip=null)}removeActionPanel(){this.actionPanel&&(this.actionPanel.remove(),this.actionPanel=null)}}let dn=!1,pn=null;const mn=(t,e)=>{dn&&("string"!=typeof e&&"number"!=typeof e||(e={value:e}),window.parent.postMessage(Object.assign({type:t,from:"vdev"},e),"*"))};!async function(){const t=document.createElement("style");t.innerHTML="\n [vref] {\n display: block;\n }\n [vparsing] {\n display: none;\n -webkit-text-fill-color: transparent;\n }\n vslot, vrouter {\n display: block;\n }\n",document.head.firstChild?document.head.insertBefore(t,document.head.firstChild):document.head.appendChild(t);const e=[],n=t=>{if(!t.isConnected)return;let n=t.getAttribute("vdelay");if(n){let o=e[n];o&&o(t)}};function o(t,e){const n=Function("sandbox",t=`with (sandbox) { ${t} }`);let o={data:null,key:null};const r=t=>new Proxy(t,{has:(t,e)=>!0,get(t,e,n){if(e===Symbol.unscopables)return;let i=Reflect.get(t,e,n);return o.data=t,o.key=e,"object"==typeof i&&i&&i[w.DataID]?r(i):i},set:(t,e,n,o)=>!1});return n(r(e)),o}new MutationObserver((function(t,e){t.forEach((function(t){for(let e of t.addedNodes)1===e.nodeType&&(n(e),e.querySelectorAll("*[vdelay]").forEach(n))}))})).observe(document.body,{attributes:!1,childList:!0,subtree:!0,characterData:!1});const r=/{{|}}/g,i=/^(\s*(\w+)\s+in\s+|\((\w+),\s*(\w+)\)\s+in\s+)([\w\?\$\.\[\]\(\)'"]+)$/;window.$vyes||(window.$vyes=new class{app=null;root=null;vget=en;vproxy=w;t=!0;$router=cn.$router;constructor(t){"string"==typeof t?this.app=document.getElementById(t):t instanceof HTMLElement?this.app=t:this.app=document.body,this.app&&(async()=>{let t=await en.FetchUI(window.location.pathname,{},!0);this.root=t.env?.root||"",t.env?.vdev&&window.self!==window.top&&(dn||(dn=!0,pn=new hn,mn("iframe-loaded"),pn.postMessage=mn,window.addEventListener("keyup",(t=>{"Escape"===t.key&&mn("key-esc")})),setTimeout((()=>{window.$vyes&&window.$vyes.$router&&$vyes.$router.onChange((t=>{mn("url-change",t.fullPath)}))}),100),window.addEventListener("message",(t=>{const e=t.data;if("vyes"==e.from)switch(e.type){case"reload":window.location.reload();break;case"magic":pn&&pn.isActive?pn.deactivate():pn&&pn.activate()}})))),this.parseRef("root",this.app,{},t.env||{},t,!0)})()}async parseDom(t,e={},n){if(n instanceof HTMLElement)throw Error("env error");let o=t.nodeName.toLowerCase();if(3===t.nodeType)return void this.parseTextNode(t,e,n);if(8===t.nodeType)return;if(1!==t.nodeType)return;if(t.hasAttribute("novyes")||t.vparsed)return;let r=t.getAttribute("v-for");if(null!==r)return void this.parseVfor(r,t,e,n);if(-1!==o.indexOf("-")){let r="/"+o.split("-").join("/"),i=t.hasAttribute("single");return this.parseRef(r,t,e,n,null,i),void(t.vparsed=!0)}if(t.getAttribute(":vsrc")){let o=t.getAttribute(":vsrc");t.removeAttribute(":vsrc");let r=Array.from(t.attributes).map((t=>({name:t.name,value:t.value}))),i=Array.from(t.childNodes);return void w.Watch((()=>{delete t.vparsed,t.setAttribute("vparsing","");let s=w.Run(o,e,n);s&&(Array.from(t.attributes).forEach((e=>{t.removeAttribute(e.name)})),t.innerHTML="",r.forEach((e=>{t.setAttribute(e.name,e.value)})),i.forEach((e=>{t.appendChild(e.cloneNode(!0))})),this.parseRef(s,t,e,n,null,!1),t.vparsed=!0)}))}if(t.getAttribute("vsrc")){let o=t.hasAttribute("single");return this.parseRef(t.getAttribute("vsrc"),t,e,n,null,o),void(t.vparsed=!0)}if("div"===o&&t.getAttribute("v-html")){let o=t.getAttribute("v-html");return t.removeAttribute("v-html"),t.innerHTML="",this.parseAttrs(t,e,n),t.vparsed=!0,void w.Watch((()=>{let r=w.Run(o,e,n);t.innerHTML=r;let i=this.parseVif(Array.from(t.childNodes),e,n);for(let t of i)this.parseDom(t,e,n)}))}if("vslot"===o)return this.parseSlots(t,e,n),void(t.vparsed=!0);if("vrouter"===o)return this.parseAttrs(t,e,n),void cn.$router.ParseVrouter(this,t,n);this.parseAttrs(t,e,n);let i=this.parseVif(Array.from(t.childNodes),e,n);for(let s of i)this.parseDom(s,e,n);t.vparsed=!0}onMountedRun(t,n,o=!0){if(o){if(t.isConnected)return void n(t);let o=e.push((t=>{t.removeAttribute("vdelay"),n(t)}));return void t.setAttribute("vdelay",o-1)}t.isConnected&&n(t);let r=e.push(n);t.setAttribute("vdelay",r-1)}AllENVs={};async parseRef(t,e,n,o,r,i=!1){e.setAttribute("vparsing","");let s=o,a=e.getAttribute("vrefof"),c=e.closest(`*[vref='${a}']`);c&&(o=c.$env),!r&&t&&(t.endsWith(".html")||(t+=".html"),r=await en.FetchUI(t,o,e.hasAttribute("root"))),o=Object.assign({},o,r?.env||{}),e.$env=o,e.$vsrc=t,o.$router=cn.$router,o.$emit=(t,...n)=>{if(t=t.toLowerCase(),!e.$vevent)return;let o=e.$vevent[t];o&&"function"==typeof o&&o(...n)};let l=await this.setupRef(e,n,s,r,i);i?this.parseAttrs(e,l,o,r?.customAttrs):this.parseAttrs(e,n,s,r?.customAttrs);let u=this.parseVif(Array.from(e.childNodes),l,o);for(let f of u)this.parseDom(f,l,o);e.removeAttribute("vparsing"),this.mountRef(e,l,o,r)}async setupRef(t,e,n,r,i=!1){let s=w.Wrap({});if(r.setup){let e=r.setup.innerHTML;e=await w.ParseImport(e,s,t.$env,t.$vsrc),await w.AsyncRun(e,s,t.$env,{$node:t,$watch:t=>{setTimeout((()=>{w.Watch(t)}),50)}})}if(t.$refScope=e,t.$refData=s,i)return s;if(!t.$refSlots){let e=w.Wrap({});t.childNodes.forEach((t=>{let n=t.getAttribute?t.getAttribute("vslot"):"";n=n||"",e[n]||(e[n]=[]),e[n].push(t)})),t.$refSlots=e}t.innerHTML="";let a=r.body.cloneNode(!0);t.append(...a.childNodes),Object.keys(s).forEach((r=>{const i=un.CamelToKebabCase(r);if("boolean"==typeof s[r]?(t.hasAttribute(r)||t.hasAttribute(i))&&(s[r]=!0):t.hasAttribute(r)?s[r]=t.getAttribute(r):t.hasAttribute(i)&&(s[r]=t.getAttribute(i)),t.hasAttribute(":"+r)||t.hasAttribute(":"+i)){let o=t.getAttribute(":"+r)||t.getAttribute(":"+i);t.removeAttribute(":"+r),t.removeAttribute(":"+i),w.Watch((()=>{s[r]=o?w.Run(o,e,n):e[r]}))}if(t.hasAttribute("v:"+r)||t.hasAttribute("v:"+i)){let n=t.getAttribute("v:"+r)||t.getAttribute("v:"+i);t.removeAttribute("v:"+r),t.removeAttribute("v:"+i),n||(n=r);let a=o(n,e);if(a.data&&a.key){let t=a.key,e=a.data;void 0!==e[t]&&null!==e[t]||(e[t]=s[r]),w.Watch((()=>{s[r]=e[t]})),w.Watch((()=>{e[t]=s[r]}))}}}));let c=Array.from(a.attributes);return c=c.filter((e=>!this.parseAttr(t,e.name,e.value,s,n)||(a.removeAttribute(e.name),!1))),c.forEach((e=>{if("class"===e.name)t.classList.add(...e.value.trim().split(/\s+/));else if("style"===e.name){let n=e.value.split(";");for(let e of n){let n=e.split(":");if(2===n.length&&!t.style[n[0]]){let e=n[0].trim();e.startsWith("--")?t.style.setProperty(e,n[1].trim()):t.style[e]=n[1].trim()}}}else t.getAttribute(e.name)||t.setAttribute(e.name,e.value)})),s}async mountRef(t,e,n,o){for(let r of o.scripts)r.hasAttribute("active")?this.onMountedRun(t,(()=>{w.AsyncRun(r.innerHTML,e,n,{$node:t,$watch:w.Watch})}),!1):w.AsyncRun(r.innerHTML,e,n,{$node:t,$watch:w.Watch})}parseAttrs(t,e,n,o){if("A"===t.nodeName&&this.parseAHref(t,e,n),Array.from(t.attributes).forEach((o=>{this.parseAttr(t,o.name,o.value,e,n)&&t.removeAttribute(o.name)})),o&&Object.keys(o).forEach((e=>{this.parseAttr(t,e,o[e],t.$refData,n)})),t.hasAttribute("v-show")){let o=t.getAttribute("v-show"),r=t.style.display;w.Watch((()=>{let i=w.Run(o,e,n);t.style.display=i?r:"none"}))}}parseAHref(t,e,n){if(!t.hasAttribute("href")&&!t.hasAttribute(":href"))return;w.Watch((()=>{let o=t.getAttribute("href");if(t.hasAttribute(":href")){let r=t.getAttribute(":href");t.removeAttribute(":href"),o=w.Run(r,e,n)}if(o&&!o.startsWith("#")&&!o.startsWith("http"))if(o.startsWith("@"))o=o.replaceAll("//","/"),t.setAttribute("href",o.slice(1));else if(o){let e=n?.root;e&&(o=e+o),t.setAttribute("href",o)}}));const o=e=>{let n=e?.fullPath;t.getAttribute("href")===n?t.setAttribute("active",""):t.removeAttribute("active")};o(cn.$router.current),cn.$router.onChange(o)}parseAttr(t,e,n,r,i){if(e.startsWith(":")){let o=e.slice(1);return"class"===o||"style"===o?this.handleStyle(t,o,n,r,i):w.Watch((()=>{let e;e=n?w.Run(n,r,i):r[o],un.SetAttr(t,o,e)})),!0}if(e.startsWith("@"))return this.handleEvent(t,e,n,r,i),!0;if(e.indexOf("!")>-1);else if(e.startsWith("v:")){let e=o(n,r);if(e.data&&e.key){let n=e.key,o=e.data;return un.BindInputDomValue(t,o,n,w.Watch)}}else if("vdom"===e){let e=o(n,r);return e.data&&e.key&&(e.data[e.key]=t),!0}return!1}handleStyle(t,e,n,o,r){let i="";w.Watch((()=>{let s=w.Run(n,o,r);if("function"==typeof s&&(s=s()),"class"===e){if(i&&(t.classList.remove(...i.split(/\s+/)),i=""),s instanceof Array)i="",s.forEach((t=>{if("string"==typeof t&&t.length)i+=" "+t;else if("object"==typeof t)for(let e in t)t[e]&&(i+=" "+e)}));else if("string"==typeof s&&s.length)i=s.trim();else if("object"==typeof s){i="";for(let t in s)s[t]&&(i+=" "+t)}i=i.trim(),i&&t.classList.add(...i.split(/\s+/))}else if("style"===e){if(i)if("object"==typeof i)for(let e in i)e.startsWith("--")?t.style.removeProperty(e):t.style[e]="";else if("string"==typeof i){let e=i.split(";");for(let n of e){let e=n.split(":");2===e.length&&(e[0].trim().startsWith("--")?t.style.removeProperty(e[0].trim()):t.style[e[0].trim()]="")}}if("object"==typeof s)for(let e in s)e.startsWith("--")?t.style.setProperty(e,s[e]):t.style[e]=s[e];else if("string"==typeof s){let e=s.split(";");for(let n of e){let e=n.split(":");2===e.length&&(e[0].trim().startsWith("--")?t.style.setProperty(e[0].trim(),e[1].trim()):t.style[e[0].trim()]=e[1].trim())}}i=s}}))}handleEvent(t,e,n,o,r){let i=e.slice(1).split("."),s={self:!1,prevent:!1,stop:!1},a=i[0];if("mounted"===a)this.onMountedRun(t,(t=>{let e=w.Run(n,o,r);"function"==typeof e&&e(t)}),!1);else if("outerclick"===a){let e=t=>{let e=w.Run(n,o,r,{$event:t});"function"==typeof e&&e(t)};un.AddClicker(t,"outer",e)}else if(-1!==un.EventsList.indexOf(a)){"keydown"!==a&&"keyup"!==a&&"keypress"!==a||"INPUT"!==t.tagName&&"TEXTAREA"!==t.tagName&&t.setAttribute("tabindex","0");let e=t=>{let e=w.Run(n,o,r,{$event:t});"function"==typeof e&&e(t)};i.slice(1).forEach((i=>{if(i.startsWith("delay")){let s=i.slice(5);s=s?s.endsWith("ms")?+s.slice(0,-2):s.endsWith("s")?1e3*+s.slice(0,-1):+s:1e3,isNaN(s)&&(s=1e3),e=e=>{let i=t["_"+a];i&&"number"==typeof i&&clearTimeout(i),t["_"+a]=setTimeout((()=>{let t=w.Run(n,o,r,{$event:e});"function"==typeof t&&t(e)}),s)}}s[i]=!0})),t.addEventListener(a,(t=>{(1>=i.length||"keydown"!==a&&"keyup"!=a&&"keypress"!=a||i[1]===t.key.toLowerCase())&&(s.self&&t.currentTarget!==t.target||(s.prevent&&t.preventDefault(),s.stop&&t.stopPropagation(),e(t)))}))}else t.$vevent=t.$vevent||{},t.$vevent[a]=(...t)=>{let e=w.Run(n,o,r,{});"function"==typeof e&&e(...t)}}parseTextNode(t,e,n){let o,i=t.nodeValue.trim();if(!i)return;let s=0,a=-1,c=[];for(;null!==(o=r.exec(i));)if("{{"===o[0])a=o.index;else if("}}"===o[0]&&a>=0){s!==a&&c.push(i.slice(s,a)),c.push("");let r=i.slice(a+2,o.index),l=c.length;a=-1,s=o.index+2,w.Watch((()=>{c[l-1]=w.Run(r,e,n),"object"==typeof c[l-1]&&(c[l-1]=JSON.stringify(c[l-1])),t.nodeValue=c.join("")}))}c.push(i.slice(s)),t.nodeValue=c.join("")}vforDomCache={};parseVfor(t,e,n,o){e.removeAttribute("v-for");let r=i.exec(t);if(6===r?.length){let t=document.createElement("div");t.style.display="none";let i=w.GenUniqueID();this.vforDomCache[i]={},e.parentNode.replaceChild(t,e),w.Watch((()=>{let s=r[3]||r[2],a=r[4],c=w.Run(r[5],n,o),l=this.vforDomCache[i],u=new Set;if("function"==typeof c?c=c():"number"==typeof c&&(c=Array.from({length:c},((t,e)=>e))),null==c&&(c=[]),c.length,"object"==typeof c){let r=Object.keys(c),f=[];for(let t in r){let e=r[t],n="";n=c[e]&&c[e][w.DataID]?c[e][w.DataID]:e+"."+c[e],n=i+"."+n,u.add(n),f.push({k:e,vfk:n,val:c[e]})}for(let t of Object.keys(l))u.has(t)||(l[t]instanceof Array?l[t].forEach((t=>t.remove())):l[t].remove(),delete l[t]);let h=t;for(let i=f.length-1;i>=0;i--){let{k:r,vfk:c,val:u}=f[i],d=l[c];if(d){a&&(d.$vforData[a]="0"===r?0:+r||r),d.isConnected&&(d.nextSibling!==h&&t.parentNode.insertBefore(d,h),h=d);continue}let p=e.cloneNode(!0);l[c]=p;let m={[s]:u};a&&(m[a]="0"===r?0:+r||r),m=w.Wrap(m,n),p.$vforData=m,t.parentNode.insertBefore(p,h);let y=e.getAttribute("v-if");if(!y){this.parseDom(p,m,o),h=p;continue}p.removeAttribute("v-if");let b=-1;b=w.Watch((()=>{let e=l[c];if(e)if(w.Run(y,m,o)){if(e.vparsed||this.parseDom(e,m,o),!e.isConnected){let n=!1,o=t;for(let t in l)if(t!==c){if(n&&l[t].isConnected){o=l[t];break}}else n=!0;t.parentNode.insertBefore(e,o)}}else e.isConnected?e.remove():this.onMountedRun(e,(t=>{e.remove()}));else w.Cancel(b)})),p.isConnected&&(h=p)}}}))}}parseVif(t,e,n){let o={now:document.createElement("div"),conds:[],doms:[]};const r=t=>{let o={now:t.now,conds:t.conds,doms:t.doms},r=[];for(let e in o.conds){let t=o.conds[e];t=""===t?"true":"Boolean("+t+")",r.push(t)}let i=`let res = [${r.join(",")}]\n return res.indexOf(true)`;w.Watch((()=>{let t=w.Run(i,e,n),r=o.doms[t];return r||(r=document.createElement("div"),r.style.display="none"),r}),(t=>{t&&(this.onMountedRun(o.now,(e=>{e.replaceWith(t),o.now=t})),t?.vparsed||this.parseDom(t,e,n))}))};let i=t.filter((t=>!(t.getAttribute&&!t.getAttribute("v-for")&&(null!==t.getAttribute("v-if")?(o.conds.length>0&&(r(o),o={now:document.createElement("div"),conds:[],doms:[]}),t.replaceWith(o.now),o.conds.push(t.getAttribute("v-if")),t.removeAttribute("v-if"),o.doms.push(t),1):null!==t.getAttribute("v-else-if")?(o.conds.push(t.getAttribute("v-else-if")),t.removeAttribute("v-else-if"),o.doms.push(t),t.remove(),1):null!==t.getAttribute("v-else")&&(o.conds.push(""),t.removeAttribute("v-else"),o.doms.push(t),t.remove(),1)))));return o.conds.length>0&&r(o),i}parseSlots(t,e,n){let o=t.getAttribute("vrefof"),r=t.closest(`*[vref='${o}']`);if(!r)return void this.onMountedRun(t,(t=>{this.parseSlots(t,e,n)}));for(;;){let t=r?.parentNode.closest("*[vref]");if(!t)break;if(t.getAttribute("vref")!==o)break;r=t}let i=t.getAttribute("name")||"";if(t.getAttribute(":name")){let o=t.getAttribute(":name");t.removeAttribute(":name"),i=w.Run(o,e,n)}return t.originContent||(t.$originContent=Array.from(t.childNodes),t.innerHTML=""),t.$slotCache={},w.Watch((()=>{let o=r.$refSlots||{},s=r.$refScope||{},a=o[i];if(a&&a.length>0){let o=a[0].hashID;if(o){if(t.$slotCache[o])return t.innerHTML="",void t.append(...t.$slotCache[o])}else o=w.GenUniqueID(),a[0].hashID=o;t.innerHTML="",a=a.map((t=>t.cloneNode(!0))),t.append(...a);let r=s;if(null!==t.getAttribute("vbind")){let n=t.getAttribute("vbind").split(",").map((t=>t.trim()));r=w.Wrap({}),n.forEach((t=>{e.hasOwnProperty(t)&&(r[t]=e[t])})),w.SetDataRoot(r,s)}let i="";a.find((t=>!(!t.getAttribute||!t.getAttribute("vrefof")||(i=t.getAttribute("vrefof"),0))));let c=n;if(i){let e=t.closest(`*[vref='${i}']`);c=e?.$env||n}a=this.parseVif(a,r,c),a.forEach((t=>this.parseDom(t,r,c))),t.$slotCache[o]=a}else{t.innerHTML="",t.append(...t.$originContent);let o=!1;t.$originContent.forEach((t=>{t.hasAttribute&&t.vparsed&&(o=!0)})),o||(t.$originContent=this.parseVif(t.$originContent,e,n),t.$originContent.forEach((t=>this.parseDom(t,e,n))))}})),this.parseAttrs(t,e,n),t}}(document.body))}()},"function"==typeof define&&define.amd?define(t):t(); \ No newline at end of file